Package Products :: Package ZenRelations :: Module ZenPropertyManager
[hide private]
[frames] | no frames]

Source Code for Module Products.ZenRelations.ZenPropertyManager

  1  ############################################################################## 
  2  #  
  3  # Copyright (C) Zenoss, Inc. 2007, all rights reserved. 
  4  #  
  5  # This content is made available according to terms specified in 
  6  # License.zenoss under the directory where your Zenoss product is installed. 
  7  #  
  8  ############################################################################## 
  9   
 10   
 11  import re 
 12  import logging 
 13   
 14  from OFS.PropertyManager import PropertyManager 
 15  from zExceptions import BadRequest 
 16  from Globals import DTMLFile 
 17  from Globals import InitializeClass 
 18  from Acquisition import aq_base, aq_chain 
 19  from ZPublisher.Converters import type_converters 
 20  from Products.ZenMessaging.audit import audit 
 21  from Products.ZenModel.ZenossSecurity import * 
 22  from AccessControl import ClassSecurityInfo 
 23  from Exceptions import zenmarker 
 24  from Products.ZenWidgets.interfaces import IMessageSender 
 25  from Products.ZenRelations.zPropertyCategory import getzPropertyCategory 
 26  from Products.ZenUtils.Utils import unused, getDisplayType 
 27   
 28  iszprop = re.compile("z[A-Z]").match 
 29   
 30  log = logging.getLogger('zen.PropertyManager') 
 31   
 32  # Z_PROPERTIES is a list of (id, type, value) pairs that define all the 
 33  # zProperties.  The values are set on dmd.Devices in the 
 34  # buildDeviceTreeProperties of DeviceClass 
 35  Z_PROPERTIES = [ 
 36   
 37      # zPythonClass maps device class to python classs (separate from device 
 38      # class name) 
 39      ('zPythonClass', '', 'string'), 
 40   
 41      # zProdStateThreshold is the production state threshold at which to start 
 42      # monitoring boxes 
 43      ('zProdStateThreshold', 300, 'int'), 
 44   
 45      # zIfDescription determines whether or not the ifdescripion field is 
 46      # displayed 
 47      ('zIfDescription', False, 'boolean'), 
 48   
 49      # Snmp collection properties 
 50      ('zSnmpCommunities', ['public', 'private'], 'lines'), 
 51      ('zSnmpCommunity', 'public', 'string'), 
 52      ('zSnmpPort', 161, 'int'), 
 53      ('zSnmpVer', 'v2c', 'string'), 
 54      ('zSnmpTries', 6, 'int'), 
 55      ('zSnmpTimeout', 1, 'float'), 
 56      ('zSnmpEngineId', '', 'string'), 
 57      ('zSnmpSecurityName', '', 'string'), 
 58      ('zSnmpAuthPassword', '', 'password'), 
 59      ('zSnmpPrivPassword', '', 'password'), 
 60      ('zSnmpAuthType', '', 'string'), 
 61      ('zSnmpPrivType', '', 'string'), 
 62      ('zSnmpCollectionInterval', 300, 'int'), 
 63      ('zRouteMapCollectOnlyLocal', False, 'boolean'), 
 64      ('zRouteMapCollectOnlyIndirect', False, 'boolean'), 
 65      ('zRouteMapMaxRoutes', 500, 'int'), 
 66      ('zInterfaceMapIgnoreTypes', '', 'string'), 
 67      ('zInterfaceMapIgnoreNames', '', 'string'), 
 68      ('zInterfaceMapIgnoreDescriptions', '', 'string'), 
 69      ('zFileSystemMapIgnoreTypes', [], 'lines'), 
 70      ('zFileSystemMapIgnoreNames', '', 'string'), 
 71      ('zFileSystemSizeOffset', 1.0, 'float'), 
 72      ('zHardDiskMapMatch', '', 'string'), 
 73      ('zSysedgeDiskMapIgnoreNames', '', 'string'), 
 74      ('zIpServiceMapMaxPort', 1024, 'int'), 
 75      ('zDeviceTemplates', ['Device'], 'lines'), 
 76      ('zLocalIpAddresses', '^127|^0\\.0|^169\\.254|^224', 'string'), 
 77      ('zLocalInterfaceNames', '^lo|^vmnet', 'string'), 
 78   
 79      # Status monitor properties 
 80      ('zSnmpMonitorIgnore', False, 'boolean'), 
 81      ('zPingMonitorIgnore', False, 'boolean'), 
 82      ('zStatusConnectTimeout', 15.0, 'float'), 
 83   
 84      # DataCollector properties 
 85      ('zCollectorPlugins', [], 'lines'), 
 86      ('zCollectorClientTimeout', 180, 'int'), 
 87      ('zCollectorDecoding', 'latin-1', 'string'), 
 88      ('zCommandUsername', '', 'string'), 
 89      ('zCommandPassword', '', 'password'), 
 90      ('zCommandProtocol', 'ssh', 'string'), 
 91      ('zCommandPort', 22, 'int'), 
 92      ('zCommandLoginTries', 1, 'int'), 
 93      ('zCommandLoginTimeout', 10.0, 'float'), 
 94      ('zCommandCommandTimeout', 10.0, 'float'), 
 95      ('zCommandSearchPath', [], 'lines'), 
 96      ('zCommandExistanceTest', 'test -f %s', 'string'), 
 97      ('zCommandPath', '/usr/local/zenoss/libexec', 'string'), 
 98      ('zTelnetLoginRegex', 'ogin:.$', 'string'), 
 99      ('zTelnetPasswordRegex', 'assword:', 'string'), 
100      ('zTelnetSuccessRegexList', ['\\$.$', '\\#.$'], 'lines'), 
101      ('zTelnetEnable', False, 'boolean'), 
102      ('zTelnetEnableRegex', 'assword:', 'string'), 
103      ('zTelnetTermLength', True, 'boolean'), 
104      ('zTelnetPromptTimeout', 10.0, 'float'), 
105      ('zKeyPath', '~/.ssh/id_dsa', 'string'), 
106      ('zMaxOIDPerRequest', 40, 'int'), 
107   
108      # Extra stuff for users 
109      ('zLinks', '', 'string'), 
110   
111      # zIcon is the icon path 
112      ('zIcon', '/zport/dmd/img/icons/noicon.png', 'string'), 
113   
114      # used in ApplyDataMap 
115      ('zCollectorLogChanges', True, 'boolean'), 
116   
117      # enable password for Cisco routers 
118      ('zEnablePassword', '', 'password'), 
119   
120      # used in zenoss.nmap.IpServiceMap 
121      ('zNmapPortscanOptions', '-p 1-1024 -sT -oG -', 'string'), 
122   
123      # how many SSH sessions to open up to one device (some SSH servers have a limit) 
124      ('zSshConcurrentSessions', 10, 'int'), 
125   
126      ] 
127   
128 -class PropertyDescriptor(object):
129 """ 130 Transforms the property value based on its type. 131 132 Follows the Descriptor protocol defined at 133 http://docs.python.org/reference/datamodel.html#descriptors 134 """ 135
136 - def __init__(self, id, type, transformer):
137 self.id = id 138 self.type = type 139 self.transformer = transformer
140
141 - def __get__(self, instance, owner):
142 """ 143 Returns self for class attribute access. Returns the transformed 144 value for instance attribute access. 145 """ 146 try: 147 if instance is None: 148 retval = self 149 else: 150 self._migrate(instance) 151 value = instance._propertyValues[self.id] 152 retval = self._transform(instance, value, 'transformForGet') 153 return retval 154 except: 155 raise AttributeError
156
157 - def __set__(self, instance, value):
158 """ 159 Transforms the value and sets it. 160 """ 161 self._migrate(instance) 162 self._set(instance, value)
163
164 - def __delete__(self, instance):
165 """ 166 Delete the property. 167 """ 168 self._migrate(instance) 169 del instance._propertyValues[self.id]
170
171 - def _migrate(self, instance):
172 """ 173 If the id is in __dict__ then move the value to the _propertyValues 174 dictionary. Check to make sure that the type of this descriptor class 175 and the type in the Zope OFS PropertyManager metadata are the same. 176 """ 177 if not hasattr(instance, '_propertyValues'): 178 instance._propertyValues = {} 179 if self.id in vars(instance): 180 self._set(instance, vars(instance)[self.id]) 181 del instance.__dict__[self.id] 182 instance._p_changed = True 183 for dct in instance._properties: 184 if dct['id'] == self.id: 185 if dct['type'] != self.type: 186 dct['type'] = self.type 187 instance._p_changed = True 188 break
189
190 - def _set(self, instance, value):
191 """ 192 Transform and set the value in the _propertyValues dictionary. 193 """ 194 valueToSet = self._transform(instance, value, 'transformForSet') 195 instance._propertyValues[self.id] = valueToSet
196
197 - def _transform(self, instance, value, method):
198 """ 199 Lookup the transformer for the type and transform the value. The 200 method parameter can be 'transformForGet' or 'transformForSet' and 201 determines the transformer method that is called. 202 """ 203 return getattr(self.transformer, method)(value)
204
205 -class ZenPropertyDoesNotExist(ValueError):
206 pass
207
208 -class ZenPropertyManager(object, PropertyManager):
209 """ 210 211 ZenPropertyManager adds keyedselection type to PropertyManager. 212 A keyedselection displayes a different name in the popup then 213 the actual value the popup will have. 214 215 It also has management for zenProperties which are properties that can be 216 inherited long the acquision chain. All properties are for a branch are 217 defined on a "root node" specified by the function which must be returned 218 by the function getZenRootNode that should be over ridden in a sub class. 219 Prperties can then be added further "down" the aq_chain by calling 220 setZenProperty on any contained node. 221 222 ZenProperties all have the same prefix which is defined by iszprop 223 this can be overridden in a subclass. 224 225 ZenPropertyManager overrides getProperty and getPropertyType from 226 PropertyManager to support acquisition. If you want to query an object 227 about a property, but do not want it to search the acquistion chain then 228 use the super classes method or aq_base. Example: 229 230 # acquires property from dmd.Devices 231 dmd.Devices.Server.getProperty('zCollectorPlugins') 232 233 # does not acquire property from dmd.Devices 234 PropertyManager.getProperty(dmd.Devices.Server, 'zCollectorPlugins') 235 236 # also does not acquire property from dmd.Devices 237 aq_base(dmd.Devices.Server).getProperty('zSnmpCommunity') 238 239 The properties are stored as attributes which is convenient, but can be 240 confusing. Attribute access always uses acquistion. Setting an 241 attribute, will not add it to the list of properties, so subsquent calls 242 to hasProperty or getProperty won't return it. 243 244 Property Transformers are stored at dmd.propertyTransformers and transform 245 the property based on type during calls to the _setProperty, 246 _updateProperty, and getProperty methods. Adding a property using 247 _setProperty applies the appropriate transformer and adds its value as an 248 attribute, but when you access it as an attribute the property transformer 249 is again applied, but this time using its transformForGet method. 250 """ 251 __pychecker__='no-override' 252 253 security = ClassSecurityInfo() 254 255 manage_propertiesForm=DTMLFile('dtml/properties', globals(), 256 property_extensible_schema__=1) 257
258 - def _setPropValue(self, id, value):
259 """override from PerpertyManager to handle checks and ip creation""" 260 self._wrapperCheck(value) 261 propType = self.getPropertyType(id) 262 if propType == 'keyedselection': 263 value = int(value) 264 if not getattr(self,'_v_propdict',False): 265 self._v_propdict = self.propdict() 266 if 'setter' in self._v_propdict: 267 settername = self._v_propdict['setter'] 268 setter = getattr(aq_base(self), settername, None) 269 if not setter: 270 raise ValueError("setter %s for property %s doesn't exist" 271 % (settername, id)) 272 if not callable(setter): 273 raise TypeError("setter %s for property %s not callable" 274 % (settername, id)) 275 setter(value) 276 else: 277 setattr(self, id, value)
278 279
280 - def _setProperty(self, id, value, type='string', label=None, 281 visible=True, setter=None):
282 """for selection and multiple selection properties 283 the value argument indicates the select variable 284 of the property 285 """ 286 self._wrapperCheck(value) 287 if not self.valid_property_id(id): 288 raise BadRequest, 'Id %s is invalid or duplicate' % id 289 290 def setprops(**pschema): 291 self._properties=self._properties+(pschema,) 292 if setter: pschema['setter'] = setter 293 if label: pschema['label'] = label
294 295 if type in ('selection', 'multiple selection'): 296 if not hasattr(self, value): 297 raise BadRequest, 'No select variable %s' % value 298 setprops(id=id,type=type, visible=visible, 299 select_variable=value) 300 if type=='selection': 301 self._setPropValue(id, '') 302 else: 303 self._setPropValue(id, []) 304 else: 305 setprops(id=id, type=type, visible=visible) 306 self._setPropValue(id, value)
307
308 - def _updateProperty(self, id, value):
309 """ This method sets a property on a zope object. It overrides the 310 method in PropertyManager. If Zope is upgraded you will need to check 311 that this method has not changed! It is overridden so that we can catch 312 the ValueError returned from the field2* converters in the class 313 Converters.py 314 """ 315 try: 316 super(ZenPropertyManager, self)._updateProperty(id, value) 317 except ValueError: 318 msg = "Error Saving Property '%s'. New value '%s' is of invalid " 319 msg += "type. It should be type '%s'." 320 proptype = self.getPropertyType(id) 321 args = (id, value, proptype) 322 log.error(msg % args)
323 324 325 _onlystars = re.compile("^\*+$").search 326 security.declareProtected(ZEN_ZPROPERTIES_EDIT, 'manage_editProperties')
327 - def manage_editProperties(self, REQUEST):
328 """ 329 Edit object properties via the web. 330 The purpose of this method is to change all property values, 331 even those not listed in REQUEST; otherwise checkboxes that 332 get turned off will be ignored. Use manage_changeProperties() 333 instead for most situations. 334 """ 335 for prop in self._propertyMap(): 336 name=prop['id'] 337 if 'w' in prop.get('mode', 'wd'): 338 value=REQUEST.get(name, '') 339 if self.zenPropIsPassword(name) and self._onlystars(value): 340 continue 341 self._updateProperty(name, value) 342 if getattr(self, "index_object", False): 343 self.index_object() 344 if REQUEST: 345 message="Saved changes." 346 return self.manage_propertiesForm(self,REQUEST, 347 manage_tabs_message=message)
348 349
350 - def getZenRootNode(self):
351 """sub class must implement to use zenProperties.""" 352 raise NotImplementedError
353 354 security.declareProtected(ZEN_ZPROPERTIES_VIEW, 'zenPropertyIds')
355 - def zenPropertyIds(self, all=True, pfilt=iszprop):
356 """ 357 Return list of device tree property names. 358 If all use list from property root node. 359 """ 360 if all: 361 rootnode = self.getZenRootNode() 362 else: 363 if self.id == self.dmdRootName: return [] 364 rootnode = aq_base(self) 365 return sorted(prop for prop in rootnode.propertyIds() if pfilt(prop))
366 367 security.declareProtected(ZEN_ZPROPERTIES_VIEW, 'zenPropertyItems')
368 - def zenPropertyItems(self):
369 """Return list of (id, value) tuples of zenProperties. 370 """ 371 return map(lambda x: (x, getattr(self, x)), self.zenPropertyIds())
372 373 security.declareProtected(ZEN_ZPROPERTIES_VIEW, 'zenPropertyMap')
374 - def zenPropertyMap(self, pfilt=iszprop):
375 """Return property mapping of device tree properties.""" 376 rootnode = self.getZenRootNode() 377 return sorted((pdict for pdict in rootnode.propertyMap() 378 if pfilt(pdict['id'])), 379 key=lambda x : x['id'])
380 381 security.declareProtected(ZEN_ZPROPERTIES_VIEW, 'zenPropertyString')
382 - def zenPropertyString(self, id):
383 """Return the value of a device tree property as a string""" 384 def displayLines(lines): 385 return '\n'.join(str(line) for line in lines)
386 def displayPassword(password): 387 return '*' * len(password) 388 def displayOthers(other): 389 return other 390 displayFunctions = {'lines': displayLines, 391 'password': displayPassword} 392 display = displayFunctions.get(self.getPropertyType(id), 393 displayOthers) 394 return display(self.getProperty(id, '')) 395 396 security.declareProtected(ZEN_ZPROPERTIES_VIEW, 'zenPropIsPassword')
397 - def zenPropIsPassword(self, id):
398 """Is this field a password field. 399 """ 400 return self.getPropertyType(id) == 'password'
401 402 security.declareProtected(ZEN_ZPROPERTIES_VIEW, 'zenPropertyPath')
403 - def zenPropertyPath(self, id):
404 """Return the primaryId of where a device tree property is found.""" 405 ob = self._findParentWithProperty(id) 406 if ob is None: 407 path = None 408 else: 409 path = ob.getPrimaryId(self.getZenRootNode().getId()) 410 return path
411 412 security.declareProtected(ZEN_ZPROPERTIES_EDIT, 'setZenProperty')
413 - def setZenProperty(self, propname, propvalue, REQUEST=None):
414 """ 415 Add or set the propvalue of the property propname on this node of 416 the device Class tree. 417 """ 418 ptype = self.getPropertyType(propname) 419 if ptype == 'lines': 420 dedupedList = [] 421 for x in propvalue: 422 if x not in dedupedList: 423 dedupedList.append(x) 424 propvalue = dedupedList 425 if getattr(aq_base(self), propname, zenmarker) != zenmarker: 426 self._updateProperty(propname, propvalue) 427 else: 428 if ptype in ("selection", 'multiple selection'): ptype="string" 429 if ptype in type_converters: 430 propvalue=type_converters[ptype](propvalue) 431 if getattr(self, propname, None) != propvalue: 432 self._setProperty(propname, propvalue, type=ptype) 433 if REQUEST: return self.callZenScreen(REQUEST)
434 435 security.declareProtected(ZEN_ZPROPERTIES_EDIT, 'saveZenProperties')
436 - def saveZenProperties(self, pfilt=iszprop, REQUEST=None):
437 """Save all ZenProperties found in the REQUEST.form object. 438 """ 439 maskFields=[] 440 for name, value in REQUEST.form.items(): 441 if pfilt(name): 442 if self.zenPropIsPassword(name): 443 maskFields.append(name) 444 if self._onlystars(value): 445 continue 446 if name == 'zCollectorPlugins': 447 if tuple(getattr(self, name, ())) != tuple(value): 448 self.setZenProperty(name, value) 449 else: 450 self.setZenProperty(name, value) 451 452 if REQUEST: 453 audit(('UI', getDisplayType(self), 'EditProperties'), self, data_=REQUEST.form, 454 skipFields_=['savezenproperties','zenscreenname'], maskFields_=maskFields) 455 IMessageSender(self).sendToBrowser( 456 'Configuration Propeties Updated', 457 'Configuration properties have been updated.' 458 ) 459 460 return self.callZenScreen(REQUEST)
461 462 security.declareProtected(ZEN_ZPROPERTIES_EDIT, 'deleteZenProperty')
463 - def deleteZenProperty(self, propname=None, REQUEST=None):
464 """ 465 Delete device tree properties from the this DeviceClass object. 466 """ 467 if propname: 468 try: 469 self._delProperty(propname) 470 except AttributeError: 471 #occasional object corruption where the propName is in 472 #_properties but not set as an attribute. filter out the prop 473 #and create a new _properties tuple 474 newProps = [x for x in self._properties if x['id'] != propname] 475 self._properties=tuple(newProps) 476 except ValueError: 477 raise ZenPropertyDoesNotExist() 478 if REQUEST: 479 if propname: 480 audit(('UI',getDisplayType(self),'DeleteZProperty'), self, property=propname) 481 return self.callZenScreen(REQUEST)
482 483 security.declareProtected(ZEN_ZPROPERTIES_VIEW, 'zenPropertyOptions')
484 - def zenPropertyOptions(self, propname):
485 "Provide a set of default options for a ZProperty" 486 unused(propname) 487 return []
488 489 security.declareProtected(ZEN_ZPROPERTIES_VIEW, 'isLocal')
490 - def isLocal(self, propname):
491 """Check to see if a name is local to our current context. 492 """ 493 v = getattr(aq_base(self), propname, zenmarker) 494 return v != zenmarker
495 496 security.declareProtected(ZEN_ZPROPERTIES_VIEW, 'getOverriddenObjects')
497 - def getOverriddenObjects(self, propname, showDevices=False):
498 """ Get the objects that override a property somewhere below in the tree 499 """ 500 if showDevices: 501 objects = [] 502 for inst in self.getSubInstances('devices'): 503 if inst.isLocal(propname) and inst not in objects: 504 objects.append(inst) 505 for suborg in self.children(): 506 if suborg.isLocal(propname): 507 objects.append(suborg) 508 for inst in suborg.getOverriddenObjects(propname, showDevices): 509 if inst not in objects: 510 objects.append(inst) 511 return objects 512 513 return [ org for org in self.getSubOrganizers() 514 if org.isLocal(propname) ]
515
516 - def _findParentWithProperty(self, id):
517 """ 518 Returns self or the first acquisition parent that has a property with 519 the id. Returns None if no parent had the id. 520 """ 521 for ob in aq_chain(self): 522 if isinstance(ob, ZenPropertyManager) and ob.hasProperty(id): 523 parentWithProperty = ob 524 break 525 else: 526 parentWithProperty = None 527 return parentWithProperty
528
529 - def hasProperty(self, id, useAcquisition=False):
530 """ 531 Override method in PropertyManager to support acquisition. 532 """ 533 if useAcquisition: 534 hasProp = self._findParentWithProperty(id) is not None 535 else: 536 hasProp = PropertyManager.hasProperty(self, id) 537 return hasProp
538
539 - def getProperty(self, id, d=None):
540 """ 541 Get property value and apply transformer. Overrides method in Zope's 542 PropertyManager class. Acquire values from aquisiton parents if 543 needed. 544 """ 545 ob = self._findParentWithProperty(id) 546 if ob is None: 547 value = d 548 else: 549 value = PropertyManager.getProperty(ob, id, d) 550 return value
551 552 security.declareProtected(ZEN_ZPROPERTIES_VIEW, 'getPropertyType')
553 - def getPropertyType(self, id):
554 """ 555 Overrides methods from PropertyManager to support acquistion. 556 """ 557 ob = self._findParentWithProperty(id) 558 if ob is None: 559 type = None 560 else: 561 type = PropertyManager.getPropertyType(ob, id) 562 return type
563 564 security.declareProtected(ZEN_ZPROPERTIES_VIEW, 'getZ')
565 - def getZ(self, id, default=None):
566 """ 567 Return the value of a zProperty on this object. This method is used to 568 lookup zProperties for a user with a role that doesn't have direct 569 access to an attribute further up the acquisition path. If the 570 requested property is a password, then None is returned. 571 572 @param id: id of zProperty 573 @type id: string 574 @return: Value of zProperty 575 @permission: ZEN_ZPROPERTIES_VIEW 576 577 >>> dmd.Devices.getZ('zSnmpPort') 578 161 579 >>> dmd.Devices.getZ('zSnmpAuthPassword') 580 >>> 581 """ 582 if self.hasProperty(id, useAcquisition=True) \ 583 and not self.zenPropIsPassword(id): 584 returnValue = self.getProperty(id) 585 else: 586 returnValue = default 587 return returnValue
588
589 - def exportZProperties(self, exclusionList=()):
590 """ 591 @param exclusionList: list of zproperties we do not want to export 592 @type exclusionList: collection 593 For this manager will return the following about each zProperty 594 Will return the following about each Zen Property 595 - id - identifier 596 - islocal - if this object has a local definition 597 - value - value for this object 598 - valueAsString - string representation of the property 599 - type - int string lines etc 600 - path - where it is defined 601 - options - acceptable values of this zProperty 602 """ 603 props = [] 604 for zId in self.zenPropertyIds(): 605 if zId in exclusionList: 606 continue 607 prop = dict( 608 id=zId, 609 islocal=self.hasProperty(zId), 610 type=self.getPropertyType(zId), 611 path=self.zenPropertyPath(zId), 612 options=self.zenPropertyOptions(zId), 613 category=getzPropertyCategory(zId), 614 value=None, 615 valueAsString=self.zenPropertyString(zId) 616 ) 617 if not self.zenPropIsPassword(zId): 618 prop['value'] = self.getZ(zId) 619 else: 620 prop['value'] = self.zenPropertyString(zId) 621 props.append(prop) 622 return props
623 624 InitializeClass(ZenPropertyManager) 625
626 -class IdentityTransformer(object):
627 "A do-nothing transformer to use as the default" 628
629 - def transformForGet(self, value):
630 return value
631
632 - def transformForSet(self, value):
633 return value
634
635 -def monkeypatchDescriptors(zprops, transformerFactories):
636 """ 637 monkeypatch ZenPropertyManager adding an instance of the descriptor class 638 for each of the zProperties 639 """ 640 for id, type in zprops: 641 factory = transformerFactories.get(type, IdentityTransformer) 642 descriptor = PropertyDescriptor(id, type, factory()) 643 setattr(ZenPropertyManager, id, descriptor)
644
645 -def setDescriptors(dmd):
646 """ 647 Set the property descriptors on the ZenPropertyManager class. The 648 transformerFactories parameter is a dictionary that maps a property type 649 to a callable factory that produces instances with transformForGet and 650 transformForSet methods. 651 """ 652 zprops = set() 653 654 # copy the core zProps 655 for prop_id, propt_default_value, prop_type in Z_PROPERTIES: 656 zprops.add((prop_id, prop_type)) 657 658 # add zProps from zenpacks 659 from Products.ZenUtils.PkgResources import pkg_resources 660 for zpkg in pkg_resources.iter_entry_points('zenoss.zenpacks'): 661 # fromlist is typically ZenPacks.zenoss 662 fromlist = zpkg.module_name.split('.')[:-1] 663 module = __import__(zpkg.module_name, globals(), locals(), fromlist) 664 if hasattr(module, 'ZenPack'): 665 for prop_id, propt_default_value, prop_type in module.ZenPack.packZProperties: 666 zprops.add((prop_id, prop_type)) 667 668 # add zProps from dmd.Devices to catch any that are undefined elsewhere 669 for prop_id in dmd.Devices.zenPropertyIds(): 670 prop_type = dmd.Devices.getPropertyType(prop_id) 671 if (prop_id, prop_type) not in zprops: 672 log.debug('Property {prop_id} is deprecated. It should be removed from the system.'.format(prop_id=prop_id)) 673 zprops.add((prop_id, prop_type)) 674 675 monkeypatchDescriptors(zprops, dmd.propertyTransformers)
676
677 -def updateDescriptors(type, transformer):
678 """ 679 Update all descriptors with the specified type to use the specified 680 transformer. 681 """ 682 for var in vars(ZenPropertyManager): 683 attr = getattr(ZenPropertyManager, var) 684 if isinstance(attr, PropertyDescriptor) and attr.type == type: 685 attr.transformer = transformer
686