1
2
3
4
5
6
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')
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
40 data = [row for row in data if hasFilter(row, key, value)]
41
42 return data
43
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
54
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
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
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')
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
139
140 if not isinstance(zProperty, dict):
141 properties[zProperty] = value
142 else:
143 properties = zProperty
144 for key, value in properties.iteritems():
145
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
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')
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
240
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
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