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

Source Code for Module 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 as published by 
  8  # 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 AccessControl import ClassSecurityInfo 
 23  from AccessControl import getSecurityManager 
 24  from OFS.OrderedFolder import OrderedFolder 
 25  from OFS.CopySupport import CopyError, eNotSupported 
 26  from Products.CMFCore.DirectoryView import registerDirectory 
 27  from ImageFile import ImageFile 
 28  from Globals import HTMLFile, DTMLFile 
 29  from Globals import InitializeClass 
 30  from Acquisition import aq_base 
 31  from Products.PageTemplates.PageTemplateFile import PageTemplateFile 
 32  from Products.ZenModel.SiteError import SiteError 
 33  from ImageFile import ImageFile 
 34  from Products.ZenModel.ZenModelBase import ZenModelBase 
 35  from Products.ZenModel.ZenMenuable import ZenMenuable 
 36  from Products.ZenRelations.RelSchema import * 
 37  from Products.ZenUtils.IpUtil import IpAddressError 
 38  from Commandable import Commandable 
 39  import DateTime 
 40  import socket 
 41   
 42  from Products.ZenUtils.Utils import zenPath 
 43  from Products.ZenUtils.Utils import extractPostContent 
 44   
 45  from AccessControl import Permissions as permissions 
 46   
 47  from ZenModelRM import ZenModelRM 
 48  from ZenossSecurity import ZEN_COMMON 
 49   
50 -def manage_addDataRoot(context, id, title = None, REQUEST = None):
51 """make a device""" 52 dr = DataRoot(id, title) 53 context._setObject(id, dr) 54 55 if REQUEST is not None: 56 REQUEST['RESPONSE'].redirect(context.absolute_url() + '/manage_main')
57 58 59 addDataRoot = DTMLFile('dtml/addDataRoot',globals()) 60
61 -class DataRoot(ZenModelRM, OrderedFolder, Commandable, ZenMenuable):
62 meta_type = portal_type = 'DataRoot' 63 64 manage_main = OrderedFolder.manage_main 65 66 manage_options = OrderedFolder.manage_options 67 68 #setTitle = DTMLFile('dtml/setTitle',globals()) 69 70 uuid = None 71 availableVersion = None 72 lastVersionCheck = 0 73 lastVersionCheckAttempt = 0 74 versionCheckOptIn = True 75 reportMetricsOptIn = True 76 acceptedTerms = True 77 smtpHost = 'localhost' 78 snppHost = 'localhost' 79 smtpPort = 25 80 snppPort = 444 81 smtpUser = '' 82 smtpPass = '' 83 smtpUseTLS = 0 84 emailFrom = '' 85 iconMap = {} 86 geomapapikey = '' 87 geocache = '' 88 version = "" 89 90 _properties=( 91 {'id':'title', 'type': 'string', 'mode':'w'}, 92 {'id':'prodStateDashboardThresh','type':'int','mode':'w'}, 93 {'id':'prodStateConversions','type':'lines','mode':'w'}, 94 {'id':'priorityConversions','type':'lines','mode':'w'}, 95 {'id':'priorityDashboardThresh','type':'int','mode':'w'}, 96 {'id':'statusConversions','type':'lines','mode':'w'}, 97 {'id':'interfaceStateConversions','type':'lines','mode':'w'}, 98 {'id':'administrativeRoles','type':'lines','mode':'w'}, 99 {'id':'uuid', 'type': 'string', 'mode':'w'}, 100 {'id':'availableVersion', 'type': 'string', 'mode':'w'}, 101 {'id':'lastVersionCheck', 'type': 'long', 'mode':'w'}, 102 {'id':'lastVersionCheckAttempt', 'type': 'long', 'mode':'w'}, 103 {'id':'versionCheckOptIn', 'type': 'boolean', 'mode':'w'}, 104 {'id':'reportMetricsOptIn', 'type': 'boolean', 'mode':'w'}, 105 {'id':'smtpHost', 'type': 'string', 'mode':'w'}, 106 {'id':'smtpPort', 'type': 'int', 'mode':'w'}, 107 {'id':'snppHost', 'type': 'string', 'mode':'w'}, 108 {'id':'snppPort', 'type': 'int', 'mode':'w'}, 109 {'id':'smtpUser', 'type': 'string', 'mode':'w'}, 110 {'id':'smtpPass', 'type': 'string', 'mode':'w'}, 111 {'id':'smtpUseTLS', 'type': 'int', 'mode':'w'}, 112 {'id':'emailFrom', 'type': 'string', 'mode':'w'}, 113 {'id':'geomapapikey', 'type': 'string', 'mode':'w'}, 114 {'id':'geocache', 'type': 'string', 'mode':'w'}, 115 ) 116 117 _relations = ( 118 ('userCommands', ToManyCont(ToOne, 'Products.ZenModel.UserCommand', 'commandable')), 119 ('packs', ToManyCont(ToOne, 'Products.ZenModel.ZenPack', 'root')), 120 ('zenMenus', ToManyCont( 121 ToOne, 'Products.ZenModel.ZenMenu', 'menuable')), 122 ) 123 124 # Screen action bindings (and tab definitions) 125 factory_type_information = ( 126 { 127 'id' : 'DataRoot', 128 'meta_type' : 'DataRoot', 129 'description' : """Arbitrary device grouping class""", 130 'icon' : 'DataRoot_icon.gif', 131 'product' : 'ZenModel', 132 'factory' : 'manage_addStatusMonitorconf', 133 'immediate_view' : 'Dashboard', 134 'actions' : 135 ( 136 { 'id' : 'settings' 137 , 'name' : 'Settings' 138 , 'action' : 'editSettings' 139 , 'permissions' : ( "Manage DMD", ) 140 }, 141 { 'id' : 'manage' 142 , 'name' : 'Commands' 143 , 'action' : 'dataRootManage' 144 , 'permissions' : ('Manage DMD',) 145 }, 146 { 'id' : 'users' 147 , 'name' : 'Users' 148 , 'action' : 'ZenUsers/manageUserFolder' 149 , 'permissions' : ( 'Manage DMD', ) 150 }, 151 { 'id' : 'packs' 152 , 'name' : 'ZenPacks' 153 , 'action' : 'viewZenPacks' 154 , 'permissions' : ( "Manage DMD", ) 155 }, 156 { 'id' : 'menus' 157 , 'name' : 'Menus' 158 , 'action' : 'editMenus' 159 , 'permissions' : ( "Manage DMD", ) 160 }, 161 { 'id' : 'portlets' 162 , 'name' : 'Portlets' 163 , 'action' : 'editPortletPerms' 164 , 'permissions' : ( "Manage DMD", ) 165 }, 166 { 'id' : 'daemons' 167 , 'name' : 'Daemons' 168 , 'action' : '../About/zenossInfo' 169 , 'permissions' : ( "Manage DMD", ) 170 }, 171 { 'id' : 'versions' 172 , 'name' : 'Versions' 173 , 'action' : '../About/zenossVersions' 174 , 'permissions' : ( "Manage DMD", ) 175 }, 176 ) 177 }, 178 ) 179 180 security = ClassSecurityInfo() 181 182 # production state threshold at which devices show on dashboard 183 prodStateDashboardThresh = 1000 184 185 # priority threshold at which devices show on dashboard 186 priorityDashboardThresh = 2 187 188 prodStateConversions = [ 189 'Production:1000', 190 'Pre-Production:500', 191 'Test:400', 192 'Maintenance:300', 193 'Decommissioned:-1', 194 ] 195 196 priorityConversions = [ 197 'Highest:5', 198 'High:4', 199 'Normal:3', 200 'Low:2', 201 'Lowest:1', 202 'Trivial:0', 203 ] 204 205 statusConversions = [ 206 'Up:0', 207 'None:-1', 208 'No DNS:-2', 209 ] 210 211 interfaceStateConversions = [ 212 'up:1', 213 'down:2', 214 'testing:3', 215 'unknown:4', 216 'dormant:5', 217 'notPresent:6', 218 'lowerLayerDown:7', 219 ] 220 221 administrativeRoles = ( 222 "Administrator", 223 "Analyst", 224 "Engineer", 225 "Tester", 226 ) 227 228 defaultDateRange = 129600 229 performanceDateRanges = [ 230 ('Hourly',129600,), 231 ('Daily',864000,), 232 ('Weekly',3628800,), 233 ('Monthly',41472000,), 234 ('Yearly',62208000,) 235 ] 236 237 238 # when calculating the primary path this will be its root 239 zPrimaryBasePath = ("", "zport") 240 241
242 - def __init__(self, id, title=None):
243 ZenModelRM.__init__(self, id, title) 244 from ZVersion import VERSION 245 self.version = "Zenoss " + VERSION
246 247
248 - def getEventCount(self, **kwargs):
249 """Return the current event list for this managed entity. 250 """ 251 return self.ZenEventManager.getEventCount(**kwargs)
252 253
254 - def getDmdRoots(self):
255 return filter(lambda o: o.isInTree, self.objectValues())
256 257
258 - def exportXmlHook(self,ofile, ignorerels):
259 map(lambda x: x.exportXml(ofile, ignorerels), self.getDmdRoots())
260 261 262 security.declareProtected(ZEN_COMMON, 'getProdStateConversions')
263 - def getProdStateConversions(self):
264 """getProdStateConversions() -> return a list of tuples 265 for prodstat select edit box""" 266 return self.getConversions(self.prodStateConversions)
267 268 269 security.declareProtected(ZEN_COMMON, 'convertProdState')
270 - def convertProdState(self, prodState):
271 '''convert a numeric production state to a 272 textual representation using the prodStateConversions 273 map''' 274 return self.convertAttribute(prodState, self.prodStateConversions)
275 276 277 security.declareProtected(ZEN_COMMON, 'getStatusConversions')
278 - def getStatusConversions(self):
279 """get text strings for status field""" 280 return self.getConversions(self.statusConversions)
281 282 283 security.declareProtected(ZEN_COMMON, 'convertStatus')
284 - def convertStatus(self, status):
285 """get text strings for status field""" 286 return self.convertAttribute(status, self.statusConversions)
287 288 security.declareProtected(ZEN_COMMON, 'getPriorityConversions')
289 - def getPriorityConversions(self):
290 return self.getConversions(self.priorityConversions)
291 292 security.declareProtected(ZEN_COMMON, 'convertPriority')
293 - def convertPriority(self, priority):
295 296 security.declareProtected(ZEN_COMMON, 'getInterfaceStateConversions')
298 """get text strings for interface status""" 299 if hasattr(self, 'interfaceStateConversions'): 300 return self.getConversions(self.interfaceStateConversions)
301 302 303 security.declareProtected(ZEN_COMMON, 'convertAttribute')
304 - def convertAttribute(self, numbValue, conversions):
305 '''convert a numeric production state to a 306 textual representation using the prodStateConversions 307 map''' 308 numbValue = int(numbValue) 309 for line in conversions: 310 line = line.rstrip() 311 (name, number) = line.split(':') 312 if int(number) == numbValue: 313 return name 314 return numbValue
315 316 317 security.declareProtected(ZEN_COMMON, 'getConversions')
318 - def getConversions(self, attribute):
319 """get the text list of itmes that convert to ints""" 320 convs = [] 321 for item in attribute: 322 tup = item.split(':') 323 tup[1] = int(tup[1]) 324 convs.append(tup) 325 return convs
326 327 security.declarePublic('filterObjectsRegex')
328 - def filterObjectsRegex(self, filter, objects, 329 filteratt='id', negatefilter=0):
330 """filter a list of objects based on a regex""" 331 filter = re.compile(filter).search 332 filteredObjects = [] 333 for obj in objects: 334 value = getattr(obj, filteratt, None) 335 if callable(value): 336 value = value() 337 fvalue = filter(value) 338 if (fvalue and not negatefilter) or (not fvalue and negatefilter): 339 filteredObjects.append(obj) 340 return filteredObjects
341 342 343 security.declareProtected('View', 'myUserGroups')
344 - def myUserGroups(self):
345 user = self.REQUEST.get('AUTHENTICATED_USER') 346 if hasattr(user, 'getGroups'): 347 return user.getGroups() 348 else: 349 return ()
350 351 352 security.declareProtected('View', 'getAllUserGroups')
353 - def getAllUserGroups(self):
354 return self.acl_users.getGroups()
355
356 - def reportError(self):
357 ''' send an email to the zenoss error email address 358 then send user to a thankyou page or an email error page. 359 ''' 360 mailSent = SiteError.sendErrorEmail( 361 self.REQUEST.errorType, 362 self.REQUEST.errorValue, 363 self.REQUEST.errorTrace, 364 self.REQUEST.errorUrl, 365 self.About.getZenossRevision(), 366 self.About.getZenossVersionShort(), 367 self.REQUEST.contactName, 368 self.REQUEST.contactEmail, 369 self.REQUEST.comments) 370 if not mailSent: 371 toAddress = SiteError.ERRORS_ADDRESS 372 body = SiteError.createReport( 373 self.REQUEST.errorType, 374 self.REQUEST.errorValue, 375 self.REQUEST.errorTrace, 376 self.REQUEST.errorUrl, 377 self.About.getZenossRevision(), 378 self.About.getZenossVersionShort(), 379 True, 380 self.REQUEST.contactName, 381 self.REQUEST.contactEmail, 382 self.REQUEST.comments) 383 return getattr(self, 'errorEmailFailure')( 384 toAddress=SiteError.ERRORS_ADDRESS, 385 body=body) 386 return getattr(self, 'errorEmailThankYou')()
387 388 389 #security.declareProtected('View', 'writeExportRows')
390 - def writeExportRows(self, fieldsAndLabels, objects, out=None):
391 '''Write out csv rows with the given objects and fields. 392 If out is not None then call out.write() with the result and return None 393 otherwise return the result. 394 Each item in fieldsAndLabels is either a string representing a 395 field/key/index (see getDataField) or it is a tuple of (field, label) 396 where label is the string to be used in the first row as label 397 for that column. 398 Objects can be either dicts, lists/tuples or other objects. Field 399 is interpreted as a key, index or attribute depending on what 400 object is. 401 Method names can be passed instead of attribute/key/indices as field. 402 In this case the method is called and the return value is used in 403 the export. 404 ''' 405 import csv 406 import StringIO 407 if out: 408 buffer = out 409 else: 410 buffer = StringIO.StringIO() 411 fields = [] 412 labels = [] 413 if not fieldsAndLabels: 414 fieldsAndLabels = [] 415 if not objects: 416 objects = [] 417 for p in fieldsAndLabels: 418 if isinstance(p, tuple): 419 fields.append(p[0]) 420 labels.append(p[1]) 421 else: 422 fields.append(p) 423 labels.append(p) 424 writer = csv.writer(buffer) 425 writer.writerow(labels) 426 def getDataField(thing, field): 427 if isinstance(thing, dict): 428 value = thing.get(field, '') 429 elif isinstance(thing, list) or isinstance(thing, tuple): 430 value = thing[int(field)] 431 else: 432 value = getattr(thing, field, '') 433 if isinstance(value, ZenModelBase): 434 value = value.id 435 elif callable(value): 436 value = value() 437 if value == None: 438 value = '' 439 return str(value)
440 for o in objects: 441 writer.writerow([getDataField(o,f) for f in fields]) 442 if out: 443 result = None 444 else: 445 result = buffer.getvalue() 446 return result
447 448
449 - def getUserCommandTargets(self):
450 ''' Called by Commandable.doCommand() to ascertain objects on which 451 a UserCommand should be executed. 452 ''' 453 raise 'Not supported on DataRoot'
454 455
456 - def getUrlForUserCommands(self):
457 return self.getPrimaryUrlPath() + '/dataRootManage'
458 459
460 - def getEmailFrom(self):
461 ''' Return self.emailFrom or a suitable default 462 ''' 463 return self.emailFrom or 'zenossuser_%s@%s' % ( 464 getSecurityManager().getUser().getId(), socket.getfqdn())
465
466 - def manage_addZenPack(self, id, 467 author="", 468 organization="", 469 version="", 470 REQUEST = None):
471 """make a new ZenPack""" 472 from ZenPack import ZenPack 473 pack = ZenPack(id) 474 pack.author = author 475 pack.organization = organization 476 pack.version = version 477 self.packs._setObject(id, pack) 478 import os 479 zp = zenPath('Products', id) 480 if not os.path.isdir(zp): 481 os.makedirs(zp, 0750) 482 for d in ['objects', 'skins', 'modeler/plugins', 483 'reports', 'daemons']: 484 os.makedirs(os.path.join(zp, d), 0750) 485 skinsDir = os.path.join(zp, 'skins') 486 skinsDir2 = os.path.join(skinsDir, id) 487 if not os.path.isdir(skinsDir2): 488 os.makedirs(skinsDir2, 0750) 489 registerDirectory(skinsDir, globals()) 490 # Install in order to register the skins directory 491 pack.install(self.getPhysicalRoot()) 492 if REQUEST is not None: 493 return self.callZenScreen(REQUEST, redirect=True)
494
495 - def removeZenPacks(self, ids=(), REQUEST = None):
496 """remove a ZenPack""" 497 import os 498 zp = zenPath('bin', 'zenpack') 499 import os 500 for pack in ids: 501 os.system('%s run --remove %s' % (zp, pack)) 502 self._p_jar.sync() 503 if REQUEST is not None: 504 return self.callZenScreen(REQUEST, redirect=True)
505 506
507 - def getBrokenPackName(self, pack):
508 ''' Extract the zenpack name from the broken module 509 ''' 510 return pack.__class__.__module__.split('.')[1]
511
512 - def getIconPath(self, obj):
513 """ Retrieve the appropriate image path associated 514 with a given object. 515 """ 516 try: 517 return obj.primaryAq().zIcon 518 except AttributeError: 519 return '/zport/dmd/img/icons/noicon.png'
520
521 - def setGeocodeCache(self, REQUEST=None):
522 """ Store a JSON representation of 523 the Google Maps geocode cache 524 """ 525 cache = extractPostContent(REQUEST) 526 self.geocache = cache 527 return True
528 529 security.declareProtected(ZEN_COMMON, 'getGeoCache')
530 - def getGeoCache(self, REQUEST=None):
531 cachestr = self.geocache 532 for char in ('\\r', '\\n'): 533 cachestr = cachestr.replace(char, ' ') 534 return cachestr
535
536 - def goToStatusPage(self, objid, REQUEST=None):
537 """ Find a device or network and redirect 538 to its status page. 539 """ 540 import urllib 541 objid = urllib.unquote(objid) 542 try: 543 devid = objid 544 if not devid.endswith('*'): devid += '*' 545 obj = self.Devices.findDevice(devid) 546 except: 547 obj=None 548 if not obj: 549 try: 550 obj = self.Networks.getNet(objid) 551 except IpAddressError: 552 return None 553 if not obj: return None 554 if REQUEST is not None: 555 REQUEST['RESPONSE'].redirect(obj.getPrimaryUrlPath())
556 557
558 - def getXMLEdges(self, objid, depth=1, filter="/"):
559 """ Get the XML representation of network nodes 560 and edges using the obj with objid as a root 561 """ 562 import urllib 563 objid = urllib.unquote(objid) 564 try: 565 devid = objid 566 if not devid.endswith('*'): devid += '*' 567 obj = self.Devices.findDevice(devid) 568 except: obj=None 569 if not obj: 570 obj = self.Networks.getNet(objid) 571 if not obj: 572 return '<graph><Start name="%s"/></graph>' % objid 573 return obj.getXMLEdges(int(depth), filter, 574 start=(obj.id,obj.getPrimaryUrlPath()))
575 576 InitializeClass(DataRoot) 577