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

Source Code for Module Products.Zuul.routers.device

   1  ############################################################################## 
   2  # 
   3  # Copyright (C) Zenoss, Inc. 2009-2013, 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  Operations for Device Organizers and Devices. 
  13   
  14  Available at:  /zport/dmd/device_router 
  15  """ 
  16  import logging 
  17  from cgi import escape 
  18  from collections import OrderedDict 
  19  from itertools import islice 
  20  from AccessControl import Unauthorized 
  21  from Products.ZenUtils.Ext import DirectResponse 
  22  from Products.ZenUtils.Utils import getDisplayType 
  23  from Products.ZenUtils.jsonutils import unjson 
  24  from Products import Zuul 
  25  from Products.ZenModel.Device import Device 
  26  from Products.ZenModel.ZenossSecurity import ZEN_CHANGE_DEVICE_PRODSTATE, ZEN_MANAGE_DMD, \ 
  27      ZEN_ADMIN_DEVICE, ZEN_MANAGE_DEVICE, ZEN_DELETE_DEVICE 
  28  from Products.Zuul import filterUidsByPermission 
  29  from Products.Zuul.facades import ObjectNotFoundException 
  30  from Products.Zuul.routers import TreeRouter 
  31  from Products.Zuul.exceptions import DatapointNameConfict 
  32  from Products.Zuul.catalog.events import IndexingEvent 
  33  from Products.Zuul.form.interfaces import IFormBuilder 
  34  from Products.Zuul.decorators import require, contextRequire, serviceConnectionError 
  35  from Products.ZenUtils.guid.interfaces import IGlobalIdentifier, IGUIDManager 
  36  from Products.ZenMessaging.audit import audit 
  37  from zope.event import notify 
  38   
  39  log = logging.getLogger('zen.Zuul') 
40 41 -class DeviceRouter(TreeRouter):
42 """ 43 A JSON/ExtDirect interface to operations on devices 44 """ 45 46 @serviceConnectionError 47 @contextRequire("Manage DMD", 'contextUid')
48 - def addDeviceClassNode(self, type, contextUid, id, description=None, connectionInfo=None):
49 """ 50 Adds a new device class organizer specified by the parameter id to 51 the parent organizer specified by contextUid. 52 53 contextUid must be a path to a DeviceClass. 54 55 @type type: string 56 @param type: Node type (always 'organizer' in this case) 57 @type contextUid: string 58 @param contextUid: Path to the location organizer that will 59 be the new node's parent (ex. /zport/dmd/Devices/) 60 @type id: string 61 @param id: The identifier of the new node 62 @type description: string 63 @param description: (optional) Describes the new device class 64 @type connectionInfo: list 65 @param connectionInfo: (optional) List of zproperties that constitute credentials for this device classs 66 @rtype: dictionary 67 @return: B{Properties}: 68 - success: (bool) Success of node creation 69 - nodeConfig: (dictionary) The new device class's properties 70 """ 71 facade = self._getFacade() 72 organizer = facade.addDeviceClass(contextUid, 73 id, 74 description, 75 connectionInfo) 76 uid = organizer.uid 77 78 treeNode = facade.getTree(uid) 79 audit('UI.DeviceClass.Add', uid, description=description, connectionInfo=connectionInfo) 80 return DirectResponse.succeed("Device Class Added", nodeConfig=Zuul.marshal(treeNode))
81 82 83 @serviceConnectionError 84 @contextRequire("Manage DMD", 'contextUid')
85 - def addLocationNode(self, type, contextUid, id, 86 description=None, address=None):
87 """ 88 Adds a new location organizer specified by the parameter id to 89 the parent organizer specified by contextUid. 90 91 contextUid must be a path to a Location. 92 93 @type type: string 94 @param type: Node type (always 'organizer' in this case) 95 @type contextUid: string 96 @param contextUid: Path to the location organizer that will 97 be the new node's parent (ex. /zport/dmd/Devices/Locations) 98 @type id: string 99 @param id: The identifier of the new node 100 @type description: string 101 @param description: (optional) Describes the new location 102 @type address: string 103 @param address: (optional) Physical address of the new location 104 @rtype: dictionary 105 @return: B{Properties}: 106 - success: (bool) Success of node creation 107 - nodeConfig: (dictionary) The new location's properties 108 """ 109 facade = self._getFacade() 110 organizer = facade.addLocationOrganizer(contextUid, 111 id, 112 description, 113 address) 114 uid = organizer.uid 115 116 treeNode = facade.getTree(uid) 117 audit('UI.Location.Add', uid, description=description, address=address) 118 return DirectResponse.succeed("Location added", nodeConfig=Zuul.marshal(treeNode))
119
120 - def _getFacade(self):
121 return Zuul.getFacade('device', self.context)
122 123 @serviceConnectionError
124 - def getTree(self, id):
125 """ 126 Returns the tree structure of an organizer hierarchy where 127 the root node is the organizer identified by the id parameter. 128 129 @type id: string 130 @param id: Id of the root node of the tree to be returned 131 @rtype: [dictionary] 132 @return: Object representing the tree 133 """ 134 facade = self._getFacade() 135 tree = facade.getTree(id) 136 data = Zuul.marshal(tree) 137 return [data]
138 139 @serviceConnectionError
140 - def getComponents(self, uid=None, meta_type=None, keys=None, start=0, 141 limit=50, page=0, sort='name', dir='ASC', name=None):
142 """ 143 Retrieves all of the components at a given UID. This method 144 allows for pagination. 145 146 @type uid: string 147 @param uid: Unique identifier of the device whose components are 148 being retrieved 149 @type meta_type: string 150 @param meta_type: (optional) The meta type of the components to be 151 retrieved (default: None) 152 @type keys: list 153 @param keys: (optional) List of keys to include in the returned 154 dictionary. If None then all keys will be returned 155 (default: None) 156 @type start: integer 157 @param start: (optional) Offset to return the results from; used in 158 pagination (default: 0) 159 @type limit: integer 160 @param limit: (optional) Number of items to return; used in pagination 161 (default: 50) 162 @type sort: string 163 @param sort: (optional) Key on which to sort the return results; 164 (default: 'name') 165 @type dir: string 166 @param dir: (optional) Sort order; can be either 'ASC' or 'DESC' 167 (default: 'ASC') 168 @type name: regex 169 @param name: (optional) Used to filter the results (default: None) 170 @rtype: DirectResponse 171 @return: B{Properties}: 172 - data: (dictionary) The components returned 173 - totalCount: (integer) Number of items returned 174 - hash: (string) Hashcheck of the current component state (to check 175 whether components have changed since last query) 176 """ 177 facade = self._getFacade() 178 if name: 179 # Load every component if we have a filter 180 limit = None 181 comps = facade.getComponents(uid, meta_type=meta_type, start=start, 182 limit=limit, sort=sort, dir=dir, name=name, keys=keys) 183 total = comps.total 184 hash = comps.hash_ 185 186 data = Zuul.marshal(comps, keys=keys) 187 return DirectResponse(data=data, totalCount=total, 188 hash=hash)
189
190 - def getComponentTree(self, uid=None, id=None, sorting_dict=None):
191 """ 192 Retrieves all of the components set up to be used in a 193 tree. 194 195 @type uid: string 196 @param uid: Unique identifier of the root of the tree to retrieve 197 @type id: string 198 @param id: not used 199 @rtype: [dictionary] 200 @return: Component properties in tree form 201 """ 202 if id: 203 uid = id 204 facade = self._getFacade() 205 data = facade.getComponentTree(uid) 206 sevs = [c[0].lower() for c in 207 self.context.ZenEventManager.severityConversions] 208 data.sort(cmp=lambda a, b: cmp(sevs.index(a['severity']), 209 sevs.index(b['severity']))) 210 result = [] 211 for datum in data: 212 result.append(dict( 213 id=datum['type'], 214 path='Components/%s' % datum['type'], 215 text={ 216 'text': datum['type'], 217 'count': datum['count'], 218 'description': 'components'}, 219 iconCls='tree-severity-icon-small-' + datum['severity'], 220 leaf=True)) 221 if sorting_dict: 222 sorting_keys_list = [key for key in sorting_dict.iterkeys()] 223 def cmp_items(first, second): 224 # Resolving keys from a dictionary of given names convention 225 x = str(first['text']['text']) 226 y = str(second['text']['text']) 227 if x in sorting_keys_list: 228 x = sorting_dict[x][0] 229 if y in sorting_keys_list: 230 y = sorting_dict[y][0] 231 if x < y: 232 return -1 233 elif x > y: 234 return 1 235 else: 236 return 0
237 result.sort(cmp=cmp_items) 238 return result
239
240 - def findComponentIndex(self, componentUid, uid=None, meta_type=None, 241 sort='name', dir='ASC', name=None, **kwargs):
242 """ 243 Given a component uid and the component search criteria, this retrieves 244 the position of the component in the results. 245 246 @type componentUid: string 247 @param componentUid: Unique identifier of the component whose index 248 to return 249 @type uid: string 250 @param uid: Unique identifier of the device queried for components 251 @type meta_type: string 252 @param meta_type: (optional) The meta type of the components to retrieve 253 (default: None) 254 @type sort: string 255 @param sort: (optional) Key on which to sort the return results (default: 256 'name') 257 @type dir: string 258 @param dir: (optional) Sort order; can be either 'ASC' or 'DESC' 259 (default: 'ASC') 260 @type name: regex 261 @param name: (optional) Used to filter the results (default: None) 262 @rtype: DirectResponse 263 @return: B{Properties}: 264 - index: (integer) Index of the component 265 """ 266 facade = self._getFacade() 267 i = facade.findComponentIndex(componentUid, uid, 268 meta_type, sort, dir, name) 269 return DirectResponse(index=i)
270 271 @serviceConnectionError
272 - def getForm(self, uid):
273 """ 274 Given an object identifier, this returns all of the editable fields 275 on that object as well as their ExtJs xtype that one would 276 use on a client side form. 277 278 @type uid: string 279 @param uid: Unique identifier of an object 280 @rtype: DirectResponse 281 @return: B{Properties} 282 - form: (dictionary) form fields for the object 283 """ 284 info = self._getFacade().getInfo(uid) 285 form = IFormBuilder(info).render(fieldsets=False) 286 form = Zuul.marshal(form) 287 return DirectResponse(form=form)
288 289 @serviceConnectionError
290 - def getInfo(self, uid, keys=None):
291 """ 292 Get the properties of a device or device organizer 293 294 @type uid: string 295 @param uid: Unique identifier of an object 296 @type keys: list 297 @param keys: (optional) List of keys to include in the returned 298 dictionary. If None then all keys will be returned 299 (default: None) 300 @rtype: DirectResponse 301 @return: B{Properties} 302 - data: (dictionary) Object properties 303 - disabled: (bool) If current user doesn't have permission to use setInfo 304 """ 305 facade = self._getFacade() 306 process = facade.getInfo(uid) 307 data = Zuul.marshal(process, keys) 308 disabled = not Zuul.checkPermission('Manage DMD', self.context) 309 return DirectResponse(data=data, disabled=disabled)
310 311 @serviceConnectionError
312 - def setInfo(self, **data):
313 """ 314 Set attributes on a device or device organizer. 315 This method accepts any keyword argument for the property that you wish 316 to set. The only required property is "uid". 317 318 @type uid: string 319 @keyword uid: Unique identifier of an object 320 @rtype: DirectResponse 321 """ 322 facade = self._getFacade() 323 if not (Zuul.checkPermission(ZEN_MANAGE_DEVICE, self.context) or ( 324 Zuul.checkPermission(ZEN_CHANGE_DEVICE_PRODSTATE, 325 self.context) and 'productionState' in data.keys())): 326 raise Exception('You do not have permission to save changes.') 327 the_uid = data['uid'] # gets deleted 328 process = facade.getInfo(the_uid) 329 oldData = self._getInfoData(process, data.keys()) 330 Zuul.unmarshal(data, process) 331 newData = self._getInfoData(process, data.keys()) 332 # reindex the object if necessary 333 if hasattr(process._object, 'index_object'): 334 process._object.index_object() 335 336 # Ex: ('UI.Device.Edit', uid, data_={'productionState': 'High'}) 337 # Ex: ('UI.Location.Edit', uid, description='Blah', old_description='Foo') 338 if 'name' in oldData: 339 oldData['device_name'] = oldData['name'] # we call it this now 340 del oldData['name'] 341 if 'name' in newData: 342 del newData['name'] # it gets printed automatically 343 if isinstance(process._object, Device): 344 # ZEN-2837, ZEN-247: Audit names instead of numbers 345 dmd = self.context 346 if 'productionState' in oldData: 347 oldData['productionState'] = dmd.convertProdState(oldData['productionState']) 348 if 'productionState' in newData: 349 newData['productionState'] = dmd.convertProdState(newData['productionState']) 350 if 'priority' in oldData: 351 oldData['priority'] = dmd.convertPriority(oldData['priority']) 352 if 'priority' in newData: 353 newData['priority'] = dmd.convertPriority(newData['priority']) 354 audit(['UI', getDisplayType(process._object), 'Edit'], the_uid, 355 data_=newData, oldData_=oldData, skipFields_='uid') 356 return DirectResponse.succeed()
357
358 - def _getInfoData(self, info, keys):
359 # TODO: generalize this code for all object types, if possible. 360 values = {} 361 for key in keys: 362 val = getattr(info, key, None) 363 if val is not None: 364 values[key] = str(val) # unmutable copy 365 return values
366 367 @require('Manage Device')
368 - def resumeCollection(self, id):
369 # argument 1 is actually uid but is passed as the "id" keyword 370 return self._getFacade().resumeCollection(id)
371 372 @require('Manage Device')
373 - def setProductInfo(self, uid, **data):
374 """ 375 Sets the ProductInfo on a device. This method has the following valid 376 keyword arguments: 377 378 @type uid: string 379 @keyword uid: Unique identifier of a device 380 @type hwManufacturer: string 381 @keyword hwManufacturer: Hardware manufacturer 382 @type hwProductName: string 383 @keyword hwProductName: Hardware product name 384 @type osManufacturer: string 385 @keyword osManufacturer: Operating system manufacturer 386 @type osProductName: string 387 @keyword osProductName: Operating system product name 388 @rtype: DirectResponse 389 """ 390 facade = self._getFacade() 391 facade.setProductInfo(uid, **data) 392 audit('UI.Device.Edit', uid, data_=data) 393 return DirectResponse()
394
395 - def getDeviceUuidsByName(self, query="", start=0, limit=25, page=1, uuid=None):
396 """ 397 Retrieves a list of device uuids. For use in combos. 398 If uuid is set, ensures that it is included in the returned list. 399 """ 400 facade = self._getFacade() 401 devices = facade.getDevices(params={'name':query}) # TODO: pass start=start, limit=limit 402 result = [{'name':escape(dev.name), 403 'uuid':IGlobalIdentifier(dev._object).getGUID()} 404 for dev in devices] 405 406 if uuid and uuid not in (device['uuid'] for device in result): 407 guidManager = IGUIDManager(self.context.dmd) 408 device = guidManager.getObject(uuid) 409 if device: 410 result.append({'name':escape(device.name()), 'uuid':uuid}) 411 412 return DirectResponse.succeed(data=result)
413
414 - def getDeviceUids(self, uid):
415 """ 416 Return a list of device uids underneath an organizer. This includes 417 all the devices belonging to an child organizers. 418 419 @type uid: string 420 @param uid: Unique identifier of the organizer to get devices from 421 @rtype: DirectResponse 422 @return: B{Properties}: 423 - devices: (list) device uids 424 """ 425 facade = self._getFacade() 426 uids = facade.getDeviceUids(uid) 427 return DirectResponse.succeed(devices=uids)
428 429 @serviceConnectionError
430 - def getDevices(self, uid=None, start=0, params=None, limit=50, sort='name', 431 page=None, 432 dir='ASC', keys=None):
433 """ 434 Retrieves a list of devices. This method supports pagination. 435 436 @type uid: string 437 @param uid: Unique identifier of the organizer to get devices from 438 @type start: integer 439 @param start: (optional) Offset to return the results from; used in 440 pagination (default: 0) 441 @type params: dictionary 442 @param params: (optional) Key-value pair of filters for this search. 443 Can be one of the following: name, ipAddress, 444 deviceClass, or productionState (default: None) 445 @type limit: integer 446 @param limit: (optional) Number of items to return; used in pagination 447 (default: 50) 448 @type sort: string 449 @param sort: (optional) Key on which to sort the return results (default: 450 'name') 451 @type dir: string 452 @param dir: (optional) Sort order; can be either 'ASC' or 'DESC' 453 (default: 'ASC') 454 @rtype: DirectResponse 455 @return: B{Properties}: 456 - devices: (list) Dictionaries of device properties 457 - totalCount: (integer) Number of devices returned 458 - hash: (string) Hashcheck of the current device state (to check 459 whether devices have changed since last query) 460 """ 461 facade = self._getFacade() 462 if isinstance(params, basestring): 463 params = unjson(params) 464 465 if params: 466 # clearing most often issue 467 # - anterior asterisk wildcard (one or more) 468 params = {key:(value.lstrip('*') if isinstance(value, str) else value) 469 for key, value in params.iteritems()} 470 471 devices = facade.getDevices(uid, start, limit, sort, dir, params) 472 allKeys = ['name', 'ipAddress', 'productionState', 'events', 473 'ipAddressString', 'serialNumber', 'hwManufacturer', 474 'hwModel', 'osModel', 'osManufacturer', 'collector', 475 'priority', 'systems', 'groups', 'location', 476 'pythonClass', 'tagNumber'] 477 usedKeys = keys or allKeys 478 if not 'uid' in usedKeys: 479 usedKeys.append('uid') 480 481 data = Zuul.marshal(devices.results, usedKeys) 482 483 return DirectResponse(devices=data, totalCount=devices.total, 484 hash=devices.hash_)
485
486 - def renameDevice(self, uid, newId, retainGraphData=False):
487 """ 488 Set the device specified by the uid,"uid" to have the 489 the id "newId" 490 This will raise an exception if it fails. 491 492 @type uid: string 493 @param uid: The unique id of the device we are renaming 494 @type newId: string 495 @param newId: string of the new id 496 """ 497 facade = self._getFacade() 498 newUid = facade.renameDevice(uid, newId, retainGraphData) 499 return DirectResponse.succeed(uid=newUid)
500
501 - def doesMoveRequireRemodel(self, uid, target):
502 """ 503 Determine if the device will need to be remodeled if it is moved. 504 505 @type uid: string 506 @param uid: Uid of device in current location 507 @type target: string 508 @param target: Uid of the organizer to move the device to 509 """ 510 facade = self._getFacade() 511 remodelRequired = facade.doesMoveRequireRemodel(uid, target) 512 return DirectResponse.succeed(remodelRequired=remodelRequired)
513
514 - def moveDevices(self, uids, target, hashcheck=None, ranges=(), uid=None, 515 params=None, sort='name', dir='ASC', asynchronous=True):
516 """ 517 Moves the devices specified by uids to the organizer specified by 'target'. 518 519 @type uids: [string] 520 @param uids: List of device uids to move 521 @type target: string 522 @param target: Uid of the organizer to move the devices to 523 @type hashcheck: string 524 @param hashcheck: Hashcheck for the devices (from getDevices()) 525 @type ranges: [integer] 526 @param ranges: (optional) List of two integers that are the min/max 527 values of a range of uids to include (default: None) 528 @type uid: string 529 @param uid: (optional) Organizer to use when using ranges to get 530 additional uids (default: None) 531 @type params: dictionary 532 @param params: (optional) Key-value pair of filters for this search. 533 Can be one of the following: name, ipAddress, 534 deviceClass, or productionState (default: None) 535 @type sort: string 536 @param sort: (optional) Key on which to sort the return result (default: 537 'name') 538 @type dir: string 539 @param dir: (optional) Sort order; can be either 'ASC' or 'DESC' 540 (default: 'ASC') 541 @rtype: DirectResponse 542 @return: B{Properties}: 543 - tree: ([dictionary]) Object representing the new device tree 544 - exports: (integer) Number of devices moved 545 """ 546 if ranges: 547 uids += self.loadRanges(ranges, hashcheck, uid, params, sort, dir) 548 uids = filterUidsByPermission(self.context.dmd, ZEN_MANAGE_DEVICE, uids) 549 facade = self._getFacade() 550 551 # In order to display the device name and old location/device class, 552 # we must audit first. This means it's possible we can audit a change 553 # then the command fails, unfortunately. 554 # example: audit('UI.Device.ChangeLocation', uid, location=..., old_location=...) 555 targetType = getDisplayType(facade._getObject(target)) 556 autoRemovalTypes = ('DeviceClass', 'Location') 557 action = ('Change' if targetType in autoRemovalTypes else 'AddTo') + targetType 558 for uid in uids: 559 oldData = {} 560 if targetType == 'Location': # get old location 561 location = facade._getObject(uid).location() 562 locationPath = location.getPrimaryId() if location else '' 563 oldData[targetType] = locationPath 564 elif targetType == 'DeviceClass': 565 deviceClass = facade._getObject(uid).deviceClass() 566 deviceClassPath = deviceClass.getPrimaryId() if deviceClass else '' 567 oldData[targetType] = deviceClassPath 568 audit(['UI.Device', action], uid, 569 data_={targetType:target}, oldData_=oldData) 570 try: 571 targetObj = facade._getObject(target) 572 if Zuul.checkPermission(ZEN_ADMIN_DEVICE, targetObj): 573 result = facade.moveDevices(uids, target, asynchronous=asynchronous) 574 else: 575 return DirectResponse.fail(msg='User does not have permissions to move devices to {0}'.format(target)) 576 except Exception, e: 577 log.exception("Failed to move devices") 578 return DirectResponse.exception(e, 'Failed to move devices.') 579 if asynchronous: 580 return DirectResponse.succeed(new_jobs=Zuul.marshal([result], 581 keys=('uuid', 'description', 'started'))) 582 else: 583 return DirectResponse.succeed(exports=result)
584 585 @require('Manage Device')
586 - def pushChanges(self, uids, hashcheck, ranges=(), uid=None, params=None, 587 sort='name', dir='ASC'):
588 """ 589 Push changes on device(s) configuration to collectors. 590 591 @type uids: [string] 592 @param uids: List of device uids to push changes 593 @type hashcheck: string 594 @param hashcheck: Hashcheck for the devices (from getDevices()) 595 @type ranges: [integer] 596 @param ranges: (optional) List of two integers that are the min/max 597 values of a range of uids to include (default: None) 598 @type uid: string 599 @param uid: (optional) Organizer to use when using ranges to get 600 additional uids (default: None) 601 @type params: dictionary 602 @param params: (optional) Key-value pair of filters for this search. 603 Can be one of the following: name, ipAddress, 604 deviceClass, or productionState (default: None) 605 @type sort: string 606 @param sort: (optional) Key on which to sort the return result (default: 607 'name') 608 @type dir: string 609 @param dir: (optional) Sort order; can be either 'ASC' or 'DESC' 610 (default: 'ASC') 611 @rtype: DirectResponse 612 @return: Success message 613 """ 614 if ranges: 615 uids += self.loadRanges(ranges, hashcheck, uid, params, sort, dir) 616 617 facade = self._getFacade() 618 facade.pushChanges(uids) 619 for uid in uids: 620 audit('UI.Device.PushChanges', uid) 621 return DirectResponse.succeed('Changes pushed to collectors.')
622
623 - def lockDevices(self, uids, hashcheck, ranges=(), updates=False, 624 deletion=False, sendEvent=False, uid=None, params=None, 625 sort='name', dir='ASC'):
626 """ 627 Lock device(s) from changes. 628 629 @type uids: [string] 630 @param uids: List of device uids to lock 631 @type hashcheck: string 632 @param hashcheck: Hashcheck for the devices (from getDevices()) 633 @type ranges: [integer] 634 @param ranges: (optional) List of two integers that are the min/max 635 values of a range of uids to include (default: None) 636 @type updates: boolean 637 @param updates: (optional) True to lock device from updates (default: False) 638 @type deletion: boolean 639 @param deletion: (optional) True to lock device from deletion 640 (default: False) 641 @type sendEvent: boolean 642 @param sendEvent: (optional) True to send an event when an action is 643 blocked by locking (default: False) 644 @type uid: string 645 @param uid: (optional) Organizer to use when using ranges to get 646 additional uids (default: None) 647 @type params: dictionary 648 @param params: (optional) Key-value pair of filters for this search. 649 Can be one of the following: name, ipAddress, 650 deviceClass, or productionState (default: None) 651 @type sort: string 652 @param sort: (optional) Key on which to sort the return result (default: 653 'name') 654 @type dir: string 655 @param dir: (optional) Sort order; can be either 'ASC' or 'DESC' 656 (default: 'ASC') 657 @rtype: DirectResponse 658 @return: Success or failure message 659 """ 660 if ranges: 661 uids += self.loadRanges(ranges, hashcheck, uid, params, sort, dir) 662 facade = self._getFacade() 663 uids = filterUidsByPermission(self.context.dmd, ZEN_MANAGE_DMD, uids) 664 try: 665 facade.setLockState(uids, deletion=deletion, updates=updates, 666 sendEvent=sendEvent) 667 if not deletion and not updates: 668 message = "Unlocked %s devices." % len(uids) 669 else: 670 actions = [] 671 if deletion: 672 actions.append('deletion') 673 if updates: 674 actions.append('updates') 675 message = "Locked %s devices from %s." % (len(uids), 676 ' and '.join(actions)) 677 for uid in uids: 678 audit('UI.Device.EditLocks', uid, 679 deletion=deletion, updates=updates, sendEvent=sendEvent) 680 return DirectResponse.succeed(message) 681 except Exception, e: 682 log.exception(e) 683 return DirectResponse.exception(e, 'Failed to lock devices.')
684 685
686 - def resetIp(self, uids, hashcheck, uid=None, ranges=(), params=None, 687 sort='name', dir='ASC', ip=''):
688 """ 689 Reset IP address(es) of device(s) to the results of a DNS lookup or 690 a manually set address 691 692 @type uids: [string] 693 @param uids: List of device uids with IP's to reset 694 @type hashcheck: string 695 @param hashcheck: Hashcheck for the devices (from getDevices()) 696 @type uid: string 697 @param uid: (optional) Organizer to use when using ranges to get 698 additional uids (default: None) 699 @type ranges: [integer] 700 @param ranges: (optional) List of two integers that are the min/max 701 values of a range of uids to include (default: None) 702 @type params: dictionary 703 @param params: (optional) Key-value pair of filters for this search. 704 Can be one of the following: name, ipAddress, 705 deviceClass, or productionState (default: None) 706 @type sort: string 707 @param sort: (optional) Key on which to sort the return result (default: 708 'name') 709 @type dir: string 710 @param dir: (optional) Sort order; can be either 'ASC' or 'DESC' 711 (default: 'ASC') 712 @type ip: string 713 @param ip: (optional) IP to set device to. Empty string causes DNS 714 lookup (default: '') 715 @rtype: DirectResponse 716 @return: Success or failure message 717 """ 718 if ranges: 719 uids += self.loadRanges(ranges, hashcheck, uid, params, sort, dir) 720 facade = self._getFacade() 721 uids = filterUidsByPermission(self.context.dmd, ZEN_ADMIN_DEVICE, uids) 722 try: 723 for uid in uids: 724 info = facade.getInfo(uid) 725 info.ipAddress = ip # Set to empty causes DNS lookup 726 audit('UI.Device.ResetIP', uid, ip=ip) 727 return DirectResponse('Reset %s IP addresses.' % len(uids)) 728 except Exception, e: 729 log.exception(e) 730 return DirectResponse.exception(e, 'Failed to reset IP addresses.')
731 732 @require('Manage Device')
733 - def resetCommunity(self, uids, hashcheck, uid=None, ranges=(), params=None, 734 sort='name', dir='ASC'):
735 """ 736 Reset SNMP community string(s) on device(s) 737 738 @type uids: [string] 739 @param uids: List of device uids to reset 740 @type hashcheck: string 741 @param hashcheck: Hashcheck for the devices (from getDevices()) 742 @type uid: string 743 @param uid: (optional) Organizer to use when using ranges to get 744 additional uids (default: None) 745 @type ranges: [integer] 746 @param ranges: (optional) List of two integers that are the min/max 747 values of a range of uids to include (default: None) 748 @type params: dictionary 749 @param params: (optional) Key-value pair of filters for this search. 750 Can be one of the following: name, ipAddress, 751 deviceClass, or productionState (default: None) 752 @type sort: string 753 @param sort: (optional) Key on which to sort the return result (default: 754 'name') 755 @type dir: string 756 @param dir: (optional) Sort order; can be either 'ASC' or 'DESC' 757 (default: 'ASC') 758 @rtype: DirectResponse 759 @return: Success or failure message 760 """ 761 if ranges: 762 uids += self.loadRanges(ranges, hashcheck, uid, params, sort, dir) 763 facade = self._getFacade() 764 try: 765 for uid in uids: 766 facade.resetCommunityString(uid) 767 audit('UI.Device.ResetCommunity', uid) 768 return DirectResponse('Reset %s community strings.' % len(uids)) 769 except Exception, e: 770 log.exception(e) 771 return DirectResponse.exception(e, 'Failed to reset community strings.')
772
773 - def setProductionState(self, uids, prodState, hashcheck, uid=None, 774 ranges=(), params=None, sort='name', dir='ASC'):
775 """ 776 Set the production state of device(s). 777 778 @type uids: [string] 779 @param uids: List of device uids to set 780 @type prodState: integer 781 @param prodState: Production state to set device(s) to. 782 @type hashcheck: string 783 @param hashcheck: Hashcheck for the devices (from getDevices()) 784 @type uid: string 785 @param uid: (optional) Organizer to use when using ranges to get 786 additional uids (default: None) 787 @type ranges: [integer] 788 @param ranges: (optional) List of two integers that are the min/max 789 values of a range of uids to include (default: None) 790 @type params: dictionary 791 @param params: (optional) Key-value pair of filters for this search. 792 Can be one of the following: name, ipAddress, 793 deviceClass, or productionState (default: None) 794 @type sort: string 795 @param sort: (optional) Key on which to sort the return result (default: 796 'name') 797 @type dir: string 798 @param dir: (optional) Sort order; can be either 'ASC' or 'DESC' 799 (default: 'ASC') 800 @rtype: DirectResponse 801 @return: Success or failure message 802 """ 803 if ranges: 804 uids += self.loadRanges(ranges, hashcheck, uid, params, sort, dir) 805 facade = self._getFacade() 806 uids = filterUidsByPermission(self.context.dmd, ZEN_CHANGE_DEVICE_PRODSTATE, 807 uids) 808 try: 809 oldStates = {} 810 uids = (uids,) if isinstance(uids, basestring) else uids 811 for uid in uids: 812 device = facade._getObject(uid) 813 if isinstance(device, Device): 814 oldStates[uid] = self.context.convertProdState(device.getProductionState()) 815 816 prodStateName = self.context.convertProdState(prodState) 817 818 auditData = {'productionState': prodStateName} 819 for uid in uids: 820 oldAuditData = {'productionState': oldStates[uid]} 821 audit('UI.Device.Edit', uid, oldData_=oldAuditData, data_=auditData) 822 facade.setProductionState(uids, prodState, asynchronous=True) 823 return DirectResponse('Set %s devices to %s.' % ( 824 len(uids), prodStateName)) 825 except Exception, e: 826 log.exception(e) 827 return DirectResponse.exception(e, 'Failed to change production state.')
828
829 - def setPriority(self, uids, priority, hashcheck, uid=None, ranges=(), 830 params=None, sort='name', dir='ASC'):
831 """ 832 Set device(s) priority. 833 834 @type uids: [string] 835 @param uids: List of device uids to set 836 @type priority: integer 837 @param priority: Priority to set device(s) to. 838 @type hashcheck: string 839 @param hashcheck: Hashcheck for the devices (from getDevices()) 840 @type uid: string 841 @param uid: (optional) Organizer to use when using ranges to get 842 additional uids (default: None) 843 @type ranges: [integer] 844 @param ranges: (optional) List of two integers that are the min/max 845 values of a range of uids to include (default: None) 846 @type params: dictionary 847 @param params: (optional) Key-value pair of filters for this search. 848 Can be one of the following: name, ipAddress, 849 deviceClass, or productionState (default: None) 850 @type sort: string 851 @param sort: (optional) Key on which to sort the return result (default: 852 'name') 853 @type dir: string 854 @param dir: (optional) Sort order; can be either 'ASC' or 'DESC' 855 (default: 'ASC') 856 @rtype: DirectResponse 857 @return: Success or failure message 858 """ 859 if ranges: 860 uids += self.loadRanges(ranges, hashcheck, uid, params, sort, dir) 861 facade = self._getFacade() 862 uids = filterUidsByPermission(self.context.dmd, ZEN_MANAGE_DEVICE, uids) 863 try: 864 for uid in uids: 865 info = facade.getInfo(uid) 866 oldPriorityLabel = info.priorityLabel 867 info.priority = priority 868 notify(IndexingEvent(info._object)) 869 audit('UI.Device.Edit', uid, 870 priority=info.priorityLabel, 871 oldData_={'priority':oldPriorityLabel}) 872 return DirectResponse('Set %s devices to %s priority.' % ( 873 len(uids), info.priorityLabel)) 874 except Exception, e: 875 log.exception(e) 876 return DirectResponse.exception(e, 'Failed to change priority.')
877
878 - def moveCollectorDevices(self, srcCollectors, dstCollector, hashcheck, uid=None, ranges=(), 879 params=None, sort='name', dir='ASC', moveData=False, 880 asynchronous=True):
881 """ 882 Move all devices under one or more collectors to another collector 883 884 The signature is exactly the same as setCollector(), except that the 885 'uids' parameter is replaced with 'srcCollectors' 886 887 @type srcCollectors: list of strings 888 @param srcCollectors: The collectors to move all devices from 889 """ 890 monitorFacade = Zuul.getFacade('monitors', self.context) 891 if isinstance(srcCollectors, basestring): 892 srcCollectorObjs = monitorFacade.get(srcCollectors) 893 else: 894 srcCollectorObjs = [] 895 for collector in srcCollectors: 896 srcCollectorObjs.append(monitorFacade.get(collector)) 897 deviceUids = [] 898 for collector in srcCollectorObjs: 899 deviceUids.extend([ dev.getPrimaryId() for dev in collector.getDevices() ]) 900 return self.setCollector(deviceUids, dstCollector, hashcheck, uid, ranges, 901 params, sort, dir, moveData, asynchronous)
902
903 - def setCollector(self, uids, collector, hashcheck, uid=None, ranges=(), 904 params=None, sort='name', dir='ASC', moveData=False, 905 asynchronous=True):
906 """ 907 Set device(s) collector. 908 909 @type uids: [string] 910 @param uids: List of device uids to set 911 @type collector: string 912 @param collector: Collector to set devices to 913 @type hashcheck: string 914 @param hashcheck: Hashcheck for the devices (from getDevices()) 915 @type uid: string 916 @param uid: (optional) Organizer to use when using ranges to get 917 additional uids (default: None) 918 @type ranges: [integer] 919 @param ranges: (optional) List of two integers that are the min/max 920 values of a range of uids to include (default: None) 921 @type params: dictionary 922 @param params: (optional) Key-value pair of filters for this search. 923 Can be one of the following: name, ipAddress, 924 deviceClass, or productionState (default: None) 925 @type sort: string 926 @param sort: (optional) Key on which to sort the return result (default: 927 'name') 928 @type dir: string 929 @param dir: (optional) Sort order; can be either 'ASC' or 'DESC' 930 (default: 'ASC') 931 @rtype: DirectResponse 932 @return: Success or failure message 933 """ 934 if ranges: 935 uids += self.loadRanges(ranges, hashcheck, uid, params, sort, dir) 936 facade = self._getFacade() 937 uids = filterUidsByPermission(self.context.dmd, ZEN_ADMIN_DEVICE, uids) 938 try: 939 # iterate through uids so that logging works as expected 940 result = facade.setCollector(uids, collector, asynchronous) 941 for devUid in uids: 942 audit('UI.Device.ChangeCollector', devUid, collector=collector) 943 if asynchronous and result: 944 return DirectResponse.succeed(new_jobs=Zuul.marshal(result, 945 keys=('uuid', 'description', 'started'))) 946 else: 947 return DirectResponse.succeed('Changed collector to %s for %s devices.' % 948 (collector, len(uids))) 949 except Exception, e: 950 log.exception(e) 951 return DirectResponse.exception(e, 'Failed to change the collector.')
952
953 - def setComponentsMonitored(self, uids, hashcheck, monitor=False, uid=None, 954 ranges=(), meta_type=None, keys=None, 955 start=0, limit=50, sort='name', dir='ASC', 956 name=None):
957 """ 958 Set the monitoring flag for component(s) 959 960 @type uids: [string] 961 @param uids: List of component uids to set 962 @type hashcheck: string 963 @param hashcheck: Hashcheck for the components (from getComponents()) 964 @type monitor: boolean 965 @param monitor: (optional) True to monitor component (default: False) 966 @type uid: string 967 @param uid: (optional) Device to use when using ranges to get 968 additional uids (default: None) 969 @type ranges: [integer] 970 @param ranges: (optional) List of two integers that are the min/max 971 values of a range of uids to include (default: None) 972 @type meta_type: string 973 @param meta_type: (optional) The meta type of the components to retrieve 974 (default: None) 975 @type keys: [string] 976 @param keys: not used 977 @type start: integer 978 @param start: (optional) Offset to return the results from; used in 979 pagination (default: 0) 980 @type limit: integer 981 @param limit: (optional) Number of items to return; used in pagination 982 (default: 50) 983 @type sort: string 984 @param sort: (optional) Key on which to sort the return result (default: 985 'name') 986 @type dir: string 987 @param dir: (optional) Sort order; can be either 'ASC' or 'DESC' 988 (default: 'ASC') 989 @type name: string 990 @param name: (optional) Component name to search for when loading ranges 991 (default: None) 992 @rtype: DirectResponse 993 @return: Success or failure message 994 """ 995 if ranges: 996 uids += self.loadComponentRanges(ranges, hashcheck, uid, (), 997 meta_type, start, limit, sort, 998 dir, name) 999 facade = self._getFacade() 1000 facade.setMonitor(uids, monitor) 1001 action = 'SetMonitored' if monitor else 'SetUnmonitored' 1002 for uid in uids: 1003 audit(['UI.Component', action], uid) 1004 return DirectResponse.succeed(('Set monitoring to %s for %s' 1005 ' components.') % (monitor, len(uids)))
1006
1007 - def lockComponents(self, uids, hashcheck, uid=None, ranges=(), 1008 updates=False, deletion=False, sendEvent=False, 1009 meta_type=None, keys=None, start=0, limit=50, 1010 sort='name', dir='ASC', name=None):
1011 """ 1012 Lock component(s) from changes. 1013 1014 @type uids: [string] 1015 @param uids: List of component uids to lock 1016 @type hashcheck: string 1017 @param hashcheck: Hashcheck for the components (from getComponents()) 1018 @type uid: string 1019 @param uid: (optional) Device to use when using ranges to get 1020 additional uids (default: None) 1021 @type ranges: [integer] 1022 @param ranges: (optional) List of two integers that are the min/max 1023 values of a range of uids to include (default: None) 1024 @type updates: boolean 1025 @param updates: (optional) True to lock component from updates (default: False) 1026 @type deletion: boolean 1027 @param deletion: (optional) True to lock component from deletion 1028 (default: False) 1029 @type sendEvent: boolean 1030 @param sendEvent: (optional) True to send an event when an action is 1031 blocked by locking (default: False) 1032 @type meta_type: string 1033 @param meta_type: (optional) The meta type of the components to retrieve 1034 (default: None) 1035 @type keys: [string] 1036 @param keys: not used 1037 @type start: integer 1038 @param start: (optional) Offset to return the results from; used in 1039 pagination (default: 0) 1040 @type limit: integer 1041 @param limit: (optional) Number of items to return; used in pagination 1042 (default: 50) 1043 @type sort: string 1044 @param sort: (optional) Key on which to sort the return result (default: 1045 'name') 1046 @type dir: string 1047 @param dir: (optional) Sort order; can be either 'ASC' or 'DESC' 1048 (default: 'ASC') 1049 @type name: string 1050 @param name: (optional) Component name to search for when loading ranges 1051 (default: None) 1052 @rtype: DirectResponse 1053 @return: Success or failure message 1054 """ 1055 if ranges: 1056 uids += self.loadComponentRanges(ranges, hashcheck, uid, (), 1057 meta_type, start, limit, sort, 1058 dir, name) 1059 facade = self._getFacade() 1060 try: 1061 facade.setLockState(uids, deletion=deletion, updates=updates, 1062 sendEvent=sendEvent) 1063 if not deletion and not updates: 1064 message = "Unlocked %d components." % len(uids) 1065 else: 1066 actions = [] 1067 if deletion: 1068 actions.append('deletion') 1069 if updates: 1070 actions.append('updates') 1071 actions = ' and '.join(actions) 1072 message = "Locked %d components from %s." % (len(uids), actions) 1073 for uid in uids: 1074 audit('UI.Component.EditLocks', uid, 1075 deletion=deletion, updates=updates, sendEvents=sendEvent) 1076 return DirectResponse.succeed(message) 1077 except Exception, e: 1078 log.exception(e) 1079 return DirectResponse.exception(e, 'Failed to lock components.')
1080
1081 - def deleteComponents(self, uids, hashcheck, uid=None, ranges=(), 1082 meta_type=None, keys=None, start=0, limit=50, 1083 sort='name', dir='ASC', name=None):
1084 """ 1085 Delete device component(s). 1086 1087 @type uids: [string] 1088 @param uids: List of component uids to delete 1089 @type hashcheck: string 1090 @param hashcheck: Hashcheck for the components (from getComponents()) 1091 @type uid: string 1092 @param uid: (optional) Device to use when using ranges to get 1093 additional uids (default: None) 1094 @type ranges: [integer] 1095 @param ranges: (optional) List of two integers that are the min/max 1096 values of a range of uids to include (default: None) 1097 @type meta_type: string 1098 @param meta_type: (optional) The meta type of the components to retrieve 1099 (default: None) 1100 @type keys: [string] 1101 @param keys: not used 1102 @type start: integer 1103 @param start: (optional) Offset to return the results from; used in 1104 pagination (default: 0) 1105 @type limit: integer 1106 @param limit: (optional) Number of items to return; used in pagination 1107 (default: 50) 1108 @type sort: string 1109 @param sort: (optional) Key on which to sort the return result (default: 1110 'name') 1111 @type dir: string 1112 @param dir: (optional) Sort order; can be either 'ASC' or 'DESC' 1113 (default: 'ASC') 1114 @type name: string 1115 @param name: (optional) Component name to search for when loading ranges 1116 (default: None) 1117 @rtype: DirectResponse 1118 @return: Success or failure message 1119 """ 1120 if ranges: 1121 uids += self.loadComponentRanges(ranges, hashcheck, uid, (), 1122 meta_type, start, limit, sort, 1123 dir, name) 1124 facade = self._getFacade() 1125 try: 1126 facade.deleteComponents(uids) 1127 for uid in uids: 1128 audit('UI.Component.Delete', uid) 1129 return DirectResponse.succeed('Components deleted.') 1130 except Exception, e: 1131 log.exception(e) 1132 return DirectResponse.exception(e, 'Failed to delete components.')
1133
1134 - def removeDevices(self, uids, hashcheck, action="remove", uid=None, 1135 ranges=(), params=None, sort='name', dir='ASC', 1136 deleteEvents=False, deletePerf=False 1137 ):
1138 """ 1139 Remove/delete device(s). 1140 1141 @type uids: [string] 1142 @param uids: List of device uids to remove 1143 @type hashcheck: string 1144 @param hashcheck: Hashcheck for the devices (from getDevices()) 1145 @type action: string 1146 @param action: Action to take. 'remove' to remove devices from organizer 1147 uid, and 'delete' to delete the device from Zenoss. 1148 @type uid: string 1149 @param uid: (optional) Organizer to use when using ranges to get 1150 additional uids and/or to remove device (default: None) 1151 @type ranges: [integer] 1152 @param ranges: (optional) List of two integers that are the min/max 1153 values of a range of uids to include (default: None) 1154 @type params: dictionary 1155 @param params: (optional) Key-value pair of filters for this search. 1156 Can be one of the following: name, ipAddress, 1157 deviceClass, or productionState (default: None) 1158 @type sort: string 1159 @param sort: (optional) Key on which to sort the return result (default: 1160 'name') 1161 @type dir: string 1162 @param dir: (optional) Sort order; can be either 'ASC' or 'DESC' 1163 (default: 'ASC') 1164 @type deleteEvents: bool 1165 @param deleteEvents: will remove all the events for the devices as well 1166 @type deletePerf: bool 1167 @param deletePerf: will remove all the perf data for the devices 1168 @rtype: DirectResponse 1169 @return: B{Properties}: 1170 - devtree: ([dictionary]) Object representing the new device tree 1171 - grptree: ([dictionary]) Object representing the new group tree 1172 - systree: ([dictionary]) Object representing the new system tree 1173 - loctree: ([dictionary]) Object representing the new location tree 1174 """ 1175 if ranges: 1176 uids += self.loadRanges(ranges, hashcheck, uid, params, sort, dir) 1177 facade = self._getFacade() 1178 removedUids = tuple() 1179 uids = filterUidsByPermission(self.context.dmd, ZEN_DELETE_DEVICE, uids) 1180 try: 1181 if action == "remove": 1182 removed = facade.removeDevices(uids, organizer=uid) 1183 1184 # uid could be an object or string. 1185 organizer = facade._getObject(uid) if isinstance(uid, basestring) else uid 1186 organizerType = organizer.meta_type 1187 action = 'RemoveFrom' + organizerType # Ex: RemoveFromLocation 1188 removedUids = map(lambda x: x.uid, removed) 1189 for devuid in removedUids: 1190 # Ex: ('UI.Device.RemoveFromLocation', deviceUid, location=...) 1191 audit('UI.Device.%s' % action, devuid, data_={organizerType:uid}) 1192 notRemovedUids = list(set(uids) - set(removedUids)) 1193 return DirectResponse.succeed( 1194 removedUids=removedUids, 1195 notRemovedUids=notRemovedUids) 1196 elif action == "delete": 1197 for devuid in uids: 1198 audit('UI.Device.Delete', devuid, 1199 deleteEvents=deleteEvents, 1200 deletePerf=deletePerf) 1201 facade.deleteDevices(uids, 1202 deleteEvents=deleteEvents, 1203 deletePerf=deletePerf) 1204 return DirectResponse.succeed() 1205 except Exception, e: 1206 log.exception(e) 1207 return DirectResponse.exception(e, 'Failed to remove devices.')
1208 1209 @serviceConnectionError
1210 - def getGraphDefs(self, uid, drange=None):
1211 """ 1212 Returns the url and title for each graph 1213 for the object passed in. 1214 @type uid: string 1215 @param uid: unique identifier of an object 1216 """ 1217 facade = self._getFacade() 1218 data = facade.getGraphDefs(uid, drange) 1219 return DirectResponse(data=Zuul.marshal(data))
1220
1221 - def loadRanges(self, ranges, hashcheck, uid=None, params=None, 1222 sort='name', dir='ASC'):
1223 """ 1224 Get a range of device uids. 1225 1226 @type ranges: [integer] 1227 @param ranges: List of two integers that are the min/max values of a 1228 range of uids 1229 @type hashcheck: string 1230 @param hashcheck: Hashcheck for the devices (from getDevices()) 1231 @type uid: string 1232 @param uid: (optional) Organizer to use to get uids (default: None) 1233 @type params: dictionary 1234 @param params: (optional) Key-value pair of filters for this search. 1235 Can be one of the following: name, ipAddress, 1236 deviceClass, or productionState (default: None) 1237 @type sort: string 1238 @param sort: (optional) Key on which to sort the return result (default: 1239 'name') 1240 @type dir: string 1241 @param dir: (optional) Sort order; can be either 'ASC' or 'DESC' 1242 (default: 'ASC') 1243 @rtype: [string] 1244 @return: A list of device uids 1245 """ 1246 facade = self._getFacade() 1247 if isinstance(params, basestring): 1248 params = unjson(params) 1249 devs = facade.getDeviceBrains(uid, limit=None, sort=sort, dir=dir, 1250 params=params, hashcheck=hashcheck) 1251 uids = [] 1252 for start, stop in sorted(ranges): 1253 uids.extend(b.getPath() for b in islice(devs, start, stop + 1)) 1254 return uids
1255
1256 - def loadComponentRanges(self, ranges, hashcheck, uid=None, types=(), 1257 meta_type=(), start=0, limit=None, sort='name', 1258 dir='ASC', name=None):
1259 """ 1260 Get a range of component uids. 1261 1262 @type ranges: [integer] 1263 @param ranges: List of two integers that are the min/max values of a 1264 range of uids 1265 @type hashcheck: string 1266 @param hashcheck: not used 1267 @type uid: string 1268 @param uid: (optional) Device to use to get uids (default: None) 1269 @type types: [string] 1270 @param types: (optional) The types of components to retrieve (default: None) 1271 @type meta_type: string 1272 @param meta_type: (optional) The meta type of the components to retrieve 1273 (default: None) 1274 @type start: integer 1275 @param start: (optional) Offset to return the results from; used in 1276 pagination (default: 0) 1277 @type limit: integer 1278 @param limit: (optional) Number of items to return; used in pagination 1279 (default: None) 1280 @type sort: string 1281 @param sort: (optional) Key on which to sort the return result (default: 1282 'name') 1283 @type dir: string 1284 @param dir: (optional) Sort order; can be either 'ASC' or 'DESC' 1285 (default: 'ASC') 1286 @type name: string 1287 @param name: (optional) Component name to search for when loading ranges 1288 (default: None) 1289 @rtype: [string] 1290 @return: A list of component uids 1291 """ 1292 if uid is None: 1293 uid = "/".join(self.context.getPhysicalPath()) 1294 facade = self._getFacade() 1295 comps = facade.getComponents(uid, types, meta_type, start, limit, sort, 1296 dir, name) 1297 uids = [] 1298 for start, stop in sorted(ranges): 1299 uids.extend(b.uid for b in islice(comps, start, stop)) 1300 return uids
1301 1302 @serviceConnectionError
1303 - def getUserCommands(self, uid):
1304 """ 1305 Get a list of user commands for a device uid. 1306 1307 @type uid: string 1308 @param uid: Device to use to get user commands 1309 @rtype: [dictionary] 1310 @return: List of objects representing user commands 1311 """ 1312 facade = self._getFacade() 1313 cmds = facade.getUserCommands(uid) 1314 return Zuul.marshal(cmds, ['id', 'description'])
1315
1316 - def getProductionStates(self, **kwargs):
1317 """ 1318 Get a list of available production states. 1319 1320 @rtype: [dictionary] 1321 @return: List of name/value pairs of available production states 1322 """ 1323 return DirectResponse(data=[dict(name=s.split(':')[0], 1324 value=int(s.split(':')[1])) for s in 1325 self.context.dmd.prodStateConversions])
1326
1327 - def getAllCredentialsProps(self, **kwargs):
1328 """ 1329 Get a list of available credentials props 1330 1331 @rtype: DirectResponse 1332 @return: List of credentials props 1333 """ 1334 props = self._getFacade().getAllCredentialsProps() 1335 # zSnmpCommunity is always on the form, don't include it 1336 return DirectResponse(data=[prop for prop in props if prop != 'zSnmpCommunity'])
1337
1338 - def getCredentialsProps(self, deviceClass):
1339 """ 1340 Get a dictionary of the creds props and default values for this device class 1341 1342 @rtype: DirectResponse 1343 @return: List of credentials props 1344 """ 1345 organizerUid = '/zport/dmd/Devices' + deviceClass 1346 try: 1347 connInfo = self._getFacade().getConnectionInfo(organizerUid) 1348 except ObjectNotFoundException as o: 1349 connInfo = {} 1350 1351 props = OrderedDict([(item['id'], item.get('valueAsString', '')) for item in connInfo]) 1352 if props.get('zSnmpCommunity'): 1353 del props['zSnmpCommunity'] # its always on the form 1354 return DirectResponse(data=props)
1355
1356 - def getPriorities(self, **kwargs):
1357 """ 1358 Get a list of available device priorities. 1359 1360 @rtype: [dictionary] 1361 @return: List of name/value pairs of available device priorities 1362 """ 1363 return DirectResponse(data=[dict(name=s.split(':')[0], 1364 value=int(s.split(':')[1])) for s in 1365 self.context.dmd.priorityConversions])
1366
1367 - def getCollectors(self):
1368 """ 1369 Get a list of available collectors. 1370 1371 @rtype: [string] 1372 @return: List of collectors 1373 """ 1374 return self.context.dmd.Monitors.getPerformanceMonitorNames()
1375
1376 - def getDeviceClassesToAdd(self, **data):
1377 """ 1378 Get a list of device classes that don't require special case add jobs 1379 1380 @rtype: DirectResponse 1381 @return: B{Properties}: 1382 - deviceClasses: ([dictionary]) List of device classes 1383 - totalCount: (integer) Total number of device classes 1384 """ 1385 facade = self._getFacade() 1386 deviceClasses = [''] 1387 deviceClasses.extend(facade.getDeviceClasses(allClasses=False)) 1388 result = [{'name': name} for name in deviceClasses] 1389 return DirectResponse(deviceClasses=result, totalCount=len(result))
1390
1391 - def getDeviceClasses(self, **data):
1392 """ 1393 Get a list of all device classes. 1394 1395 @rtype: DirectResponse 1396 @return: B{Properties}: 1397 - deviceClasses: ([dictionary]) List of device classes 1398 - totalCount: (integer) Total number of device classes 1399 """ 1400 facade = self._getFacade() 1401 deviceClasses = [''] 1402 deviceClasses.extend(facade.getDeviceClasses()) 1403 result = [{'name': name} for name in deviceClasses] 1404 return DirectResponse(deviceClasses=result, totalCount=len(result))
1405
1406 - def getSystems(self, **data):
1407 """ 1408 Get a list of all systems. 1409 1410 @rtype: DirectResponse 1411 @return: B{Properties}: 1412 - systems: ([dictionary]) List of systems 1413 - totalCount: (integer) Total number of systems 1414 """ 1415 systems = self.context.dmd.Systems.getOrganizerNames() 1416 result = [{'name': name} for name in systems if name != '/'] 1417 return DirectResponse(systems=result, totalCount=len(result))
1418
1419 - def getGroups(self, **data):
1420 """ 1421 Get a list of all groups. 1422 1423 @rtype: DirectResponse 1424 @return: B{Properties}: 1425 - systems: ([dictionary]) List of groups 1426 - totalCount: (integer) Total number of groups 1427 """ 1428 groups = self.context.dmd.Groups.getOrganizerNames() 1429 result = [{'name': name} for name in groups if name != '/'] 1430 return DirectResponse(groups=result, totalCount=len(result))
1431
1432 - def getLocations(self, **data):
1433 """ 1434 Get a list of all locations. 1435 1436 @rtype: DirectResponse 1437 @return: B{Properties}: 1438 - systems: ([dictionary]) List of locations 1439 - totalCount: (integer) Total number of locations 1440 """ 1441 locations = self.context.dmd.Locations.getOrganizerNames() 1442 result = [{'name': name} for name in locations if name != '/'] 1443 return DirectResponse(locations=result, totalCount=len(result))
1444
1445 - def getManufacturerNames(self, **data):
1446 """ 1447 Get a list of all manufacturer names. 1448 1449 @rtype: DirectResponse 1450 @return: B{Properties}: 1451 - manufacturers: ([dictionary]) List of manufacturer names 1452 - totalCount: (integer) Total number of manufacturer names 1453 """ 1454 names = self.context.dmd.Manufacturers.getManufacturerNames() 1455 result = [{'name': name} for name in names] 1456 return DirectResponse(manufacturers=result, totalCount=len(result))
1457
1458 - def getHardwareProductNames(self, manufacturer='', **data):
1459 """ 1460 Get a list of all hardware product names from a manufacturer. 1461 1462 @type manufacturer: string 1463 @param manufacturer: Manufacturer name 1464 @rtype: DirectResponse 1465 @return: B{Properties}: 1466 - productNames: ([dictionary]) List of hardware product names 1467 - totalCount: (integer) Total number of hardware product names 1468 """ 1469 manufacturers = self.context.dmd.Manufacturers 1470 names = manufacturers.getProductNames(manufacturer, 'HardwareClass') 1471 result = [{'name': name} for name in names] 1472 return DirectResponse(productNames=result, totalCount=len(result))
1473
1474 - def getOSProductNames(self, manufacturer='', **data):
1475 """ 1476 Get a list of all OS product names from a manufacturer. 1477 1478 @type manufacturer: string 1479 @param manufacturer: Manufacturer name 1480 @rtype: DirectResponse 1481 @return: B{Properties}: 1482 - productNames: ([dictionary]) List of OS product names 1483 - totalCount: (integer) Total number of OS product names 1484 """ 1485 manufacturers = self.context.dmd.Manufacturers 1486 names = manufacturers.getProductNames(manufacturer, 'OS') 1487 result = [{'name': name} for name in names] 1488 return DirectResponse(productNames=result, totalCount=len(result))
1489
1490 - def addDevice(self, deviceName, deviceClass, title=None, 1491 snmpCommunity="", snmpPort=161, manageIp="", 1492 model=False, collector='localhost', rackSlot=0, 1493 locationPath="", systemPaths=[], groupPaths=[], 1494 productionState=1000, comments="", hwManufacturer="", 1495 hwProductName="", osManufacturer="", osProductName="", 1496 priority=3, tag="", serialNumber="", zCommandUsername="", 1497 zCommandPassword="", zWinUser="", zWinPassword="", 1498 zProperties={}, cProperties={},):
1499 1500 """ 1501 Add a device. 1502 1503 @type deviceName: string 1504 @param deviceName: Name or IP of the new device 1505 @type deviceClass: string 1506 @param deviceClass: The device class to add new device to 1507 @type title: string 1508 @param title: (optional) The title of the new device (default: '') 1509 @type snmpCommunity: string 1510 @param snmpCommunity: (optional) A specific community string to use for 1511 this device. (default: '') 1512 @type snmpPort: integer 1513 @param snmpPort: (optional) SNMP port on new device (default: 161) 1514 @type manageIp: string 1515 @param manageIp: (optional) Management IP address on new device (default: 1516 empty/derive from DNS) 1517 @type locationPath: string 1518 @param locationPath: (optional) Organizer path of the location for this device 1519 @type systemPaths: List (strings) 1520 @param systemPaths: (optional) List of organizer paths for the device 1521 @type groupPaths: List (strings) 1522 @param groupPaths: (optional) List of organizer paths for the device 1523 @type model: boolean 1524 @param model: (optional) True to model device at add time (default: False) 1525 @type collector: string 1526 @param collector: (optional) Collector to use for new device (default: 1527 localhost) 1528 @type rackSlot: string 1529 @param rackSlot: (optional) Rack slot description (default: '') 1530 @type productionState: integer 1531 @param productionState: (optional) Production state of the new device 1532 (default: 1000) 1533 @type comments: string 1534 @param comments: (optional) Comments on this device (default: '') 1535 @type hwManufacturer: string 1536 @param hwManufacturer: (optional) Hardware manufacturer name (default: '') 1537 @type hwProductName: string 1538 @param hwProductName: (optional) Hardware product name (default: '') 1539 @type osManufacturer: string 1540 @param osManufacturer: (optional) OS manufacturer name (default: '') 1541 @type osProductName: string 1542 @param osProductName: (optional) OS product name (default: '') 1543 @type priority: integer 1544 @param priority: (optional) Priority of this device (default: 3) 1545 @type tag: string 1546 @param tag: (optional) Tag number of this device (default: '') 1547 @type serialNumber: string 1548 @param serialNumber: (optional) Serial number of this device (default: '') 1549 @type zCommandUsername: string 1550 @param zWinUser: (optional) Username for WMI (default: '') 1551 @type zCommandPassword: string 1552 @param zWinPassword: (optional) Password for WMI (default: '') 1553 @rtype: DirectResponse 1554 @return: B{Properties}: 1555 - jobId: (string) ID of the add device job 1556 """ 1557 # check for permission in the device organizer to which we are 1558 # adding the device 1559 facade = self._getFacade() 1560 organizerUid = '/zport/dmd/Devices' + deviceClass 1561 organizer = facade._getObject(organizerUid) 1562 if not Zuul.checkPermission("Manage Device", organizer): 1563 raise Unauthorized('Calling AddDevice requires ' + 1564 'Manage Device permission on %s' % deviceClass) 1565 1566 if title is None: 1567 title = deviceName 1568 1569 # the device name is used as part of the URL, so any unicode characters 1570 # will be stripped before saving. Preempt this and make the device name 1571 # safe prior to the uniqueness check. 1572 safeDeviceName = organizer.prepId(deviceName) 1573 1574 deviceByIp = facade.getDeviceByIpAddress(safeDeviceName, collector, manageIp) 1575 deviceByName = facade.getDeviceByName(safeDeviceName) 1576 if deviceByIp and organizer.getZ('zUsesManageIp', True) \ 1577 or deviceByName and deviceClass == deviceByName.getDeviceClassName(): 1578 primaryId = deviceByName.getPrimaryId() if deviceByName.getDeviceClassName() == deviceClass else deviceByIp.getPrimaryId() 1579 return DirectResponse.fail(deviceUid=primaryId, 1580 msg="Device %s already exists. <a href='%s'>Go to the device</a>" % (deviceName, primaryId)) 1581 1582 if isinstance(systemPaths, basestring): 1583 systemPaths = [systemPaths] 1584 if isinstance(groupPaths, basestring): 1585 groupPaths = [groupPaths] 1586 1587 jobrecords = self._getFacade().addDevice(deviceName, 1588 deviceClass, 1589 title, 1590 snmpCommunity, 1591 snmpPort, 1592 manageIp, 1593 model, 1594 collector, 1595 rackSlot, 1596 productionState, 1597 comments, 1598 hwManufacturer, 1599 hwProductName, 1600 osManufacturer, 1601 osProductName, 1602 priority, 1603 tag, 1604 serialNumber, 1605 locationPath, 1606 zCommandUsername, 1607 zCommandPassword, 1608 zWinUser, 1609 zWinPassword, 1610 systemPaths, 1611 groupPaths, 1612 zProperties, 1613 cProperties, 1614 ) 1615 1616 deviceUid = '/'.join([organizerUid, 'devices', deviceName]) 1617 # Zero groups or systems sends as [''] so exclude that case. 1618 hasGroups = len(groupPaths) > 1 or (groupPaths and groupPaths[0]) 1619 hasSystems = len(systemPaths) > 1 or (systemPaths and systemPaths[0]) 1620 auditData = { 1621 'deviceClass': '/Devices' + deviceClass, 1622 'location': '/Locations' + locationPath if locationPath else None, 1623 'deviceGroups': ['/Groups' + x for x in groupPaths] if hasGroups else None, 1624 'systems': ['/Systems' + x for x in systemPaths] if hasSystems else None, 1625 'device_name': title if title else deviceName, # see Trac #30109 1626 'collector': collector, 1627 'model': str(model), # show value even if False 1628 'productionState': self.context.convertProdState(productionState), 1629 'priority': self.context.convertPriority(priority), 1630 } 1631 audit('UI.Device.Add', deviceUid, data_=auditData) 1632 return DirectResponse.succeed(new_jobs=Zuul.marshal(jobrecords, keys=('uuid', 'description')))
1633 1634 @require('Manage Device')
1635 - def remodel(self, deviceUid, collectPlugins='', background=True):
1636 """ 1637 Submit a job to have a device remodeled. 1638 1639 @type deviceUid: string 1640 @param deviceUid: Device uid to have local template 1641 @type collectPlugins: string 1642 @param collectPlugins: (optional) Modeler plugins to use. 1643 Takes a regular expression (default: '') 1644 @type background: boolean 1645 @param background: (optional) False to not schedule a job 1646 (default: True) 1647 @rtype: DirectResponse 1648 @return: B{Properties}: 1649 - status: (string) ID of the add device job or command exit status 1650 """ 1651 status = self._getFacade().remodel(deviceUid, collectPlugins=collectPlugins, background=background) 1652 audit('UI.Device.Remodel', deviceUid) 1653 if background: 1654 response = DirectResponse.succeed(jobId=status.id) 1655 else: 1656 #returned value is exit status of a command 1657 #if command end up successfully None is returned 1658 #make from None a zero value to make it clear 1659 status = status or 0 1660 response = DirectResponse.succeed(exitStatus=status) 1661 return response
1662 1663 @require('Edit Local Templates')
1664 - def addLocalTemplate(self, deviceUid, templateId):
1665 """ 1666 Adds a local template on a device. 1667 1668 @type deviceUid: string 1669 @param deviceUid: Device uid to have local template 1670 @type templateId: string 1671 @param templateId: Name of the new template 1672 @rtype: DirectResponse 1673 @return: Success message 1674 """ 1675 facade = self._getFacade() 1676 facade.addLocalTemplate(deviceUid, templateId) 1677 audit('UI.Device.AddLocalTemplate', deviceUid, template=templateId) 1678 return DirectResponse.succeed()
1679 1680 @require('Edit Local Templates')
1681 - def removeLocalTemplate(self, deviceUid, templateUid):
1682 """ 1683 Removes a locally defined template on a device. 1684 1685 @type deviceUid: string 1686 @param deviceUid: Device uid that has local template 1687 @type templateUid: string 1688 @param templateUid: Name of the template to remove 1689 @rtype: DirectResponse 1690 @return: Success message 1691 """ 1692 facade = self._getFacade() 1693 facade.removeLocalTemplate(deviceUid, templateUid) 1694 audit('UI.Device.RemoveLocalTemplate', deviceUid, template=templateUid) 1695 return DirectResponse.succeed()
1696
1697 - def getLocalTemplates(self, query, uid):
1698 """ 1699 Get a list of locally defined templates on a device. 1700 1701 @type query: string 1702 @param query: not used 1703 @type uid: string 1704 @param uid: Device uid to query for templates 1705 @rtype: DirectResponse 1706 @return: B{Properties}: 1707 - data: ([dictionary]) List of objects representing local templates 1708 """ 1709 facade = self._getFacade() 1710 templates = facade.getLocalTemplates(uid) 1711 data = [] 1712 for template in templates: 1713 data.append(dict(label=template['text'], uid=template['uid'])) 1714 return DirectResponse.succeed(data=data)
1715 1716 @serviceConnectionError
1717 - def getTemplates(self, id):
1718 """ 1719 Get a list of available templates for a device. 1720 1721 @type id: string 1722 @param id: Device uid to query for templates 1723 @rtype: DirectResponse 1724 @return: B{Properties}: 1725 - data: ([dictionary]) List of objects representing templates 1726 """ 1727 facade = self._getFacade() 1728 templates = facade.getTemplates(id) 1729 return Zuul.marshal(templates)
1730 1731 @serviceConnectionError
1732 - def getUnboundTemplates(self, uid):
1733 """ 1734 Get a list of unbound templates for a device. 1735 1736 @type uid: string 1737 @param uid: Device uid to query for templates 1738 @rtype: DirectResponse 1739 @return: B{Properties}: 1740 - data: ([dictionary]) List of objects representing templates 1741 """ 1742 facade = self._getFacade() 1743 templates = facade.getUnboundTemplates(uid) 1744 data = [] 1745 for template in templates: 1746 label = '%s (%s)' % (template.titleOrId(), template.getUIPath()) 1747 data.append([template.id, label]) 1748 return DirectResponse.succeed(data=Zuul.marshal(data))
1749 1750 @serviceConnectionError
1751 - def getBoundTemplates(self, uid):
1752 """ 1753 Get a list of bound templates for a device. 1754 1755 @type uid: string 1756 @param uid: Device uid to query for templates 1757 @rtype: DirectResponse 1758 @return: B{Properties}: 1759 - data: ([dictionary]) List of objects representing templates 1760 """ 1761 facade = self._getFacade() 1762 templates = facade.getBoundTemplates(uid) 1763 data = [] 1764 for template in templates: 1765 label = '%s (%s)' % (template.titleOrId(), template.getUIPath()) 1766 data.append([template.id, label]) 1767 return DirectResponse.succeed(data=Zuul.marshal(data))
1768 1769 @require('Edit Local Templates')
1770 - def setBoundTemplates(self, uid, templateIds):
1771 """ 1772 Set a list of templates as bound to a device. 1773 1774 @type uid: string 1775 @param uid: Device uid to bind templates to 1776 @type templateIds: [string] 1777 @param templateIds: List of template uids to bind to device 1778 @rtype: DirectResponse 1779 @return: Success message 1780 """ 1781 facade = self._getFacade() 1782 try: 1783 old_templateIds = [t.id for t in facade.getBoundTemplates(uid)] 1784 facade.setBoundTemplates(uid, templateIds) 1785 except DatapointNameConfict, e: 1786 log.info("Failed to bind templates for {}: {}".format(uid, e)) 1787 return DirectResponse.exception(e, 'Failed to bind templates.') 1788 audit('UI.Device.BindTemplates', uid,new_bound_templates=templateIds, old_bound_templates=old_templateIds ) 1789 return DirectResponse.succeed()
1790 1791 @require('Edit Local Templates')
1792 - def resetBoundTemplates(self, uid):
1793 """ 1794 Remove all bound templates from a device. 1795 1796 @type uid: string 1797 @param uid: Device uid to remove bound templates from 1798 @rtype: DirectResponse 1799 @return: Success message 1800 """ 1801 facade = self._getFacade() 1802 facade.resetBoundTemplates(uid) 1803 audit('UI.Device.ResetBoundTemplates', uid) 1804 return DirectResponse.succeed()
1805 1806 @require('Edit Local Templates')
1807 - def bindOrUnbindTemplate(self, uid, templateUid):
1808 """ 1809 Bind an unbound template or unbind a bound template from a device. 1810 1811 @type uid: string 1812 @param uid: Device uid to bind/unbind template 1813 @type templateUid: string 1814 @param templateUid: Template uid to bind/unbind 1815 @rtype: DirectResponse 1816 @return: Success message 1817 """ 1818 facade = self._getFacade() 1819 template = facade._getObject(templateUid) 1820 templateIds = [t.id for t in facade.getBoundTemplates(uid)] 1821 # not bound 1822 if not template.id in templateIds: 1823 self.setBoundTemplates(uid, templateIds + [template.id]) 1824 audit('UI.Device.BindTemplate', uid, template=templateUid) 1825 else: 1826 # already bound so unbind it 1827 templateIds = [t for t in templateIds if t != template.id] 1828 self.setBoundTemplates(uid, templateIds) 1829 audit('UI.Device.UnbindTemplate', uid, template=templateUid) 1830 return DirectResponse.succeed()
1831
1832 - def getOverridableTemplates(self, query, uid):
1833 """ 1834 Get a list of available templates on a device that can be overridden. 1835 1836 @type query: string 1837 @param query: not used 1838 @type uid: string 1839 @param uid: Device to query for overridable templates 1840 @rtype: DirectResponse 1841 @return: B{Properties}: 1842 - data: ([dictionary]) List of objects representing templates 1843 """ 1844 facade = self._getFacade() 1845 templates = facade.getOverridableTemplates(uid) 1846 # we just need the text and the id (for our combobox) 1847 data = [] 1848 for template in templates: 1849 label = '%s (%s)' % (template.text, template.getUIPath()) 1850 data.append(dict(label=label, uid=template.uid)) 1851 return DirectResponse.succeed(data=data)
1852 1853 @require('Manage DMD')
1854 - def clearGeocodeCache(self):
1855 """ 1856 Clear the Google Maps geocode cache. 1857 1858 @rtype: DirectResponse 1859 @return: Success message 1860 """ 1861 facade = self._getFacade() 1862 facade.clearGeocodeCache() 1863 audit('UI.GeocodeCache.Clear') 1864 return DirectResponse.succeed()
1865
1866 - def getConnectionInfo(self, uid):
1867 """ 1868 Returns the zproperty information about those zproperties which comprise 1869 the credentials 1870 @rtype: List of Dictionaries 1871 @return: B{Properties}: 1872 - path: (string) where the property is defined 1873 - type: (string) type of zproperty it is 1874 - options: (Array) available options for the zproperty 1875 - value (Array) value of the zproperty 1876 - valueAsString (string) 1877 """ 1878 facade = self._getFacade() 1879 data = facade.getConnectionInfo(uid) 1880 return DirectResponse.succeed(data=Zuul.marshal(data))
1881 1882 @serviceConnectionError
1883 - def getModelerPluginDocStrings(self, uid):
1884 """ 1885 Given a uid returns the documentation for all the modeler plugins. 1886 """ 1887 facade = self._getFacade() 1888 data = facade.getModelerPluginDocStrings(uid) 1889 return DirectResponse.succeed(data=Zuul.marshal(data))
1890
1891 - def addIpRouteEntry(self, uid, dest='', routemask='', nexthopid='', interface='', 1892 routeproto='', routetype='', userCreated=True):
1893 """ 1894 Adds an Ip Route Entry to this device 1895 """ 1896 facade = self._getFacade() 1897 data = facade.addIpRouteEntry(uid, dest, routemask, nexthopid, interface, 1898 routeproto, routetype, userCreated) 1899 return DirectResponse.succeed(data=Zuul.marshal(data))
1900
1901 - def addIpInterface(self, uid, newId, userCreated=True):
1902 """ 1903 Adds an Ip Interface 1904 """ 1905 facade = self._getFacade() 1906 data = facade.addIpInterface(uid, newId, userCreated) 1907 return DirectResponse.succeed(data=Zuul.marshal(data))
1908
1909 - def addOSProcess(self, uid, newClassName, example, userCreated=True):
1910 """ 1911 Adds an os processes 1912 """ 1913 facade = self._getFacade() 1914 data = facade.addOSProcess(uid, newClassName, example, userCreated) 1915 return DirectResponse.succeed(data=Zuul.marshal(data))
1916
1917 - def addFileSystem(self, uid, newId, userCreated=True):
1918 """ 1919 Adds an Ip Interface 1920 """ 1921 facade = self._getFacade() 1922 data = facade.addFileSystem(uid, newId, userCreated) 1923 return DirectResponse.succeed(data=Zuul.marshal(data))
1924
1925 - def addIpService(self, uid, newClassName, protocol, userCreated=True):
1926 """ 1927 Adds an Ip Service 1928 """ 1929 facade = self._getFacade() 1930 data = facade.addIpService(uid, newClassName, protocol, userCreated) 1931 return DirectResponse.succeed(data=Zuul.marshal(data))
1932 1933
1934 - def addWinService(self, uid, newClassName, userCreated=True):
1935 """ 1936 Adds an Ip Service 1937 """ 1938 facade = self._getFacade() 1939 data = facade.addWinService(uid, newClassName, userCreated) 1940 return DirectResponse.succeed(data=Zuul.marshal(data))
1941
1942 - def getSoftware(self, uid, keys=None):
1943 1944 facade = self._getFacade() 1945 software = facade.getSoftware(uid) 1946 return DirectResponse(data=Zuul.marshal(software, keys))
1947
1948 - def getOverriddenObjectsList(self, uid, propname, relName):
1949 """ 1950 returns a list of Overridden Objects and properties for this context 1951 """ 1952 facade = self._getFacade() 1953 data = facade.getOverriddenObjectsList(uid, propname, relName) 1954 return DirectResponse.succeed(data=Zuul.marshal(data))
1955
1956 - def getOverriddenObjectsParent(self, uid, propname=''):
1957 """ 1958 returns the base of the Overridden Objects 1959 """ 1960 facade = self._getFacade() 1961 data = facade.getOverriddenObjectsParent(uid, propname) 1962 return DirectResponse.succeed(data=Zuul.marshal(data))
1963
1964 - def getOverriddenZprops(self, uid, all=True, pfilt=''):
1965 """ 1966 returns a list of zProperty values for the overridden objects 1967 """ 1968 facade = self._getFacade() 1969 data = facade.getOverriddenZprops(uid, all) 1970 return DirectResponse.succeed(data=Zuul.marshal(data))
1971
1972 - def getGraphDefintionsForComponents(self, uid):
1973 facade = self._getFacade() 1974 data = facade.getGraphDefinitionsForComponent(uid) 1975 return DirectResponse.succeed(data=Zuul.marshal(data))
1976
1977 - def getComponentGraphs(self, uid, meta_type, graphId, allOnSame=False):
1978 """ 1979 Returns the graph denoted by graphId for every component in 1980 device (uid) with the meta_type meta_type 1981 """ 1982 facade = self._getFacade() 1983 data = facade.getComponentGraphs(uid, meta_type, graphId, allOnSame=allOnSame) 1984 return DirectResponse.succeed(data=Zuul.marshal(data))
1985
1986 - def getDevTypes(self, uid, filter=None):
1987 """ 1988 Returns a list of devtypes for the wizard 1989 """ 1990 facade = self._getFacade() 1991 data = facade.getDevTypes(uid) 1992 return DirectResponse.succeed(data=Zuul.marshal(data))
1993