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

Source Code for Package Products.Zuul.routers

  1  ############################################################################## 
  2  # 
  3  # Copyright (C) Zenoss, Inc. 2009, 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  """ 
 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__) 
26 27 28 -class TreeRouter(DirectRouter):
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')
73 - def deleteNode(self, 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 # make sure we are not deleting a root node 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 # Audit first so it can display details like "name" while they exist. 92 # Trac #29148: When we delete a DeviceClass we also delete its devices 93 # and child device classes and their devices, so audit them all. 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 # update devices systems if the parent system is being removed 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
114 - def moveOrganizer(self, targetUid, organizerUid):
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
133 - def _getFacade(self):
134 """ 135 Abstract method for child classes to use to get their facade 136 """ 137 raise NotImplementedError("You must implement the _getFacade method")
138
139 - def asyncGetTree(self, id=None, additionalKeys=()):
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 # we want every tree property except the "children" one 157 keys = ('id', 'path', 'uid', 'iconCls', 'text', 'hidden', 'leaf') + additionalKeys 158 159 # load the severities in one request 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 # explicitly marshall the children 173 for child in childNodes: 174 childData = Marshaller(child).marshal(keys) 175 # set children so that there is not an expanding 176 # icon next to this child 177 # see if there are any subtypes so we can show or not show the 178 # expanding icon without serializing all the children. 179 # Note that this is a performance optimization see ZEN-15857 180 organizer = child._get_object() 181 # this looks at the children's type without waking them up 182 hasChildren = any((o['meta_type'] for o in organizer._objects if o['meta_type'] == organizer.meta_type)) 183 # reports have a different meta_type for the child organizers 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 # check to see if we are asking for the root 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
198 - def objectExists(self, uid):
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
215 - def _canDeleteUid(self, uid):
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 # check the number of levels deep it is 223 levels = len(uid.split('/')) 224 return levels > 4
225