Package Products :: Package ZenModel :: Module DataRoot
[hide private]
[frames] | no frames]

Source Code for Module Products.ZenModel.DataRoot

  1  ########################################################################### 
  2  # 
  3  # This program is part of Zenoss Core, an open source monitoring platform. 
  4  # Copyright (C) 2007, Zenoss Inc. 
  5  # 
  6  # This program is free software; you can redistribute it and/or modify it 
  7  # under the terms of the GNU General Public License version 2 or (at your 
  8  # option) any later version as published by the Free Software Foundation. 
  9  # 
 10  # For complete information please visit: http://www.zenoss.com/oss/ 
 11  # 
 12  ########################################################################### 
 13   
 14  __doc__="""DataRoot 
 15   
 16  DataRoot is the object manager which contains all confmon 
 17  data objects.  It can be used as a global acquisition 
 18  name space. 
 19  """ 
 20   
 21  import re 
 22  from zope.interface import implements 
 23  from AccessControl import ClassSecurityInfo 
 24  from AccessControl import getSecurityManager 
 25  from OFS.OrderedFolder import OrderedFolder 
 26  from Globals import DTMLFile 
 27  from Globals import InitializeClass 
 28  from Globals import DevelopmentMode 
 29  from Products.ZenModel.SiteError import SiteError 
 30  from Products.ZenModel.ZenModelBase import ZenModelBase 
 31  from Products.ZenModel.ZenMenuable import ZenMenuable 
 32  from Products.ZenRelations.RelSchema import * 
 33  from Products.ZenUtils.IpUtil import IpAddressError 
 34  from Products.ZenWidgets import messaging 
 35  from Products.ZenUtils.Security import activateSessionBasedAuthentication, activateCookieBasedAuthentication 
 36  from Commandable import Commandable 
 37  import socket 
 38  import os 
 39  import sys 
 40  from sets import Set 
 41  import string 
 42   
 43  from Products.ZenUtils.Utils import zenPath, binPath 
 44  from Products.ZenUtils.Utils import extractPostContent 
 45  from Products.ZenUtils.jsonutils import json 
 46   
 47  from Products.ZenEvents.Exceptions import * 
 48   
 49  from ZenModelRM import ZenModelRM 
 50  from ZenossSecurity import ZEN_COMMON, ZEN_MANAGE_DMD, ZEN_VIEW 
 51  from interfaces import IDataRoot 
52 53 -def manage_addDataRoot(context, id, title = None, REQUEST = None):
54 """make a device""" 55 dr = DataRoot(id, title) 56 context._setObject(id, dr) 57 58 if REQUEST is not None: 59 REQUEST['RESPONSE'].redirect(context.absolute_url() + '/manage_main')
60 61 62 addDataRoot = DTMLFile('dtml/addDataRoot',globals()) 63 64 __pychecker__='no-override'
65 66 -class DataRoot(ZenModelRM, OrderedFolder, Commandable, ZenMenuable):
67 implements(IDataRoot) 68 69 meta_type = portal_type = 'DataRoot' 70 71 manage_main = OrderedFolder.manage_main 72 73 manage_options = OrderedFolder.manage_options 74 75 #setTitle = DTMLFile('dtml/setTitle',globals()) 76 77 _rq = True 78 uuid = None 79 availableVersion = None 80 lastVersionCheck = 0 81 lastVersionCheckAttempt = 0 82 versionCheckOptIn = True 83 reportMetricsOptIn = True 84 acceptedTerms = True 85 instanceIdentifier = 'Zenoss' 86 smtpHost = 'localhost' 87 pageCommand = '$ZENHOME/bin/zensnpp localhost 444 $RECIPIENT' 88 smtpPort = 25 89 smtpUser = '' 90 smtpPass = '' 91 smtpUseTLS = 0 92 emailFrom = '' 93 iconMap = {} 94 geomapapikey = '' 95 geocache = '' 96 version = "" 97 enableLiveSearch = True 98 # how we should store our user credentials 99 AUTH_TYPE_SESSION = "session" 100 AUTH_TYPE_COOKIE = "cookie" 101 userAuthType = AUTH_TYPE_SESSION 102 pauseHubNotifications = False 103 # Setting applied to the User Interface to determine if we should load the 104 # infrastructure trees all at once or incrementally as expanded 105 incrementalTreeLoad = False 106 107 _properties=( 108 {'id':'title', 'type': 'string', 'mode':'w'}, 109 {'id':'prodStateDashboardThresh','type':'int','mode':'w'}, 110 {'id':'prodStateConversions','type':'lines','mode':'w'}, 111 {'id':'priorityConversions','type':'lines','mode':'w'}, 112 {'id':'priorityDashboardThresh','type':'int','mode':'w'}, 113 {'id':'statusConversions','type':'lines','mode':'w'}, 114 {'id':'interfaceStateConversions','type':'lines','mode':'w'}, 115 {'id':'administrativeRoles','type':'lines','mode':'w'}, 116 {'id':'uuid', 'type': 'string', 'mode':'w'}, 117 {'id':'availableVersion', 'type': 'string', 'mode':'w'}, 118 {'id':'lastVersionCheck', 'type': 'long', 'mode':'w'}, 119 {'id':'lastVersionCheckAttempt', 'type': 'long', 'mode':'w'}, 120 {'id':'versionCheckOptIn', 'type': 'boolean', 'mode':'w'}, 121 {'id':'reportMetricsOptIn', 'type': 'boolean', 'mode':'w'}, 122 {'id':'instanceIdentifier', 'type': 'string', 'mode':'w'}, 123 {'id':'smtpHost', 'type': 'string', 'mode':'w'}, 124 {'id':'smtpPort', 'type': 'int', 'mode':'w'}, 125 {'id':'pageCommand', 'type': 'string', 'mode':'w'}, 126 {'id':'smtpUser', 'type': 'string', 'mode':'w'}, 127 {'id':'smtpPass', 'type': 'string', 'mode':'w'}, 128 {'id':'smtpUseTLS', 'type': 'int', 'mode':'w'}, 129 {'id':'emailFrom', 'type': 'string', 'mode':'w'}, 130 {'id':'geomapapikey', 'type': 'string', 'mode':'w'}, 131 {'id':'userAuthType', 'type': 'string', 'mode':'w'}, 132 {'id':'geocache', 'type': 'string', 'mode':'w'}, 133 {'id':'enableLiveSearch', 'type': 'boolean', 'mode':'w'}, 134 {'id':'incrementalTreeLoad', 'type': 'boolean', 'mode':'w'}, 135 {'id':'pauseHubNotifications', 'type': 'boolean', 'mode':'w'}, 136 ) 137 138 _relations = ( 139 ('userCommands', ToManyCont(ToOne, 'Products.ZenModel.UserCommand', 'commandable')), 140 # packs is depracated. Has been moved to dmd.ZenPackManager.packs 141 # Should be removed post Zenoss 2.2 142 # TODO 143 ('packs', ToManyCont(ToOne, 'Products.ZenModel.ZenPack', 'root')), 144 ('zenMenus', ToManyCont( 145 ToOne, 'Products.ZenModel.ZenMenu', 'menuable')), 146 ) 147 148 # Screen action bindings (and tab definitions) 149 factory_type_information = ( 150 { 151 'id' : 'DataRoot', 152 'meta_type' : 'DataRoot', 153 'description' : """Arbitrary device grouping class""", 154 'icon' : 'DataRoot_icon.gif', 155 'product' : 'ZenModel', 156 'factory' : 'manage_addStatusMonitorconf', 157 'immediate_view' : 'Dashboard', 158 'actions' : 159 ( 160 { 'id' : 'settings' 161 , 'name' : 'Settings' 162 , 'action' : 'editSettings' 163 , 'permissions' : ( "Manage DMD", ) 164 }, 165 { 'id' : 'manage' 166 , 'name' : 'Commands' 167 , 'action' : 'dataRootManage' 168 , 'permissions' : ('Manage DMD',) 169 }, 170 { 'id' : 'users' 171 , 'name' : 'Users' 172 , 'action' : 'ZenUsers/manageUserFolder' 173 , 'permissions' : ( 'Manage DMD', ) 174 }, 175 { 'id' : 'packs' 176 , 'name' : 'ZenPacks' 177 , 'action' : 'ZenPackManager/viewZenPacks' 178 , 'permissions' : ( "Manage DMD", ) 179 }, 180 { 'id' : 'jobs' 181 , 'name' : 'Jobs' 182 , 'action' : 'joblist' 183 , 'permissions' : ( "Manage DMD", ) 184 }, 185 { 'id' : 'portlets' 186 , 'name' : 'Portlets' 187 , 'action' : 'editPortletPerms' 188 , 'permissions' : ( "Manage DMD", ) 189 }, 190 { 'id' : 'daemons' 191 , 'name' : 'Daemons' 192 , 'action' : '../About/zenossInfo' 193 , 'permissions' : ( "Manage DMD", ) 194 }, 195 { 'id' : 'versions' 196 , 'name' : 'Versions' 197 , 'action' : '../About/zenossVersions' 198 , 'permissions' : ( "Manage DMD", ) 199 }, 200 { 'id' : 'backups' 201 , 'name' : 'Backups' 202 , 'action' : 'backupInfo' 203 , 'permissions' : ( "Manage DMD", ) 204 }, 205 { 'id' : 'eventConfig' 206 , 'name' : 'Events' 207 , 'action' : 'eventConfig' 208 , 'permissions' : ( "Manage DMD", ) 209 }, 210 ) 211 }, 212 ) 213 214 security = ClassSecurityInfo() 215 216 # production state threshold at which devices show on dashboard 217 prodStateDashboardThresh = 1000 218 219 # priority threshold at which devices show on dashboard 220 priorityDashboardThresh = 2 221 222 prodStateConversions = [ 223 'Production:1000', 224 'Pre-Production:500', 225 'Test:400', 226 'Maintenance:300', 227 'Decommissioned:-1', 228 ] 229 230 priorityConversions = [ 231 'Highest:5', 232 'High:4', 233 'Normal:3', 234 'Low:2', 235 'Lowest:1', 236 'Trivial:0', 237 ] 238 239 statusConversions = [ 240 'Up:0', 241 'None:-1', 242 'No DNS:-2', 243 ] 244 245 interfaceStateConversions = [ 246 'up:1', 247 'down:2', 248 'testing:3', 249 'unknown:4', 250 'dormant:5', 251 'notPresent:6', 252 'lowerLayerDown:7', 253 ] 254 255 administrativeRoles = ( 256 "Administrator", 257 "Analyst", 258 "Engineer", 259 "Tester", 260 ) 261 262 defaultDateRange = 129600 263 performanceDateRanges = [ 264 ('Hourly',129600,), 265 ('Daily',864000,), 266 ('Weekly',3628800,), 267 ('Monthly',41472000,), 268 ('Yearly',62208000,) 269 ] 270 271 272 # when calculating the primary path this will be its root 273 zPrimaryBasePath = ("", "zport") 274 275
276 - def __init__(self, id, title=None):
277 ZenModelRM.__init__(self, id, title) 278 from ZVersion import VERSION 279 self.version = "Zenoss " + VERSION
280
281 - def index_html(self):
282 """ 283 Override to force redirection to quickstart. 284 """ 285 if not self._rq: 286 return self.unrestrictedTraverse('quickstart')() 287 return self()
288
289 - def getEventCount(self, **kwargs):
290 """Return the current event list for this managed entity. 291 """ 292 return self.ZenEventManager.getEventCount(**kwargs)
293 294 security.declareProtected(ZEN_COMMON, 'getEventClassNames')
295 - def getEventClassNames(self):
296 """ 297 Get a list of all event class names within the permission scope. 298 """ 299 return self.Events.getOrganizerNames()
300 301
302 - def getDmdRoots(self):
303 return filter(lambda o: o.isInTree, self.objectValues())
304 305
306 - def exportXmlHook(self,ofile, ignorerels):
307 map(lambda x: x.exportXml(ofile, ignorerels), self.getDmdRoots())
308 309 310 security.declareProtected(ZEN_COMMON, 'getProdStateConversions')
311 - def getProdStateConversions(self):
312 """getProdStateConversions() -> return a list of tuples 313 for prodstat select edit box""" 314 return self.getConversions(self.prodStateConversions)
315 316 317 security.declareProtected(ZEN_COMMON, 'convertProdState')
318 - def convertProdState(self, prodState):
319 '''convert a numeric production state to a 320 textual representation using the prodStateConversions 321 map''' 322 return self.convertAttribute(prodState, self.prodStateConversions)
323 324 325 security.declareProtected(ZEN_COMMON, 'getStatusConversions')
326 - def getStatusConversions(self):
327 """get text strings for status field""" 328 return self.getConversions(self.statusConversions)
329 330 331 security.declareProtected(ZEN_COMMON, 'convertStatus')
332 - def convertStatus(self, status):
333 """get text strings for status field""" 334 return self.convertAttribute(status, self.statusConversions)
335 336 security.declareProtected(ZEN_COMMON, 'getPriorityConversions')
337 - def getPriorityConversions(self):
338 return self.getConversions(self.priorityConversions)
339 340 security.declareProtected(ZEN_COMMON, 'convertPriority')
341 - def convertPriority(self, priority):
343 344 security.declareProtected(ZEN_COMMON, 'getInterfaceStateConversions')
346 """get text strings for interface status""" 347 if hasattr(self, 'interfaceStateConversions'): 348 return self.getConversions(self.interfaceStateConversions)
349 350 351 security.declareProtected(ZEN_COMMON, 'convertAttribute')
352 - def convertAttribute(self, numbValue, conversions):
353 '''convert a numeric production state to a 354 textual representation using the prodStateConversions 355 map''' 356 numbValue = int(numbValue) 357 for line in conversions: 358 line = line.rstrip() 359 (name, number) = line.split(':') 360 if int(number) == numbValue: 361 return name 362 return numbValue
363 364 security.declareProtected(ZEN_COMMON, 'convertStatusToDot')
365 - def convertStatusToDot(self, status):
366 colors = ['green', 'yellow', 'orange', 'red'] 367 try: 368 return colors[status] 369 except IndexError: 370 return 'grey'
371 372 security.declareProtected(ZEN_COMMON, 'getConversions')
373 - def getConversions(self, attribute):
374 """get the text list of itmes that convert to ints""" 375 convs = [] 376 for item in attribute: 377 tup = item.split(':') 378 try: 379 tup[1] = int(tup[1]) 380 except (IndexError, ValueError): 381 continue 382 convs.append(tup) 383 return convs
384 385 security.declarePublic('filterObjectsRegex')
386 - def filterObjectsRegex(self, filter, objects, 387 filteratt='id', negatefilter=0):
388 """filter a list of objects based on a regex""" 389 filter = re.compile(filter).search 390 filteredObjects = [] 391 for obj in objects: 392 value = getattr(obj, filteratt, None) 393 if callable(value): 394 value = value() 395 fvalue = filter(value) 396 if (fvalue and not negatefilter) or (not fvalue and negatefilter): 397 filteredObjects.append(obj) 398 return filteredObjects
399 400 401 security.declareProtected('View', 'myUserGroups')
402 - def myUserGroups(self):
403 user = self.REQUEST.get('AUTHENTICATED_USER') 404 if hasattr(user, 'getGroups'): 405 return user.getGroups() 406 else: 407 return ()
408 409 410 security.declareProtected('View', 'getAllUserGroups')
411 - def getAllUserGroups(self):
412 return self.acl_users.getGroups()
413 414 415 security.declareProtected(ZEN_VIEW, 'zenoss_error_message')
416 - def zenoss_error_message(self,error_type,error_value, 417 error_traceback,error_message):
418 """Return an error page that is more friendly then the standard stack 419 trace + feedback page for ConflictErrors and MySQL errors (we need to 420 add out of disk space errors). If one of these is not found we return 421 the old stacktrace page 422 """ 423 from ZODB.POSException import ConflictError 424 from Products.ZenEvents.Exceptions import MySQLConnectionError 425 from _mysql_exceptions import MySQLError 426 if isinstance(error_value, ConflictError): 427 return self.zenoss_conflict_error_message() 428 elif isinstance(error_value, MySQLConnectionError) \ 429 or isinstance(error_value, MySQLError): 430 return self.zenoss_mysql_error_message(error_value=error_value) 431 432 from traceback import format_exception 433 error_formatted = ''.join(format_exception(error_type, error_value, error_traceback)) 434 return self.zenoss_feedback_error_message(error_type=error_type, 435 error_value=error_value, 436 error_traceback=error_traceback, 437 error_formatted=error_formatted)
438 439
440 - def reportError(self):
441 ''' send an email to the zenoss error email address 442 then send user to a thankyou page or an email error page. 443 ''' 444 if self.smtpHost: host = self.smtpHost 445 else: host = None 446 port = self.smtpPort and self.smtpPort or 25 447 usetls = self.smtpUseTLS 448 usr = self.smtpUser 449 pwd = self.smtpPass 450 451 mailSent = SiteError.sendErrorEmail( 452 self.REQUEST.errorType, 453 self.REQUEST.errorValue, 454 self.REQUEST.errorTrace, 455 self.REQUEST.errorUrl, 456 self.About.getZenossRevision(), 457 self.About.getZenossVersionShort(), 458 self.REQUEST.contactName, 459 self.REQUEST.contactEmail, 460 self.REQUEST.comments, 461 host, port, usetls, usr, pwd) 462 if not mailSent: 463 body = SiteError.createReport( 464 self.REQUEST.errorType, 465 self.REQUEST.errorValue, 466 self.REQUEST.errorTrace, 467 self.REQUEST.errorUrl, 468 self.About.getZenossRevision(), 469 self.About.getZenossVersionShort(), 470 True, 471 self.REQUEST.contactName, 472 self.REQUEST.contactEmail, 473 self.REQUEST.comments) 474 return self.errorEmailFailure(toAddress=SiteError.ERRORS_ADDRESS, 475 body=body) 476 return self.errorEmailThankYou()
477 478 479 #security.declareProtected('View', 'writeExportRows')
480 - def writeExportRows(self, fieldsAndLabels, objects, out=None):
481 '''Write out csv rows with the given objects and fields. 482 If out is not None then call out.write() with the result and return None 483 otherwise return the result. 484 Each item in fieldsAndLabels is either a string representing a 485 field/key/index (see getDataField) or it is a tuple of (field, label) 486 where label is the string to be used in the first row as label 487 for that column. 488 Objects can be either dicts, lists/tuples or other objects. Field 489 is interpreted as a key, index or attribute depending on what 490 object is. 491 Method names can be passed instead of attribute/key/indices as field. 492 In this case the method is called and the return value is used in 493 the export. 494 ''' 495 import csv 496 import StringIO 497 if out: 498 buffer = out 499 else: 500 buffer = StringIO.StringIO() 501 fields = [] 502 labels = [] 503 if not fieldsAndLabels: 504 fieldsAndLabels = [] 505 if not objects: 506 objects = [] 507 for p in fieldsAndLabels: 508 if isinstance(p, tuple): 509 fields.append(p[0]) 510 labels.append(p[1]) 511 else: 512 fields.append(p) 513 labels.append(p) 514 writer = csv.writer(buffer) 515 writer.writerow(labels) 516 def getDataField(thing, field): 517 if isinstance(thing, dict): 518 value = thing.get(field, '') 519 elif isinstance(thing, list) or isinstance(thing, tuple): 520 value = thing[int(field)] 521 else: 522 value = getattr(thing, field, '') 523 if isinstance(value, ZenModelBase): 524 value = value.id 525 elif callable(value): 526 value = value() 527 if value == None: 528 value = '' 529 return str(value)
530 for o in objects: 531 writer.writerow([getDataField(o,f) for f in fields]) 532 if out: 533 result = None 534 else: 535 result = buffer.getvalue() 536 return result
537 538
539 - def getUserCommandTargets(self):
540 ''' Called by Commandable.doCommand() to ascertain objects on which 541 a UserCommand should be executed. 542 ''' 543 raise NotImplemented
544 545
546 - def getUrlForUserCommands(self):
547 return self.getPrimaryUrlPath() + '/dataRootManage'
548 549
550 - def getEmailFrom(self):
551 ''' Return self.emailFrom or a suitable default 552 ''' 553 return self.emailFrom or 'zenossuser_%s@%s' % ( 554 getSecurityManager().getUser().getId(), socket.getfqdn())
555 556
557 - def checkValidId(self, id, prep_id = False):
558 """Checks a valid id 559 """ 560 if len(id) > 128: 561 return 'ZenPack names can not be longer than 128 characters.' 562 allowed = Set(list(string.ascii_letters) 563 + list(string.digits) 564 + ['_']) 565 attempted = Set(list(id)) 566 if not attempted.issubset(allowed): 567 return 'Only letters, digits and underscores are allowed' + \ 568 ' in ZenPack names.' 569 return ZenModelRM.checkValidId(self, id, prep_id)
570 571
572 - def setGeocodeCache(self, REQUEST=None):
573 """ Store a JSON representation of 574 the Google Maps geocode cache 575 """ 576 cache = extractPostContent(REQUEST) 577 try: cache = cache.decode('utf-8') 578 except: pass 579 self.geocache = cache 580 return True
581
582 - def clearGeocodeCache(self, REQUEST=None):
583 """ 584 Clear the Google Maps cache. 585 """ 586 self.geocache = ''
587 588 security.declareProtected(ZEN_COMMON, 'getGeoCache') 589 @json
590 - def getGeoCache(self):
591 cachestr = self.geocache 592 for char in ('\\r', '\\n'): 593 cachestr = cachestr.replace(char, ' ') 594 return cachestr
595
596 - def goToStatusPage(self, objid, REQUEST=None):
597 """ Find a device or network and redirect 598 to its status page. 599 """ 600 import urllib 601 objid = urllib.unquote(objid) 602 try: 603 devid = objid 604 if not devid.endswith('*'): devid += '*' 605 obj = self.Devices.findDevice(devid) 606 except: 607 obj=None 608 if not obj: 609 try: 610 obj = self.Networks.getNet(objid) 611 except IpAddressError: 612 return None 613 if not obj: return None 614 if REQUEST is not None: 615 REQUEST['RESPONSE'].redirect(obj.getPrimaryUrlPath())
616 617
618 - def getXMLEdges(self, objid, depth=1, filter="/"):
619 """ Get the XML representation of network nodes 620 and edges using the obj with objid as a root 621 """ 622 import urllib 623 objid = urllib.unquote(objid) 624 try: 625 devid = objid 626 if not devid.endswith('*'): devid += '*' 627 obj = self.Devices.findDevice(devid) 628 except: obj=None 629 if not obj: 630 obj = self.Networks.getNet(objid) 631 if not obj: 632 return '<graph><Start name="%s"/></graph>' % objid 633 return obj.getXMLEdges(int(depth), filter, 634 start=(obj.id,obj.getPrimaryUrlPath()))
635 636 637 security.declareProtected(ZEN_MANAGE_DMD, 'getBackupFilesInfo')
638 - def getBackupFilesInfo(self):
639 """ 640 Retrieve a list of dictionaries describing the files in 641 $ZENHOME/backups. 642 """ 643 import stat 644 import os 645 import datetime 646 import operator 647 648 def FmtFileSize(size): 649 for power, units in ((3, 'GB'), (2, 'MB'), (1, 'KB')): 650 if size > pow(1024, power): 651 fmt = '%.2f %s' % ((size * 1.0)/pow(1024, power), units) 652 break 653 else: 654 fmt = '%s bytes' % size 655 return fmt
656 657 backupsDir = zenPath('backups') 658 fileInfo = [] 659 if os.path.isdir(backupsDir): 660 for dirPath, dirNames, fileNames in os.walk(backupsDir): 661 dirNames[:] = [] 662 for fileName in fileNames: 663 filePath = os.path.join(backupsDir, fileName) 664 info = os.stat(filePath) 665 fileInfo.append({ 666 'fileName': fileName, 667 'size': info[stat.ST_SIZE], 668 'sizeFormatted': FmtFileSize(info[stat.ST_SIZE]), 669 'modDate': info[stat.ST_MTIME], 670 'modDateFormatted': datetime.datetime.fromtimestamp( 671 info[stat.ST_MTIME]).strftime( 672 '%c'), 673 }) 674 fileInfo.sort(key=operator.itemgetter('modDate')) 675 return fileInfo 676 677 678 security.declareProtected(ZEN_MANAGE_DMD, 'manage_createBackup')
679 - def manage_createBackup(self, includeEvents=None, includeMysqlLogin=None, 680 timeout=120, REQUEST=None, writeMethod=None):
681 """ 682 Create a new backup file using zenbackup and the options specified 683 in the request. 684 685 This method makes use of the fact that DataRoot is a Commandable 686 in order to use Commandable.write 687 """ 688 import popen2 689 import fcntl 690 import time 691 import select 692 693 def write(s): 694 if writeMethod: 695 writeMethod(s) 696 elif REQUEST: 697 self.write(REQUEST.RESPONSE, s)
698 699 footer = None 700 if REQUEST and not writeMethod: 701 header, footer = self.commandOutputTemplate().split('OUTPUT_TOKEN') 702 REQUEST.RESPONSE.write(str(header)) 703 write('') 704 try: 705 cmd = binPath('zenbackup') + ' -v10' 706 if not includeEvents: 707 cmd += ' --no-eventsdb' 708 if not includeMysqlLogin: 709 cmd += ' --no-save-mysql-access' 710 try: 711 timeout = int(timeout) 712 except ValueError: 713 timeout = 120 714 timeout = max(timeout, 1) 715 child = popen2.Popen4(cmd) 716 flags = fcntl.fcntl(child.fromchild, fcntl.F_GETFL) 717 fcntl.fcntl(child.fromchild, fcntl.F_SETFL, flags | os.O_NDELAY) 718 endtime = time.time() + timeout 719 write('%s' % cmd) 720 write('') 721 pollPeriod = 1 722 firstPass = True 723 while time.time() < endtime and (firstPass or child.poll() == -1): 724 firstPass = False 725 r, w, e = select.select([child.fromchild], [], [], pollPeriod) 726 if r: 727 t = child.fromchild.read() 728 # We are sometimes getting to this point without any data 729 # from child.fromchild. I don't think that should happen 730 # but the conditional below seems to be necessary. 731 if t: 732 write(t) 733 734 if child.poll() == -1: 735 write('Backup timed out after %s seconds.' % timeout) 736 import signal 737 os.kill(child.pid, signal.SIGKILL) 738 739 write('DONE') 740 except: 741 write('Exception while performing backup.') 742 write('type: %s value: %s' % tuple(sys.exc_info()[:2])) 743 write('') 744 if REQUEST and footer: 745 REQUEST.RESPONSE.write(footer) 746 747 748 security.declareProtected(ZEN_MANAGE_DMD, 'manage_deleteBackups')
749 - def manage_deleteBackups(self, fileNames=(), REQUEST=None):
750 """ 751 Delete the specified files from $ZENHOME/backups 752 """ 753 backupsDir = zenPath('backups') 754 count = 0 755 if os.path.isdir(backupsDir): 756 for dirPath, dirNames, dirFileNames in os.walk(backupsDir): 757 dirNames[:] = [] 758 for fileName in fileNames: 759 if fileName in dirFileNames: 760 res = os.remove(os.path.join(dirPath, fileName)) 761 if res == 0: 762 count += 1 763 if REQUEST: 764 messaging.IMessageSender(self).sendToBrowser( 765 'Backups Deleted', 766 '%s backup files have been deleted.' % count 767 ) 768 else: 769 if REQUEST: 770 messaging.IMessageSender(self).sendToBrowser( 771 'Backup Directory Missing', 772 'Unable to find $ZENHOME/backups.', 773 priority=messaging.WARNING 774 ) 775 if REQUEST: 776 return self.callZenScreen(REQUEST)
777 778
779 - def getProductName(self):
780 """ 781 Return a string that represents the Zenoss product that is installed. 782 Currently this is something like 'core' or 'enterprise'. This is 783 used in the version check code to retrieve the available version 784 for the correct product. 785 """ 786 return getattr(self, 'productName', 'core')
787 788
789 - def error_handler(self, error=None):
790 """ 791 Returns pretty messages when errors are raised in templates. 792 793 Access this method from a template like so: 794 <div tal:content="..." 795 ... 796 tal:on-error="structure python:here.dmd.error_handler(error)"> 797 798 @param error: A TALES.ErrorInfo instance with attributes type, value 799 and traceback. 800 @return: HTML fragment with an error message 801 """ 802 if error.type==MySQLConnectionError: 803 msg = "Unable to connect to the MySQL server." 804 805 elif error.type in [ pythonThresholdException, rpnThresholdException ]: 806 msg= error.value 807 808 else: 809 raise 810 811 return '<b class="errormsg">%s</b>' % msg
812 813 @json
814 - def isDebugMode(self):
815 """ 816 Whether we're in debug mode, so that javascript will behave accordingly 817 """ 818 return DevelopmentMode
819
820 - def versionId(self):
821 """ 822 Get a string representative of the code version, to override JS 823 caching. 824 """ 825 return self.About.getZenossVersion().full().replace( 826 'Zenoss','').replace(' ','').replace('.','')
827 828 security.declareProtected('Manage DMD', 'zmanage_editProperties')
829 - def zmanage_editProperties(self, REQUEST=None, redirect=False):
830 """Handle our authentication mechanism 831 """ 832 if REQUEST: 833 app = self.unrestrictedTraverse('/') 834 if REQUEST.get('userAuthType') == self.AUTH_TYPE_SESSION: 835 activateSessionBasedAuthentication(self.zport) 836 activateSessionBasedAuthentication(app) # for admin 837 elif REQUEST.get('userAuthType') == self.AUTH_TYPE_COOKIE: 838 activateCookieBasedAuthentication(self.zport) 839 activateCookieBasedAuthentication(app) # for admin 840 return super(DataRoot, self).zmanage_editProperties(REQUEST, redirect)
841 842 843 InitializeClass(DataRoot) 844