Package Products ::
Package Zuul ::
Package routers
|
|
1
2
3
4
5
6
7
8
9
10
11 """
12 Zenoss JSON API
13 """
14
15 from Products.ZenUtils.Ext import DirectRouter, DirectResponse
16 from Products.Zuul.decorators import contextRequire
17 from Products.Zuul.interfaces.tree import ICatalogTool
18 from Products.Zuul.marshalling import Marshaller
19 from Products.ZenModel.DeviceClass import DeviceClass
20 from Products.ZenModel.System import System
21 from Products.ZenMessaging.audit import audit
22 from Products.ZenUtils.Utils import getDisplayType
23 from Products import Zuul
24 import logging
25 log = logging.getLogger(__name__)
29 """
30 A common base class for routers that have a hierarchical tree structure.
31 """
32
33 @contextRequire("Manage DMD", 'contextUid')
34 - def addNode(self, type, contextUid, id, description=None):
35 """
36 Add a node to the existing tree underneath the node specified
37 by the context UID
38
39 @type type: string
40 @param type: Either 'class' or 'organizer'
41 @type contextUid: string
42 @param contextUid: Path to the node that will
43 be the new node's parent (ex. /zport/dmd/Devices)
44 @type id: string
45 @param id: Identifier of the new node, must be unique in the
46 parent context
47 @type description: string
48 @param description: (optional) Describes this new node (default: None)
49 @rtype: dictionary
50 @return: Marshaled form of the created node
51 """
52 result = {}
53 try:
54 facade = self._getFacade()
55 if type.lower() == 'class':
56 uid = facade.addClass(contextUid, id)
57 audit('UI.Class.Add', uid)
58 else:
59 organizer = facade.addOrganizer(contextUid, id, description)
60 uid = organizer.uid
61 audit(['UI', getDisplayType(organizer), 'Add'], organizer)
62
63 treeNode = facade.getTree(uid)
64 result['nodeConfig'] = Zuul.marshal(treeNode)
65 result['success'] = True
66 except Exception, e:
67 log.exception(e)
68 result['msg'] = str(e)
69 result['success'] = False
70 return result
71
72 @contextRequire("Manage DMD", 'uid')
74 """
75 Deletes a node from the tree.
76
77 B{NOTE}: You can not delete a root node of a tree
78
79 @type uid: string
80 @param uid: Unique identifier of the node we wish to delete
81 @rtype: DirectResponse
82 @return: B{Properties}:
83 - msg: (string) Status message
84 """
85
86 if not self._canDeleteUid(uid):
87 raise Exception('You cannot delete the root node')
88 facade = self._getFacade()
89 node = facade._getObject(uid)
90
91
92
93
94 if isinstance(node, DeviceClass):
95 childBrains = ICatalogTool(node).search((
96 'Products.ZenModel.DeviceClass.DeviceClass',
97 'Products.ZenModel.Device.Device',
98 ))
99 for child in childBrains:
100 audit(['UI', getDisplayType(child), 'Delete'], child.getPath())
101 elif isinstance(node, System):
102
103 for dev in facade.getDevices(uid):
104 newSystems = facade._removeOrganizer(node, dev._object.getSystemNames())
105 dev._object.setSystems(newSystems)
106 audit(['UI', getDisplayType(node), 'Delete'], node)
107 else:
108 audit(['UI', getDisplayType(node), 'Delete'], node)
109
110 facade.deleteNode(uid)
111 msg = "Deleted node '%s'" % uid
112 return DirectResponse.succeed(msg=msg)
113
115 """
116 Move the organizer uid to be underneath the organizer
117 specified by the targetUid.
118
119 @type targetUid: string
120 @param targetUid: New parent of the organizer
121 @type organizerUid: string
122 @param organizerUid: The organizer to move
123 @rtype: DirectResponse
124 @return: B{Properties}:
125 - data: (dictionary) Moved organizer
126 """
127 facade = self._getFacade()
128 display_type = getDisplayType(facade._getObject(organizerUid))
129 audit(['UI', display_type, 'Move'], organizerUid, to=targetUid)
130 data = facade.moveOrganizer(targetUid, organizerUid)
131 return DirectResponse.succeed(data=Zuul.marshal(data))
132
134 """
135 Abstract method for child classes to use to get their facade
136 """
137 raise NotImplementedError("You must implement the _getFacade method")
138
140 """
141 Server side method for asynchronous tree calls. Retrieves
142 the immediate children of the node specified by "id"
143
144 NOTE: our convention on the UI side is if we are asking
145 for the root node then return the root and its children
146 otherwise just return the children
147
148 @type id: string
149 @param id: The uid of the node we are getting the children for
150 @rtype: [dictionary]
151 @return: Object representing the immediate children
152 """
153 showEventSeverityIcons = self.context.dmd.UserInterfaceSettings.getInterfaceSettings().get('showEventSeverityIcons')
154 facade = self._getFacade()
155 currentNode = facade.getTree(id)
156
157 keys = ('id', 'path', 'uid', 'iconCls', 'text', 'hidden', 'leaf') + additionalKeys
158
159
160 childNodes = list(currentNode.children)
161 if showEventSeverityIcons:
162 uuids = [n.uuid for n in childNodes if n.uuid]
163 zep = Zuul.getFacade('zep', self.context.dmd)
164
165 if uuids:
166 severities = zep.getWorstSeverity(uuids)
167 for child in childNodes:
168 if child.uuid:
169 child.setSeverity(zep.getSeverityName(severities.get(child.uuid, 0)).lower())
170
171 children = []
172
173 for child in childNodes:
174 childData = Marshaller(child).marshal(keys)
175
176
177
178
179
180 organizer = child._get_object()
181
182 hasChildren = any((o['meta_type'] for o in organizer._objects if o['meta_type'] == organizer.meta_type))
183
184 if "report" not in organizer.meta_type.lower() and not hasChildren:
185 childData['children'] = []
186 children.append(childData)
187 children.sort(key=lambda e: (e['leaf'], e['uid'].lower()))
188 obj = currentNode._object._unrestrictedGetObject()
189
190
191 primaryId = obj.getDmdRoot(obj.dmdRootName).getPrimaryId()
192 if id == primaryId:
193 root = Marshaller(currentNode).marshal(keys)
194 root['children'] = children
195 return [root]
196 return children
197
199 """
200 @rtype: DirectResponse
201 @return:
202 - Properties:
203 - B{exists} - Returns true if we can find the object specified by the uid
204
205 """
206 from Products.Zuul.facades import ObjectNotFoundException
207 facade = self._getFacade()
208 try:
209 facade._getObject(uid)
210 exists = True
211 except ObjectNotFoundException:
212 exists = False
213 return DirectResponse(success=True, exists=exists)
214
216 """
217 We can not delete top level UID's. For example:
218 - '/zport/dmd/Processes' this will return False (we can NOT delete)
219 - '/zport/dmd/Processes/Child' will return True
220 (we can delete this)
221 """
222
223 levels = len(uid.split('/'))
224 return levels > 4
225