1
2
3
4
5
6
7
8
9
10
11
12
13
14 from Globals import InitializeClass
15 from Acquisition import aq_parent
16 from AccessControl import ClassSecurityInfo, getSecurityManager
17
18 import simplejson
19
20 from Products.ZenRelations.RelSchema import *
21 from Products.ZenUtils.Utils import travAndColl
22 from Products.ZenUtils.Exceptions import ZenPathError, ZentinelException
23
24 from EventView import EventView
25 from ZenModelRM import ZenModelRM
26 from ZenPackable import ZenPackable
27 from ZenossSecurity import *
28
30 """
31 The base for all hierarchical organization classes. It allows Organizers
32 to be addressed and created with file system like paths like
33 /Devices/Servers. Organizers have a containment relation called children.
34 Subclasses must define the attribute:
35
36 dmdRootName - root in the dmd database for this organizer
37 """
38
39 _properties = (
40 {'id':'description', 'type':'string', 'mode':'w'},
41 )
42
43 _relations = ZenModelRM._relations
44
45 security = ClassSecurityInfo()
46 security.declareObjectProtected(ZEN_VIEW)
47
48 - def __init__(self, id, description = ''):
49 """
50 @param id: Name of this organizer
51 @type id: string
52 @param description: A decription of this organizer
53 @type description: string
54 @rtype: Organizer
55 """
56 ZenModelRM.__init__(self, id)
57 self.description = description
58
60 """
61 Override urlLink to return a link with the full path of the organizer.
62
63 >>> dmd.Devices.Server.urlLink()
64 '<a href="/zport/dmd/Devices/Server">/Server</a>'
65 """
66 return ZenModelRM.urlLink(self, self.getOrganizerName(),
67 url=url, attrs=attrs)
68
69
71 """
72 Returns a list of all organizer names
73 under the same root excluding ourselves
74
75 @return: A list of organizers excluding our self.
76 @rtype: list
77 @todo: We should be using either deviceMoveTargets or childMoveTargets
78
79 >>> dmd.Events.getOrganizerName() in dmd.Events.childMoveTargets()
80 False
81 """
82 myname = self.getOrganizerName()
83 return filter(lambda x: x != myname,
84 self.getDmdRoot(self.dmdRootName).getOrganizerNames())
85
87 """
88 Returns a list of all organizer names under the same root excluding
89 ourselves (as a json dump)
90
91 @return: Organizer names under a the same organizer root as a json dump
92 @rtype: list
93 """
94 return simplejson.dumps(self.childMoveTargets());
95
97 """
98 Returns an organizer under the same root.
99
100 @param moveTargetName: Name of the organizer
101 @type moveTargetName: string
102 @rtype: Organizer
103
104 >>> dmd.Devices.getChildMoveTarget('Server')
105 <DeviceClass at /zport/dmd/Devices/Server>
106 """
107 return self.getDmdRoot(self.dmdRootName).getOrganizer(moveTargetName)
108
109
110 security.declareProtected(ZEN_COMMON, "children")
112 """
113 Returns the immediate children of an organizer
114
115 @param sort: If True, sorts the returned children.
116 @type sort: boolean
117 @param checkPerm: If True, checks if the user has the permission
118 to view each child.
119 @type checkPerm: boolean
120 @param spec: If set, returns children of the specified meta_type.
121 @type spec: string
122 @return: A list of children of the organizer
123 @rtype: list
124 @permission: ZEN_COMMON
125
126 >>> dmd.Devices.Printer.children()
127 [<DeviceClass at /zport/dmd/Devices/Printer/Laser>,
128 <DeviceClass at /zport/dmd/Devices/Printer/InkJet>]
129 """
130 if spec is None:
131 spec = self.meta_type
132 kids = self.objectValues(spec=spec)
133 if checkPerm:
134 kids = [ kid for kid in kids if self.checkRemotePerm(ZEN_VIEW, kid)]
135 if sort: kids.sort(lambda x,y: cmp(x.primarySortKey(),
136 y.primarySortKey()))
137 return kids
138
139
141 """
142 Returns the ids of the immediate children of an organizer
143
144 @param spec: If set, returns children of the specified meta_type.
145 @type spec: string
146 @return: Ids of children within our organizer
147 @rtype: list
148
149 >>> dmd.Devices.childIds()
150 ['Discovered', 'Network', 'Server', 'Printer', 'Power', 'KVM', 'Ping']
151 """
152 if spec is None:
153 spec = self.meta_type
154
155 return self.objectIds(spec=spec)
156
157
158 security.declareProtected(ZEN_COMMON, "countChildren")
160 """
161 Returns the number of all the children underneath an organizer
162
163 @param spec: If set, returns children of the specified meta_type.
164 @type spec: string
165 @return: A count of all our contained children.
166 @rtype: integer
167 @permission: ZEN_COMMON
168
169 >>> dmd.Devices.countChildren()
170 24
171 """
172 if spec is None:
173 spec = self.meta_type
174
175 count = len(self.objectIds(spec=spec))
176 for child in self.children(spec=spec):
177 count += child.countChildren(spec=spec)
178 return count
179
180
181 security.declareProtected(ZEN_ADD, 'manage_addOrganizer')
183 """
184 Adds a new organizer under this organizer. if given a fully qualified
185 path it will create an organizer at that path
186
187 @param newPath: Path of the organizer to be created
188 @type newPath: string
189 @raise: ZentinelException
190 @permission: ZEN_ADD
191
192 >>> dmd.Devices.manage_addOrganizer('/Devices/DocTest')
193 """
194 if not newPath: return self.callZenScreen(REQUEST)
195 try:
196 if newPath.startswith("/"):
197 self.createOrganizer(newPath)
198 else:
199 org = self.__class__(newPath)
200 self._setObject(org.id, org)
201 except ZentinelException, e:
202 if REQUEST:
203 REQUEST['message'] = 'Error: %s' % e
204 return self.callZenScreen(REQUEST)
205 if REQUEST:
206 REQUEST['message'] = "%s %s added" % (self.__class__.__name__,
207 newPath)
208 return self.callZenScreen(REQUEST)
209
210
211 security.declareProtected(ZEN_DELETE, 'manage_deleteOrganizer')
213 """
214 Deletes an organizer underneath this organizer
215
216 @param orgname: Name of the organizer to delete
217 @type orgname: string
218 @raise: KeyError
219 @permission: ZEN_DELETE
220
221 >>> dmd.Devices.manage_deleteOrganizer('/Devices/Server/Linux')
222 """
223 if orgname.startswith("/"):
224 try:
225 orgroot = self.getDmdRoot(self.dmdRootName)
226 organizer = orgroot.getOrganizer(orgname)
227 parent = aq_parent(organizer)
228 parent._delObject(organizer.getId())
229 except KeyError:
230 pass
231 else:
232 self._delObject(orgname)
233 if REQUEST:
234 REQUEST['message'] = "%s %s deleted" % (self.__class__.__name__,
235 orgname)
236 return self.callZenScreen(REQUEST)
237
238
239 security.declareProtected(ZEN_DELETE, 'manage_deleteOrganizers')
241 """
242 Delete a list of Organizers from the database using their ids.
243
244 @param organizerPaths: Names of organizer to be deleted
245 @type organizerPaths: list
246 @permission: ZEN_DELETE
247
248 >>> dmd.Devices.manage_deleteOrganizers(['/Devices/Server/Linux',
249 ... '/Devices/Server/Windows'])
250 """
251 if not organizerPaths:
252 REQUEST['message'] = "Organizer not specified, not deleted"
253 return self.callZenScreen(REQUEST)
254 for organizerName in organizerPaths:
255 self.manage_deleteOrganizer(organizerName)
256 if REQUEST:
257 plural = ''
258 if len(organizerPaths) > 1: plural = 's'
259 REQUEST['message'] = "%s%s %s deleted" % (self.__class__.__name__,
260 plural, ', '.join(organizerPaths))
261 return self.callZenScreen(REQUEST)
262
263
265 """
266 DEPRECATED - see childMoveTargets
267 Return list of all organizers excluding our self.
268
269 @return: A sorted list of organizers excluding our self.
270 @rtype: list
271 @todo: We should be using either deviceMoveTargets or childMoveTargets
272 """
273 targets = filter(lambda x: x != self.getOrganizerName(),
274 self.getDmdRoot(self.dmdRootName).getOrganizerNames())
275 targets.sort(lambda x,y: cmp(x.lower(), y.lower()))
276 return targets
277
278
280 """
281 Move organizers under this organizer to another organizer
282
283 @param moveTarget: Name of the destination organizer
284 @type moveTarget: string
285 @param organizerPaths: Paths of organizers to be moved
286 @type organizerPaths: list
287
288 >>> dmd.Events.Status.moveOrganizer('/Events/Ignore',
289 ... ['Ping', 'Snmp'])
290 """
291 if not moveTarget or not organizerPaths: return self()
292 target = self.getDmdRoot(self.dmdRootName).getOrganizer(moveTarget)
293 movedStuff = False
294 for organizerName in organizerPaths:
295 if moveTarget.find(organizerName) > -1: continue
296 obj = self._getOb(organizerName)
297 obj._operation = 1
298 self._delObject(organizerName)
299 target._setObject(organizerName, obj)
300 movedStuff = True
301 if REQUEST:
302 if movedStuff:
303 plural = ''
304 if len(organizerPaths) > 1: plural = 's'
305 REQUEST['message'] = "%s%s %s moved to %s" % (self.__class__.__name__,
306 plural, ', '.join(organizerPaths), moveTarget)
307 else: REQUEST['message'] = "No %s were moved" % self.__class__.__name__
308 return target.callZenScreen(REQUEST)
309
310
312 """
313 Creates an organizer with a specified path.
314 Use manage_addOrganizer instead
315
316 @param path: Path of the organizer to create
317 @type path: string
318 @return: Organizer created with the specified path
319 @rtype: Organizer
320 """
321 return self.createHierarchyObj(self.getDmdRoot(self.dmdRootName),
322 path,self.__class__)
323
324
326 """
327 Get an organizer by path under the same root
328
329 @param path: Path of the organizer to retrieve
330 @type path: string
331 @return: Organizer with the specified path
332 @rtype: Organizer
333
334 >>> dmd.Events.Status.getOrganizer('/Status/Snmp')
335 <EventClass at /zport/dmd/Events/Status/Snmp>
336 >>> dmd.Events.Status.getOrganizer('Status/Snmp')
337 <EventClass at /zport/dmd/Events/Status/Snmp>
338 >>> dmd.Events.Status.getOrganizer('/Events/Status/Snmp')
339 <EventClass at /zport/dmd/Events/Status/Snmp>
340 """
341 if path.startswith("/"): path = path[1:]
342 return self.getDmdRoot(self.dmdRootName).getObjByPath(path)
343
344
345 security.declareProtected(ZEN_COMMON, "getOrganizerName")
347 """
348 Return the DMD path of an Organizer without its dmdSubRel names.
349
350 @return: Name of this organizer
351 @rtype: string
352 @permission: ZEN_COMMON
353
354 >>> dmd.Events.Status.Snmp.getOrganizerName()
355 '/Status/Snmp'
356 """
357 return self.getPrimaryDmdId(self.dmdRootName)
358 getDmdKey = getOrganizerName
359
360
361 security.declareProtected(ZEN_COMMON, "getOrganizerNames")
363 """
364 Returns a list of all organizer names under this organizer
365
366 @param addblank: If True, add a blank item in the list.
367 @type addblank: boolean
368 @return: The DMD paths of all Organizers below this instance.
369 @rtype: list
370 @permission: ZEN_COMMON
371
372 >>> dmd.Events.Security.getOrganizerNames()
373 ['/Security', '/Security/Auth', '/Security/Conn',
374 '/Security/Conn/Close', '/Security/Conn/Open', '/Security/Login',
375 '/Security/Login/BadPass', '/Security/Login/Fail', '/Security/Sudo',
376 '/Security/Virus']
377 """
378 groupNames = []
379 user = getSecurityManager().getUser()
380 if user.has_permission(ZEN_VIEW, self):
381 groupNames.append(self.getOrganizerName())
382 for subgroup in self.children(checkPerm=False):
383 groupNames.extend(subgroup.getOrganizerNames())
384 if self.id == self.dmdRootName:
385 if addblank: groupNames.append("")
386 groupNames.sort(lambda x,y: cmp(x.lower(), y.lower()))
387 return groupNames
388
389
391 """
392 Returns a catalog instance for this organizer.
393
394 @return: The catalog instance for this Organizer.
395 @rtype: ZCatalog
396 @note: Catalog is found using the attribute default_catalog.
397 """
398 catalog = None
399 if hasattr(self, self.default_catalog):
400 catalog = getattr(self, self.default_catalog)
401 return catalog
402
403
404 security.declareProtected(ZEN_COMMON, "getSubOrganizers")
406 """
407 Returns all the organizers under this organizer
408
409 @return: Organizers below this instance
410 @rtype: list
411 @permission: ZEN_COMMON
412
413 >>> dmd.Events.Security.getSubOrganizers()
414 [<EventClass at /zport/dmd/Events/Security/Login>,
415 <EventClass at /zport/dmd/Events/Security/Sudo>,
416 <EventClass at /zport/dmd/Events/Security/Conn>,
417 <EventClass at /zport/dmd/Events/Security/Virus>,
418 <EventClass at /zport/dmd/Events/Security/Auth>,
419 <EventClass at /zport/dmd/Events/Security/Login/BadPass>,
420 <EventClass at /zport/dmd/Events/Security/Login/Fail>,
421 <EventClass at /zport/dmd/Events/Security/Conn/Open>,
422 <EventClass at /zport/dmd/Events/Security/Conn/Close>]
423 """
424 orgs = self.children()
425 for child in self.children():
426 orgs.extend(child.getSubOrganizers())
427 return orgs
428
429 security.declareProtected(ZEN_COMMON, "getSubInstances")
431 """
432 Returns the object ids of all the instances of a specific relation
433 under this organizer
434
435 @param rel: The name of the relation to traverse
436 @type rel: string
437 @return: The object ids of instances under an relation of this org
438 @rtype: list
439 @raise: AttributeError
440 @permission: ZEN_COMMON
441
442 >>> dmd.Events.Security.Login.getSubInstanceIds('instances')
443 ['MSExchangeIS Mailbox Store_1009', 'MSExchangeIS Mailbox Store_1011',
444 'defaultmapping', 'dropbear', 'sshd', 'MSFTPSVC_100', 'W3SVC_100',
445 'dropbear', 'remote(pam_unix)']
446 """
447 relobj = getattr(self, rel, None)
448 if not relobj:
449 raise AttributeError, "%s not found on %s" % (rel, self.id)
450 objs = relobj.objectIds()
451 for suborg in self.children():
452 objs.extend(suborg.getSubInstanceIds(rel))
453 return objs
454
455 security.declareProtected(ZEN_COMMON, "getSubInstances")
457 """
458 Returns the object isntances of a specific relation
459 under this organizer
460
461 @param rel: The name of the relation to traverse
462 @type rel: string
463 @return: The object instances under an relation of this org
464 @rtype: list
465 @raise: AttributeError
466 @permission: ZEN_COMMON
467
468 >>> dmd.Events.Security.Login.getSubInstances('instances')
469 [<EventClassInst at /zport/dmd/Events/Security/Login/instances/MSExchangeIS Mailbox Store_1009>,
470 <EventClassInst at /zport/dmd/Events/Security/Login/instances/MSExchangeIS Mailbox Store_1011>,
471 <EventClassInst at /zport/dmd/Events/Security/Login/instances/defaultmapping>,
472 <EventClassInst at /zport/dmd/Events/Security/Login/BadPass/instances/dropbear>,
473 <EventClassInst at /zport/dmd/Events/Security/Login/BadPass/instances/sshd>,
474 <EventClassInst at /zport/dmd/Events/Security/Login/Fail/instances/MSFTPSVC_100>,
475 <EventClassInst at /zport/dmd/Events/Security/Login/Fail/instances/W3SVC_100>,
476 <EventClassInst at /zport/dmd/Events/Security/Login/Fail/instances/dropbear>,
477 <EventClassInst at /zport/dmd/Events/Security/Login/Fail/instances/remote(pam_unix)>]
478 """
479 relobj = getattr(self, rel, None)
480 if not relobj:
481 raise AttributeError, "%s not found on %s" % (rel, self.id)
482 objs = relobj()
483 if not objs: objs = []
484 for suborg in self.children():
485 objs.extend(suborg.getSubInstances(rel))
486 return objs
487
488 security.declareProtected(ZEN_COMMON, "getSubInstancesGen")
490 """
491 Returns the object isntances of a specific relation
492 under this organizer
493
494 @param rel: The name of the relation to traverse
495 @type rel: string
496 @return: The object ids of instances under an relation of this org
497 @rtype: generator
498 @raise: AttributeError
499 @permission: ZEN_COMMON
500 """
501 relobj = getattr(self, rel, None)
502 if not relobj:
503 raise AttributeError, "%s not found on %s" % (rel, self.id)
504 for obj in relobj.objectValuesGen():
505 yield obj
506 for suborg in self.children():
507 for obj in suborg.getSubInstancesGen(rel):
508 yield obj
509
511 """
512 Calls exportXml on the children of this organizer
513
514 @param ofile: The file to output
515 @type ofile: File
516 @param ignorerels: Relations to ignore
517 @type ignorerels: list
518 """
519 map(lambda o: o.exportXml(ofile, ignorerels), self.children())
520
521
522 InitializeClass(Organizer)
523