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 require 
 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.ZenMessaging.audit import audit 
 21  from Products.ZenUtils.Utils import getDisplayType 
 22  from Products import Zuul 
 23  import logging 
 24  log = logging.getLogger(__name__) 
25 26 27 -class TreeRouter(DirectRouter):
28 """ 29 A common base class for routers that have a hierarchical tree structure. 30 """ 31 32 @require('Manage DMD')
33 - def addNode(self, type, contextUid, id, description=None):
34 """ 35 Add a node to the existing tree underneath the node specified 36 by the context UID 37 38 @type type: string 39 @param type: Either 'class' or 'organizer' 40 @type contextUid: string 41 @param contextUid: Path to the node that will 42 be the new node's parent (ex. /zport/dmd/Devices) 43 @type id: string 44 @param id: Identifier of the new node, must be unique in the 45 parent context 46 @type description: string 47 @param description: (optional) Describes this new node (default: None) 48 @rtype: dictionary 49 @return: Marshaled form of the created node 50 """ 51 result = {} 52 try: 53 facade = self._getFacade() 54 if type.lower() == 'class': 55 uid = facade.addClass(contextUid, id) 56 audit('UI.Class.Add', uid) 57 else: 58 organizer = facade.addOrganizer(contextUid, id, description) 59 uid = organizer.uid 60 audit(['UI', getDisplayType(organizer), 'Add'], organizer) 61 62 treeNode = facade.getTree(uid) 63 result['nodeConfig'] = Zuul.marshal(treeNode) 64 result['success'] = True 65 except Exception, e: 66 log.exception(e) 67 result['msg'] = str(e) 68 result['success'] = False 69 return result
70 71 @require('Manage DMD')
72 - def deleteNode(self, uid):
73 """ 74 Deletes a node from the tree. 75 76 B{NOTE}: You can not delete a root node of a tree 77 78 @type uid: string 79 @param uid: Unique identifier of the node we wish to delete 80 @rtype: DirectResponse 81 @return: B{Properties}: 82 - msg: (string) Status message 83 """ 84 # make sure we are not deleting a root node 85 if not self._canDeleteUid(uid): 86 raise Exception('You cannot delete the root node') 87 facade = self._getFacade() 88 node = facade._getObject(uid) 89 90 # Audit first so it can display details like "name" while they exist. 91 # Trac #29148: When we delete a DeviceClass we also delete its devices 92 # and child device classes and their devices, so audit them all. 93 if isinstance(node, DeviceClass): 94 childBrains = ICatalogTool(node).search(( 95 'Products.ZenModel.DeviceClass.DeviceClass', 96 'Products.ZenModel.Device.Device', 97 )) 98 for child in childBrains: 99 audit(['UI', getDisplayType(child), 'Delete'], child.getPath()) 100 else: 101 audit(['UI', getDisplayType(node), 'Delete'], node) 102 103 facade.deleteNode(uid) 104 msg = "Deleted node '%s'" % uid 105 return DirectResponse.succeed(msg=msg)
106
107 - def moveOrganizer(self, targetUid, organizerUid):
108 """ 109 Move the organizer uid to be underneath the organizer 110 specified by the targetUid. 111 112 @type targetUid: string 113 @param targetUid: New parent of the organizer 114 @type organizerUid: string 115 @param organizerUid: The organizer to move 116 @rtype: DirectResponse 117 @return: B{Properties}: 118 - data: (dictionary) Moved organizer 119 """ 120 facade = self._getFacade() 121 display_type = getDisplayType(facade._getObject(organizerUid)) 122 audit(['UI', display_type, 'Move'], organizerUid, to=targetUid) 123 data = facade.moveOrganizer(targetUid, organizerUid) 124 return DirectResponse.succeed(data=Zuul.marshal(data))
125
126 - def _getFacade(self):
127 """ 128 Abstract method for child classes to use to get their facade 129 """ 130 raise NotImplementedError("You must implement the _getFacade method")
131
132 - def asyncGetTree(self, id=None, additionalKeys=()):
133 """ 134 Server side method for asynchronous tree calls. Retrieves 135 the immediate children of the node specified by "id" 136 137 NOTE: our convention on the UI side is if we are asking 138 for the root node then return the root and its children 139 otherwise just return the children 140 141 @type id: string 142 @param id: The uid of the node we are getting the children for 143 @rtype: [dictionary] 144 @return: Object representing the immediate children 145 """ 146 facade = self._getFacade() 147 currentNode = facade.getTree(id) 148 # we want every tree property except the "children" one 149 keys = ('id', 'path', 'uid', 'iconCls', 'text', 'hidden', 'leaf') + additionalKeys 150 151 # load the severities in one request 152 childNodes = list(currentNode.children) 153 uuids = [n.uuid for n in childNodes if n.uuid] 154 zep = Zuul.getFacade('zep', self.context.dmd) 155 if uuids: 156 severities = zep.getWorstSeverity(uuids) 157 for child in childNodes: 158 if child.uuid: 159 child.setSeverity(zep.getSeverityName(severities.get(child.uuid, 0)).lower()) 160 161 children = [] 162 # explicitly marshall the children 163 for child in childNodes: 164 childData = Marshaller(child).marshal(keys) 165 children.append(childData) 166 children.sort(key=lambda e: (e['leaf'], e['uid'].lower())) 167 obj = currentNode._object._unrestrictedGetObject() 168 169 # check to see if we are asking for the root 170 primaryId = obj.getDmdRoot(obj.dmdRootName).getPrimaryId() 171 if id == primaryId: 172 root = Marshaller(currentNode).marshal(keys) 173 root['children'] = children 174 return [root] 175 return children
176
177 - def _canDeleteUid(self, uid):
178 """ 179 We can not delete top level UID's. For example: 180 - '/zport/dmd/Processes' this will return False (we can NOT delete) 181 - '/zport/dmd/Processes/Child' will return True 182 (we can delete this) 183 """ 184 # check the number of levels deep it is 185 levels = len(uid.split('/')) 186 return levels > 4
187