Package Products :: Package Zuul :: Package routers :: Module properties
[hide private]
[frames] | no frames]

Source Code for Module Products.Zuul.routers.properties

  1  ############################################################################## 
  2  # 
  3  # Copyright (C) Zenoss, Inc. 2012, 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  from DateTime import DateTime 
 11   
 12  from Products import Zuul 
 13  from Products.ZenMessaging.audit import audit 
 14  from Products.ZenModel.ZenossSecurity import ZEN_ZPROPERTIES_EDIT 
 15  from Products.ZenUtils.Ext import DirectResponse 
 16  from Products.ZenUtils.Ext import DirectRouter 
 17  from Products.ZenUtils.jsonutils import unjson 
 18  from Products.Zuul.decorators import contextRequire, serviceConnectionError 
 19   
 20  _exclusions = ('zCollectorPlugins', 'zCredentialsZProperties') 
21 22 23 -def _filterData(params, data):
24 """ 25 @param params: params passed to the caller and used here for filtering 26 @param data: data to be filtered and returned 27 """ 28 if params: 29 if isinstance(params, basestring): 30 filters = unjson(params) 31 else: 32 filters = params 33 34 def hasFilter(row, key, value): 35 if row.get(key) is not None: 36 return value.lower() in str(row.get(key)).lower()
37 38 for key, value in filters.iteritems(): 39 # assume AND for sorting 40 data = [row for row in data if hasFilter(row, key, value)] 41 42 return data 43
44 45 -def _sortData(sort, data, dir):
46 """ 47 @param data: data to be sorted and returned 48 """ 49 reverse = (dir != "ASC") 50 return sorted(data, key=lambda row: row.get(sort, None), reverse=reverse)
51
52 53 -class PropertiesRouter(DirectRouter):
54
55 - def _getFacade(self):
56 return Zuul.getFacade('properties', self.context)
57 58 @serviceConnectionError
59 - def getZenProperties( 60 self, uid, start=0, params="{}", limit=None, sort=None, 61 page=None, dir='ASC'):
62 """ 63 Returns the definition and values of all 64 the zen properties for this context 65 @type uid: string 66 @param uid: unique identifier of an object 67 """ 68 facade = self._getFacade() 69 data = facade.getZenProperties(uid, exclusionList=_exclusions) 70 data = _filterData(params, data) 71 if sort: 72 data = _sortData(sort, data, dir) 73 return DirectResponse(data=Zuul.marshal(data), totalCount=len(data))
74 75 @serviceConnectionError
76 - def getZenProperty(self, uid, zProperty):
77 """ 78 Returns information about a zproperty for a given context, 79 including its value. 80 81 @rtype: Dictionary 82 @return: B{Properties}: 83 - path: (string) where the property is defined 84 - type: (string) type of zproperty it is 85 - options: (Array) available options for the zproperty 86 - value (Array) value of the zproperty 87 - valueAsString (string) 88 """ 89 facade = self._getFacade() 90 data = facade.getZenProperty(uid, zProperty) 91 return DirectResponse.succeed(data=Zuul.marshal(data))
92 93 @serviceConnectionError
94 - def getCustomProperties( 95 self, uid, start=0, params="{}", limit=None, sort=None, 96 page=None, dir='ASC'):
97 """ 98 Returns the definition and values of all 99 the zen properties for this context 100 @type uid: string 101 @param uid: unique identifier of an object 102 """ 103 facade = self._getFacade() 104 data = facade.getCustomProperties(uid) 105 data = _filterData(params, data) 106 if sort: 107 data = _sortData(sort, data, dir) 108 return DirectResponse(data=Zuul.marshal(data), totalCount=len(data))
109
110 - def addCustomProperty(self, id, value, label, uid, type):
111 """ 112 Adds a new property to the / of the tree 113 """ 114 facade = self._getFacade() 115 facade.addCustomProperty(id, value, label, uid, type) 116 return DirectResponse.succeed( 117 msg="Property %s added successfully." % (id,) 118 )
119 120 @serviceConnectionError 121 @contextRequire(ZEN_ZPROPERTIES_EDIT, 'uid')
122 - def setZenProperty(self, uid, zProperty, value=None):
123 """ 124 Sets the zProperty value. 125 126 @type uid: string 127 @param uid: unique identifier of an object 128 @type zProperty: string or dictionary 129 @param zProperty: either a string that represents which zproperty 130 we are changing or key value pair dictionary that is the list 131 of zproperties we wish to change. 132 @type value: anything 133 @param value: if we are modifying a single zproperty then it is the 134 value, it is not used if a dictionary is passed in for zProperty 135 """ 136 facade = self._getFacade() 137 properties = {} 138 # Allow for zProperty to be a map of zproperties that need to 139 # be saved in case there is more than one 140 if not isinstance(zProperty, dict): 141 properties[zProperty] = value 142 else: 143 properties = zProperty 144 for key, value in properties.iteritems(): 145 # Get old value for auditing 146 oldProperty = facade.getZenProperty(uid, key) 147 oldValue = oldProperty['value'] if 'value' in oldProperty else '' 148 149 facade.setZenProperty(uid, key, value) 150 data = facade.getZenProperty(uid, key) 151 152 # stringify falsey values 153 value = str(value) if not value else value 154 oldValue = str(oldValue) if not oldValue else oldValue 155 156 obj = facade._getObject(uid) 157 maskFields = 'value' if obj.zenPropIsPassword(key) else None 158 audit('UI.zProperty.Edit', key, maskFields_=maskFields, 159 data_={obj.meta_type: uid, 'value': value}, 160 oldData_={'value': oldValue}) 161 162 return DirectResponse(data=Zuul.marshal(data))
163 164 @serviceConnectionError 165 @contextRequire(ZEN_ZPROPERTIES_EDIT, 'uid')
166 - def deleteZenProperty(self, uid, zProperty):
167 """ 168 Removes the local instance of the each property in properties. Note 169 that the property will only be deleted if a hasProperty is true 170 * also used on custom properties or cProperties 171 @type uid: String 172 @param uid: unique identifier of an object 173 @type properties: String 174 @param properties: zenproperty identifier 175 """ 176 facade = self._getFacade() 177 data = facade.deleteZenProperty(uid, zProperty) 178 obj = facade._getObject(uid) 179 audit('UI.zProperty.Delete', zProperty, data_={obj.meta_type: uid}) 180 return DirectResponse(data=Zuul.marshal(data))
181 182 @serviceConnectionError
183 - def query(self, uid, constraints=None, params=None, **kw):
184 """Returns a list of properties matching the given constraints 185 and parameters. 186 187 There are two constraints that can be specified: idPrefix and type 188 189 idPrefix: Should be 'c' to return only cProperties or 'z' to 190 return only zProperties. If not specified, then both cProperties 191 and zProperties are returned. 192 193 type: Is a string naming the property type that returned properties 194 should have. If multiple types are desired, this value can be 195 a list of strings. 196 197 @param uid {str} From properties from this object path 198 @param params {dict} Return properties matching the given fields. 199 @param fields {list} List of fields to return for each property. 200 @param kw {dict} The 'limit', 'sort', 'page', and 'dir' parameters 201 are extracted from here. 202 """ 203 requirements = [lambda x: x["id"] not in _exclusions] 204 205 idPrefix = constraints.pop("idPrefix", None) 206 if idPrefix: 207 idPrefix = idPrefix.lower() 208 if idPrefix not in ('c', 'z'): 209 idPrefix = None 210 else: 211 requirements.append(lambda x: x["id"].startswith(idPrefix)) 212 if idPrefix is None: 213 requirements.append(lambda x: x["id"].startswith(('c', 'z'))) 214 215 propTypes = constraints.pop("type", None) 216 if propTypes: 217 if not isinstance(propTypes, list): 218 propTypes = [propTypes] 219 requirements.append(lambda x: x["type"] in propTypes) 220 221 facade = self._getFacade() 222 data = facade.query(uid, constraints=requirements) 223 224 if params is not None: 225 data = _filterData(params, data) 226 227 totalCount = len(data) 228 229 sort = kw.pop("sort", None) 230 if sort: 231 direction = kw.pop("dir", "ASC") 232 data = _sortData(sort, data, direction) 233 234 limit = kw.pop("limit", None) 235 if limit: 236 start = kw.pop("start", 0) 237 data = data[start:(start + limit)] 238 239 # transform some data since there isn't any IInfo support 240 # for properties (properties don't have a type other than dict). 241 for prop in data: 242 if isinstance(prop.get("value"), DateTime): 243 prop["value"] = prop.get("value").timeTime() 244 245 return DirectResponse(totalCount=totalCount, data=Zuul.marshal(data))
246 247 @serviceConnectionError 248 @contextRequire(ZEN_ZPROPERTIES_EDIT, 'uid')
249 - def add(self, uid, id, value, label, description, 250 type, select_variable=None):
251 """Adds a new property to uid. 252 """ 253 facade = self._getFacade() 254 if type == "selection" and select_variable: 255 facade.addCustomProperty( 256 id, select_variable, label, uid, type, 257 description=description 258 ) 259 facade.setZenProperty(uid, id, value) 260 else: 261 facade.addCustomProperty( 262 id, value, label, uid, type, 263 description=description 264 ) 265 return DirectResponse.succeed( 266 msg="Property %s successfully added." % (id,) 267 )
268 269 @serviceConnectionError 270 @contextRequire(ZEN_ZPROPERTIES_EDIT, 'uid')
271 - def update(self, uid, id, value, select_variable=None):
272 """Updates an existing property. 273 """ 274 facade = self._getFacade() 275 if select_variable: 276 facade.updateCustomProperty( 277 uid, id, select_variable=select_variable 278 ) 279 280 # Transform date value from milliseconds into DateTime object. 281 prop = facade.getZenProperty(uid, id) 282 if prop.get("type") == "date": 283 userfacade = Zuul.getFacade('properties', self.context) 284 usersettings = userfacade._dmd.ZenUsers.getUserSettings() 285 tz = usersettings.timezone 286 dt = DateTime(value, tz) if tz else DateTime(value) 287 value = dt.ISO8601() 288 289 facade.setZenProperty(uid, id, value) 290 return DirectResponse.succeed( 291 msg="Property %s successfully updated." % (id,) 292 )
293 294 @serviceConnectionError 295 @contextRequire(ZEN_ZPROPERTIES_EDIT, 'uid')
296 - def remove(self, uid, id=None, properties=None):
297 """Removes the local instance of the each property in properties. 298 Note that the property will only be deleted if a hasProperty is true 299 300 @param uid {str} Path to the object owning the properties. 301 @param id {str} The ID of the property to delete. 302 @param properties {list[str]} List of property IDs to delete. 303 304 Note that specifying both 'id' and 'properties' is valid. 305 Duplicate property IDs skipped. 306 """ 307 facade = self._getFacade() 308 names = set() 309 if id is not None: 310 names.add(id) 311 if properties is not None: 312 if not isinstance(properties, (list, tuple)): 313 properties = [properties] 314 names.update(properties) 315 for name in names: 316 facade.deleteZenProperty(uid, name) 317 obj = facade._getObject(uid) 318 audit('UI.zProperty.Delete', name, data_={obj.meta_type: uid}) 319 if len(names) == 1: 320 return DirectResponse.succeed( 321 msg="Property %s successfully deleted." % names.pop() 322 ) 323 return DirectResponse.succeed( 324 msg="Successfully deleted %s properties." % len(names) 325 )
326