Coverage for src/zenossapi/routers/device.py: 79%
519 statements
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-25 05:47 +0000
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-25 05:47 +0000
1# -*- coding: utf-8 -*-
3"""
4Zenoss device_router
5"""
7import re
8import warnings
9from zenossapi.apiclient import ZenossAPIClientError
10from zenossapi.routers import ZenossRouter
11from zenossapi.routers.properties import PropertiesRouter
12from zenossapi.routers.template import TemplateRouter
15class DeviceRouter(ZenossRouter):
16 """
17 Class for interacting with the Zenoss device router
18 """
20 def __init__(self, url, headers, ssl_verify):
21 super(DeviceRouter, self).__init__(url, headers, ssl_verify,
22 'device_router', 'DeviceRouter')
23 self.uid = None
24 self.properties = None
25 self.prod_states_by_value = {}
26 self.prod_states_by_name = {}
27 self.priorities_by_value = {}
28 self.priorities_by_name = {}
30 prod_states_data = self._router_request(
31 self._make_request_data(
32 'getProductionStates',
33 dict(),
34 )
35 )
36 for state in prod_states_data['data']:
37 self.prod_states_by_name[state['name']] = state['value']
38 self.prod_states_by_value[state['value']] = state['name']
40 priority_data = self._router_request(
41 self._make_request_data(
42 'getPriorities',
43 dict(),
44 )
45 )
46 for p in priority_data['data']:
47 self.priorities_by_name[p['name']] = p['value']
48 self.priorities_by_value[p['value']] = p['name']
50 def __repr__(self):
51 if self.uid:
52 identifier = self.uid
53 else:
54 identifier = hex(id(self))
56 return '<{0} object at {1}>'.format(
57 type(self).__name__, identifier
58 )
60 def object_exists(self, uid):
62 object_data = self._router_request(
63 self._make_request_data(
64 'objectExists',
65 dict(uid=uid)
66 )
67 )
69 return object_data['exists']
71 def add_node(self, type, contextUid, id, description=""):
72 """
73 Adds a node to the node tree
74 Args:
75 type: Class, Group or System
76 contextUid: The existing node to add the new node to
77 id: name of the node
78 description: optional description
80 Returns: (bool) success
82 """
83 group_data = self._router_request(
84 self._make_request_data(
85 'addNode',
86 dict(type=type,
87 contextUid=contextUid,
88 id=id,
89 description=description)
90 )
91 )
93 return group_data['success']
95 def add_location(self, id, contextUid='zport/dmd/Locations', address="", description=""):
96 """
97 Adds a node to the location tree
98 Args:
99 contextUid: The existing node to add the new node to, defaults to root
100 id: name of the node
101 address: optional physical address
102 description: optional description
104 Returns: (bool) success
106 """
107 group_data = self._router_request(
108 self._make_request_data(
109 'addLocationNode',
110 dict(type='Location',
111 contextUid=contextUid,
112 id=id,
113 address=address,
114 description=description)
115 )
116 )
118 return group_data['success']
120 def delete_node(self, uid):
121 """
122 Removes a node from the node tree
123 Args:
124 uid: (str) UID of node to delte from tree
126 Returns: (bool) success
128 """
129 group_data = self._router_request(
130 self._make_request_data(
131 'deleteNode',
132 dict(uid=uid)
133 )
134 )
136 return group_data['success']
138 def get_device_uids(self, uid):
140 uid_data = self._router_request(
141 self._make_request_data(
142 'getDeviceUids',
143 dict(uid=uid)
144 )
145 )
147 uid_list = dict(
148 total=len(uid_data['devices']),
149 uids=uid_data['devices']
150 )
152 return uid_list
154 def list_devices(self, uid=None, params=None, start=0, limit=50, sort='name',
155 dir='ASC'):
156 """
157 Get the devices contained in a device class. Supports pagination.
159 Arguments:
160 uid (str): The uid of the organizer to get devices from
161 params (dict): Key/value filters for the search, options are
162 name, ipAddress, deviceClass, or productionState
163 start (int): Offset to start device list from, default 0
164 limit (int): The number of results to return, default 50
165 sort (str): Sort key for the list, default is 'name'
166 dir (str): Sort order, either 'ASC' or 'DESC', default is 'ASC'
168 Returns:
169 dict(int, str, list(ZenossDevice)): ::
171 {
172 'total': Total number of devices found
173 'hash': Hashcheck to determine if any devices have changed,
174 'devices': ZenossDevice objects,
175 }
177 """
178 device_data = self._router_request(
179 self._make_request_data(
180 'getDevices',
181 dict(
182 uid=uid,
183 params=params,
184 start=start,
185 limit=limit,
186 sort=sort,
187 dir=dir,
188 )
189 )
190 )
192 device_list = dict(
193 total=device_data['totalCount'],
194 hash=device_data['hash'],
195 devices=[]
196 )
197 for device in device_data['devices']:
198 device_list['devices'].append(self.get_device_by_uid(
199 device['uid'].replace('/zport/dmd/', '', 1)))
201 return device_list
203 def _find_nodes_in_tree(self, tree_data):
204 """
205 Works through the dict structure returned by the Zenoss API for
206 a device class tree and returns the nodes.
208 Laving private along with _climb_tree as tree traversal can be hazardous.
210 Arguments:
211 tree_data (dict): Templates data returned by the API
213 Returns:
214 list:
215 """
216 tree = []
217 for node in tree_data['children']:
218 node_children = self._find_nodes_in_tree(node)
219 tree.append(
220 dict(
221 uid=node['path'],
222 children=node_children
223 )
224 )
226 return tree
228 def _climb_tree(self, tree_data, include_details, _root_path=True):
229 """
230 A more advanced version of _find_nodes_in_tree that will return
231 a dictionary-only structure instead of the mixed dict/list structure
232 of the original. Also includes the otion to include details about each branch.
234 Args:
235 tree_data (dict): The tree returned by the API call
236 include_details (bool): If True returns all details from the getTree API call
237 If false only includes the structure of dictionaries
238 _root_path (bool): Used as a control within the function to avoid writing
239 duplicate data. Probably a more elegant way to do this.
241 Returns:
242 dict: Dict of the tree structure
244 """
245 if include_details is True:
246 tree = dict(count=tree_data['text']['count'],
247 uid=tree_data['uid'],
248 id=tree_data['id'],
249 path=tree_data['path'],
250 uuid=tree_data['uuid']
251 )
252 else:
253 tree = {}
254 for node in tree_data['children']:
255 node_children = self._climb_tree(node, include_details, _root_path=False)
256 if include_details is False:
257 tree[node['path']] = node_children
258 else:
259 tree[node['path']] = dict(node_children,
260 count=node['text']['count'],
261 uid=node['uid'],
262 id=node['id'],
263 path=node['path'],
264 uuid=node['uuid']
265 )
266 if _root_path is True:
267 tree = {tree_data['path']: tree}
268 return tree
270 def get_info_by_uid(self, uid):
271 """
272 Get object properties by the full UID
274 Arguments:
275 uid (str): UID for the object
277 Returns:
278 dict:
279 """
280 return self._router_request(
281 self._make_request_data(
282 'getInfo',
283 dict(uid=uid),
284 )
285 )
287 def get_device_by_uid(self, device_uid):
288 """
289 Get a device by its full UID
291 Arguments:
292 device_uid (str): The uid of the device to get
294 Returns:
295 ZenossDevice:
296 """
297 device_data = self.get_info_by_uid(device_uid)
299 return ZenossDevice(
300 self.api_url,
301 self.api_headers,
302 self.ssl_verify,
303 device_data['data']
304 )
306 def get_device_by_name(self, device_name):
307 """
308 Get a device by its name
310 Arguments:
311 device_name (str): Name of the device to get
313 Returns:
314 ZenossDevice:
315 """
316 device_uid = self.get_device_uid_by_name(device_name)
317 if device_uid is None:
318 return None
319 return self.get_device_by_uid(device_uid)
321 def list_devices_by_uid(self, uid, keys=None, **kwargs):
322 """
323 Returns a list of all devices under a specified UID.
324 UID could be a device class, group, system, location, etc.
325 Args:
326 uid: (str) Device organizer to list devices under
327 keys: (list) List of keys to return in results, otherwise returns all
328 **kwargs: Additional optional arguments (sort, start, limit, params, page, dir)
330 Returns: (list) List of all devices in the group organizer and its properties
332 """
333 if not keys:
334 keys = [
335 'name',
336 'uid',
337 'ipAddressString',
338 'collector',
339 'productionState',
340 'priority',
341 'location',
342 'groups',
343 'events'
344 ]
346 device_data = self._router_request(
347 self._make_request_data(
348 'getDevices',
349 dict(
350 uid=uid,
351 **kwargs
352 )
353 )
354 )
356 device_list = dict(
357 total=device_data['totalCount'],
358 hash=device_data['hash'],
359 devices=[],
360 )
361 for device in device_data['devices']:
362 devinfo = dict()
363 for key in keys:
364 if key == "uid":
365 devinfo['uid'] = device['uid'].replace('/zport/dmd/', '', 1)
366 elif key == "location":
367 if device['location']:
368 devinfo['location'] = device['location']['name']
369 else:
370 devinfo['location'] = None
371 else:
372 devinfo[key] = device[key]
373 device_list['devices'].append(devinfo)
375 return device_list
377 def get_device_uid_by_name(self, device_name):
378 """
379 Get the UID for a device by its name
381 Arguments:
382 device_name (str): Name of the device to get the UID for
384 Returns:
385 str: UID for the device
386 """
387 device_data = self._router_request(
388 self._make_request_data(
389 'getDevices',
390 dict(
391 params={'name': device_name},
392 keys=['uid']
393 )
394 )
395 )
397 if len(device_data['devices']) == 0:
398 return None
399 return device_data['devices'][0]['uid']
401 def move_devices_by_uid(self, devices, device_class):
402 """
403 Move the devices in the list to a new device class.
405 Arguments:
406 devices (list): List of device uids to move
407 device_class (str): Target device class for the move
409 Returns:
410 list(dict(str, str)): List of Job manager info for each device move ::
412 [{
413 'uuid': Job manager uuid for the device move,
414 'description': Description of the move job,
415 }]
417 """
418 if not isinstance(devices, list):
419 raise ZenossAPIClientError(
420 'Type error: devices to move must be a list')
422 move_job_data = self._router_request(
423 self._make_request_data(
424 'moveDevices',
425 dict(
426 uids=devices,
427 target=device_class,
428 ),
429 )
430 )
431 move_jobs = []
432 for mj in move_job_data['new_jobs']:
433 move_jobs.append(dict(
434 uuid=mj['uuid'],
435 description=mj['description']
436 ))
438 return move_jobs
440 def add_device_class(self, new_class, parent,
441 description='', connection_info=None):
442 """
443 Add a new device class under a parent path
445 Arguments:
446 new_class (str): Name of the device class to add
447 parent (str): Device class to place the new class under
448 description (str): Description for the new class
449 connection_info (list): zProperties that are the credentials for
450 accessing this device class, e.g. zCommandUsername,
451 zCommandPassword
453 Returns:
454 ZenossDeviceClass:
455 """
456 response_data = self._router_request(
457 self._make_request_data(
458 'addDeviceClassNode',
459 dict(
460 type='organizer',
461 contextUid=parent,
462 id=new_class,
463 description=description,
464 connectionInfo=connection_info,
465 )
466 )
467 )
469 dc_data = self.get_info_by_uid(response_data['nodeConfig']['path'])
470 return ZenossDeviceClass(
471 self.api_url,
472 self.api_headers,
473 self.ssl_verify,
474 dc_data['data']
475 )
477 def lock_devices_by_uid(self, devices, updates=False, deletion=False,
478 send_event=False):
479 """
480 Lock devices from changes.
482 Arguments:
483 devices (list): Uids of the devices to lock
484 updates (bool): Lock devices from updates
485 deletion (bool): Lock devices from deletion
486 send_event (bool): Send an event when an action is blocked by locking
488 Returns:
489 str: Response message
490 """
491 response_data = self._router_request(
492 self._make_request_data(
493 'lockDevices',
494 dict(
495 uids=devices,
496 hashcheck='',
497 updates=updates,
498 deletion=deletion,
499 sendEvent=send_event,
500 )
501 )
502 )
504 return response_data['msg']
506 def reset_device_ip_addresses_by_uid(self, devices, ip_address=''):
507 """
508 Reset IP addresses of devices, either by DNS lookup or manually
509 specified address
511 Arguments:
512 devices (list): Uids of devices to reset IP address for
513 ip_address (str): IP address to set device to
514 """
515 response_data = self._router_request(
516 self._make_request_data(
517 'resetIp',
518 dict(
519 uids=devices,
520 hashcheck='',
521 ip=ip_address,
522 )
523 )
524 )
526 return response_data['msg']
528 def set_production_state_by_uids(self, devices, production_state):
529 """
530 Sets the production state of a list of devices.
532 Arguments:
533 devices (list): Uids of devices to set production state for
534 production_state (int): Numeric value of production state to set
536 Returns:
537 str: Response message
538 """
539 if production_state not in self.prod_states_by_value:
540 raise ZenossAPIClientError(
541 'Production state {0} is not a valid option'.format(
542 production_state))
544 response_data = self._router_request(
545 self._make_request_data(
546 'setProductionState',
547 dict(
548 uids=devices,
549 hashcheck='',
550 prodState=production_state,
551 )
552 )
553 )
555 return response_data['msg']
557 def set_priority_by_uids(self, devices, priority):
558 """
559 Sets the priority of a list of devices
561 Arguments:
562 devices (list): Uids of devices to set priority for
563 priority (int): Numeric value of priority to set
565 Returns:
566 str: Response message
567 """
568 if priority not in self.priorities_by_value:
569 raise ZenossAPIClientError(
570 "Priority {0} is not a valid option".format(
571 priority
572 )
573 )
575 response_data = self._router_request(
576 self._make_request_data(
577 'setPriority',
578 dict(
579 uids=devices,
580 hashcheck='',
581 priority=priority,
582 )
583 )
584 )
586 return response_data['msg']
588 def set_collector_by_uids(self, devices, collector):
589 """
590 Sets the collector for a list of devices.
592 Arguments:
593 devices (list): Uids of the devices to set collector for
594 collector (str): The collector to set devices to use
596 Returns:
597 list(dict(str, str)): List of Job manager info for each device move ::
599 [{
600 'uuid': Job manager uuid for the device move
601 'description': Description of the move job
602 }]
604 """
605 collector_job_data = self._router_request(
606 self._make_request_data(
607 'setCollector',
608 dict(
609 uids=devices,
610 hashcheck='',
611 collector=collector,
612 )
613 )
614 )
616 return dict(
617 uuid=collector_job_data['new_jobs']['uuid'],
618 description=collector_job_data['new_jobs']['description']
619 )
621 def delete_devices_by_uid(self, devices, action, del_events=False,
622 del_perf=False, **kwargs):
623 """
624 Remove a list of devices from their organizer UID, or delete them
625 from Zenoss altogether.
627 Arguments:
628 devices (list): Uids of devices to remove/delete
629 action (str): 'remove' to remove the devices from their organizer(see 'uid' below),
630 'delete' to delete them from Zenoss
631 del_events (bool): Remove all events for the devices
632 del_perf (bool): Remove all perf data for the devices
634 Optional Arguments:
635 uid (str): If using the 'remove' action this option must be included and should be the uid of the organizer you wish to remove the device from. ie "/zport/dmd/Groups/SOMEGROUP"
637 Returns:
638 dict:
639 """
640 if action not in ['remove', 'delete']:
641 raise ZenossAPIClientError(
642 "Delete action must be either 'remove' or 'delete'"
643 )
645 response_data = self._router_request(
646 self._make_request_data(
647 'removeDevices',
648 dict(
649 uids=devices,
650 hashcheck='',
651 action=action,
652 deleteEvents=del_events,
653 deletePerf=del_perf,
654 **kwargs
655 )
656 ),
657 response_timeout=30
658 )
660 return response_data
662 def _set_components_monitored_by_uids(self, components, monitor=True):
663 """
664 Sets the monitored state for a list of components.
666 Leaving component methods private for now as manipulating components by uid directly is
667 cumbersome and likely better achieved using the object methods that reference them.
669 Arguments:
670 components (list): Uids of the components to update
671 monitor (bool): True to monitor, False to stop monitoring
673 Returns:
674 str: Response message
675 """
676 response_data = self._router_request(
677 self._make_request_data(
678 'setComponentsMonitored',
679 dict(
680 uids=components,
681 hashcheck='',
682 monitor=monitor,
683 )
684 )
685 )
687 return response_data['msg']
689 def _lock_components_by_uid(self, components, updates=False, deletion=False,
690 send_event=False):
691 """
692 Lock devices from changes.
694 Arguments:
695 components (list): Uids of the components to lock
696 updates (bool): Lock components from updates
697 deletion (bool): Lock components from deletion
698 send_event (bool): Send an event when an action is blocked by locking
700 Returns:
701 str: Response message
702 """
703 response_data = self._router_request(
704 self._make_request_data(
705 'lockComponents',
706 dict(
707 uids=components,
708 hashcheck='',
709 updates=updates,
710 deletion=deletion,
711 sendEvent=send_event,
712 )
713 )
714 )
716 return response_data['msg']
718 def _delete_components_by_uid(self, components):
719 """
720 Deletes a list of components from a device.
722 Arguments:
723 components (list): Uids of the components to delete
725 Returns:
726 str: Response message
727 """
728 response_data = self._router_request(
729 self._make_request_data(
730 'deleteComponents',
731 dict(
732 uids=components,
733 hashcheck=''
734 )
735 )
736 )
738 return response_data['msg']
740 def get_tree(self, device_class, climb_tree=False, include_details=False):
741 """
742 Get the tree structure of a device class.
744 Arguments:
745 device_class (str): Device class to use as the top of the tree
746 climb_tree (bool): If true will return a different dictionary structure
747 where each branch is a dictionary and contains helpful metadata as
748 well as dictionaries for any branches of the tree. This version
749 ONLY uses dicts. Leaving this to 'False' will return a dictionary
750 with a structure similar to that found in the standard getTree API call.
751 include_details (bool): If the climb_tree option is used then the
752 include_details option may also be specified. If True, the function
753 returns all data provided by the getTree API method. If False, the
754 function returns only the tree structure as a dict of dicts.
756 Returns:
757 dict:
758 """
759 tree_data = self._router_request(
760 self._make_request_data(
761 'getTree',
762 dict(id=device_class)
763 )
764 )
766 if climb_tree is True:
767 return self._climb_tree(tree_data[0], include_details)
768 else:
769 return self._find_nodes_in_tree(tree_data[0])
771 def list_collectors(self):
772 """
773 Get the list of collectors.
775 Returns:
776 list:
777 """
778 return self._router_request(
779 self._make_request_data(
780 'getCollectors',
781 dict(),
782 )
783 )
785 def list_device_classes(self):
786 """
787 Get the list of all device classes.
789 Returns:
790 list:
791 """
792 device_classes_data = self._router_request(
793 self._make_request_data(
794 'getDeviceClasses',
795 dict(),
796 )
797 )
799 dc_list = []
800 for dc in device_classes_data['deviceClasses']:
801 if len(dc['name']) == 0 or dc['name'] == '/':
802 continue
803 dc_list.append('Devices{0}'.format(dc['name']))
805 return dc_list
807 def list_systems(self):
808 """
809 Get the list of all systems.
811 Returns:
812 list:
813 """
814 systems_data = self._router_request(
815 self._make_request_data(
816 'getSystems',
817 dict(),
818 )
819 )
821 systems = []
822 for s in systems_data['systems']:
823 systems.append(s['name'])
825 return systems
827 def list_groups(self):
828 """
829 Get the list of all groups.
831 Returns:
832 list:
833 """
834 groups_data = self._router_request(
835 self._make_request_data(
836 'getGroups',
837 dict(),
838 )
839 )
841 groups = []
842 for g in groups_data['groups']:
843 groups.append(g['name'])
845 return groups
847 def list_locations(self):
848 """
849 Get the list of all locations.
851 Returns:
852 list:
853 """
854 location_data = self._router_request(
855 self._make_request_data(
856 'getLocations',
857 dict(),
858 )
859 )
861 loci = []
862 for l in location_data['locations']:
863 loci.append(l['name'])
865 return loci
867 def get_device_class(self, device_class):
868 """
869 Get a device class
871 Arguments:
872 device_class (str): The name of the device class
874 Returns:
875 ZenossDeviceClass:
876 """
877 if not device_class.startswith('Devices'):
878 if device_class.startswith('/'):
879 device_class = 'Devices{0}'.format(device_class)
880 else:
881 device_class = 'Devices/{0}'.format(device_class)
883 dc_data = self.get_info_by_uid(device_class)
885 return ZenossDeviceClass(
886 self.api_url,
887 self.api_headers,
888 self.ssl_verify,
889 dc_data['data']
890 )
892 def add_comment_by_uid(self, device_uid, comment):
893 """
894 Append a new comment to a device
896 Arguments:
897 device_uid (str): The uid of the device to comment on
898 comment (str): Text of the desired comment
900 Returns:
901 str: Response message
902 """
904 # Get existing comments
905 device = self.get_device_by_uid(device_uid)
906 if len(device.comments) > 0:
907 comment = f'{device.comments}\n{comment}'
909 response_data = self._router_request(
910 self._make_request_data(
911 'setInfo',
912 dict(
913 uid=device_uid,
914 comments=comment,
915 )
916 )
917 )
919 return response_data['success']
921 def set_info_by_uid(self, device_uid, property, value):
922 """
923 Set Attributes on a device or device organizer
925 Arguments:
926 device_uid (str): The uid of the device to comment on
927 property (str): Name of the attribute to set
928 value (str): Value of the attribute to set
930 Returns:
931 str: Response message
932 """
934 response_data = self._router_request(
935 self._make_request_data(
936 'setInfo',
937 {'uid': device_uid, property: value}
938 )
939 )
941 return response_data['success']
944class ZenossDeviceClass(DeviceRouter):
945 """
946 Class for Zenoss device class objects
947 """
949 def __init__(self, url, headers, ssl_verify, device_class_data):
950 super(ZenossDeviceClass, self).__init__(url, headers, ssl_verify)
952 self.uid = device_class_data['uid'].replace('/zport/dmd/', '', 1)
953 self.name = device_class_data['name']
954 self.severity = device_class_data['severity']
955 self.id = device_class_data['id']
956 self.description = device_class_data['description']
957 self.connectionInfo = device_class_data['connectionInfo']
958 self.events = device_class_data['events']
960 def list_devices(self, params=None, keys=None, start=0, limit=50,
961 sort='name', dir='ASC'):
962 """
963 List the devices contained in a device class. Supports pagination.
965 Arguments:
966 params (dict): Key/value filters for the search, options are
967 name, ipAddress, deviceClass, or productionState
968 keys (list): List of keys to return for the devices found
969 start (int): Offset to start device list from, default 0
970 limit (int): The number of results to return, default 50
971 sort (str): Sort key for the list, default is 'name'
972 dir (str): Sort order, either 'ASC' or 'DESC', default is 'ASC'
974 Returns:
975 dict:
976 """
977 if not keys:
978 keys = [
979 'name',
980 'uid',
981 'ipAddressString',
982 'collector',
983 'productionState',
984 'priority',
985 'location',
986 'groups',
987 'events'
988 ]
990 device_data = self._router_request(
991 self._make_request_data(
992 'getDevices',
993 dict(
994 uid=self.uid,
995 params=params,
996 keys=keys,
997 start=start,
998 limit=limit,
999 sort=sort,
1000 dir=dir,
1001 )
1002 )
1003 )
1005 device_list = dict(
1006 total=device_data['totalCount'],
1007 hash=device_data['hash'],
1008 devices=[],
1009 )
1010 for device in device_data['devices']:
1011 devinfo = dict()
1012 for key in keys:
1013 if key == "uid":
1014 devinfo['uid'] = device['uid'].replace('/zport/dmd/', '', 1)
1015 elif key == "location":
1016 if device['location']:
1017 devinfo['location'] = device['location']['name']
1018 else:
1019 devinfo['location'] = None
1020 else:
1021 devinfo[key] = device[key]
1022 device_list['devices'].append(devinfo)
1024 return device_list
1026 def get_devices(self, params=None, start=0, limit=50, sort='name',
1027 dir='ASC'):
1028 """
1029 Get the devices contained in a device class. Supports pagination.
1031 Arguments:
1032 params (dict): Key/value filters for the search, options are
1033 name, ipAddress, deviceClass, or productionState
1034 start (int): Offset to start device list from, default 0
1035 limit (int): The number of results to return, default 50
1036 sort (str): Sort key for the list, default is 'name'
1037 dir (str): Sort order, either 'ASC' or 'DESC', default is 'ASC'
1039 Returns:
1040 dict(int, str, list(ZenossDevice)): ::
1042 {
1043 'total': Total number of devices found
1044 'hash': Hashcheck to determine if any devices have changed,
1045 'devices': ZenossDevice objects,
1046 }
1048 """
1049 device_data = self._router_request(
1050 self._make_request_data(
1051 'getDevices',
1052 dict(
1053 uid=self.uid,
1054 params=params,
1055 start=start,
1056 limit=limit,
1057 sort=sort,
1058 dir=dir,
1059 )
1060 )
1061 )
1063 device_list = dict(
1064 total=device_data['totalCount'],
1065 hash=device_data['hash'],
1066 devices=[]
1067 )
1068 for device in device_data['devices']:
1069 device_list['devices'].append(self.get_device_by_uid(
1070 device['uid'].replace('/zport/dmd/', '', 1)))
1072 return device_list
1074 def get_device(self, device_name):
1075 """
1076 Get a device from the device class
1078 Arguments:
1079 device_name (str): The name of the device to get
1081 Returns:
1082 ZenossDevice:
1083 """
1084 device_uid = '{0}/devices/{1}'.format(self.uid, device_name)
1085 return self.get_device_by_uid(device_uid)
1087 def add_subclass(self, name, description='', connection_info=None):
1088 """
1089 Add a new subclass to the device class.
1091 Arguments:
1092 name (str): Name of the new subclass
1093 description (str): Description for the new subclass
1094 connection_info (list): zProperties that represent the credentials
1095 for access in the subclass
1096 """
1097 return self.add_device_class(name, self.uid, description,
1098 connection_info)
1100 def add_device(self, device_name, title='', ip_address='', location=None,
1101 systems=None, groups=None, model=False,
1102 collector='localhost', production_state=500, comments='',
1103 priority=3, snmp_community='', snmp_port=161, rack_slot='',
1104 hw_manufacturer='', hw_product_name='', os_manufacturer='',
1105 os_product_name='', asset_tag='', serial_number='',
1106 windows_user='', windows_password='', zcommand_user='',
1107 zcommand_password='', configuration_properties=None,
1108 custom_properties=None):
1109 """
1110 Add a new device to the device class.
1112 Arguments:
1113 device_name (str): Name of the new device, will be the device id
1114 title (str): Optional title for the device, default is to match
1115 the device_name
1116 ip_address (str): Ip address for the device, default is to derive
1117 this from DNS based on device_name
1118 location (str): Location for the device
1119 systems (list[(str)]: List of systems for the device
1120 groups (list[(str)]: List of groups for the device
1121 model (bool): Set to True to model the device automatically after
1122 creation
1123 collector (str): Collector to use for the device
1124 production_state (int): Numerical production state for the device,
1125 default is 500 (Pre-Production)
1126 comments (str): Comments for the device
1127 priority (int): Numerical priority for the device, default
1128 is 3 (Normal)
1129 snmp_community (str): SNMP community string for the device
1130 snmp_port (int): SNMP port for the device
1131 rack_slot (str): Rack slot description
1132 hw_manufacturer (str): Hardware manufacturer name, default is to
1133 derive by modeling
1134 hw_product_name (str): Hardware product name, default is to
1135 derive by modeling
1136 os_manufacturer (str): Operating system developer, default is to
1137 derive by modeling
1138 os_product_name (str): Operating system name, default is to
1139 derive by modeling
1140 asset_tag (str): Device's inventory asset tag
1141 serial_number (str): Device's serial number
1142 windows_user (str): Username for Windows device monitoring
1143 windows_password (str): Password for the windows_user
1144 zcommand_user (str): Username for SSH-based monitoring user
1145 zcommand_password (str): Password for the zcommand_user
1146 configuration_properties (dict): Key/value pairs for setting
1147 Configuration Properties for the device
1148 custom_properties (dict): Key/value pairs for setting Custom
1149 Properties for the device
1151 Returns:
1152 str: ID of the add device job
1153 """
1154 if not configuration_properties:
1155 configuration_properties = dict()
1156 if not custom_properties:
1157 custom_properties = dict()
1158 if not systems:
1159 systems = []
1160 if not groups:
1161 groups = []
1163 job_data = self._router_request(
1164 self._make_request_data(
1165 'addDevice',
1166 dict(
1167 deviceName=device_name,
1168 deviceClass=self.uid.replace('Devices', ''),
1169 title=title,
1170 snmpCommunity=snmp_community,
1171 snmpPort=snmp_port,
1172 manageIp=ip_address,
1173 locationPath='Locations/{0}'.format(location),
1174 systemPaths=systems,
1175 groupPaths=groups,
1176 model=model,
1177 collector=collector,
1178 rackSlot=rack_slot,
1179 productionState=production_state,
1180 comments=comments,
1181 hwManufacturer=hw_manufacturer,
1182 hwProductName=hw_product_name,
1183 osManufacturer=os_manufacturer,
1184 osProductName=os_product_name,
1185 priority=priority,
1186 tag=asset_tag,
1187 serialNumber=serial_number,
1188 zWinUser=windows_user,
1189 zWinPassword=windows_password,
1190 zCommandPassword=zcommand_password,
1191 zCommandUsername=zcommand_user,
1192 zProperties=configuration_properties,
1193 cProperties=custom_properties,
1194 )
1195 )
1196 )
1198 return job_data['new_jobs'][0]['uuid']
1200 def list_properties(self, params=None, sort=None, sort_dir='ASC'):
1201 """
1202 List the configuration properties for the device class
1204 Arguments:
1205 params (dict): Search parameters to filter the properties list on.
1206 sort (str): Sort key for the properties list.
1207 sort_dir (str): Sort direction, either ASC or DESC
1209 Returns:
1210 dict(int, list(dict)): ::
1212 {
1213 'total': Total count of properties returned.
1214 'properties': List of properties found.
1215 }
1217 """
1218 pr = PropertiesRouter(self.api_url, self.api_headers, self.ssl_verify)
1219 return pr.list_properties(self.uid, params=params, sort=sort,
1220 sort_dir=sort_dir)
1222 def list_local_properties(self):
1223 """
1224 List the locally defined configuration properties for the device class
1226 Returns:
1227 dict(int, list(dict)): ::
1229 {
1230 'total': Total count of properties returned.
1231 'properties': List of properties found.
1232 }
1234 """
1235 pr = PropertiesRouter(self.api_url, self.api_headers, self.ssl_verify)
1236 return pr.list_local_properties(self.uid)
1238 def list_custom_properties(self):
1239 """
1240 List the custom properties for the device class
1242 Returns:
1243 dict(int, list(dict)): ::
1245 {
1246 'total': Total count of properties returned.
1247 'properties': List of properties found.
1248 }
1250 """
1251 pr = PropertiesRouter(self.api_url, self.api_headers, self.ssl_verify)
1252 return pr.list_custom_properties(self.uid)
1254 def get_properties(self, params=None):
1255 """
1256 Get the configuration properties for the device class
1258 Arguments:
1259 params (dict): Search parameters for filter the properties on.
1261 Returns:
1262 dict(int, list(ZenossProperty)): ::
1264 {
1265 'total': Total count of properties returned.
1266 'properties': List of ZenossProperty objects.
1267 }
1269 """
1270 pr = PropertiesRouter(self.api_url, self.api_headers, self.ssl_verify)
1271 return pr.get_properties(self.uid, params=params)
1273 def get_property(self, zproperty):
1274 """
1275 Get a configuration property
1277 Arguments:
1278 zproperty (str): The id of the property to get
1280 Returns:
1281 ZenossProperty:
1282 """
1283 pr = PropertiesRouter(self.api_url, self.api_headers, self.ssl_verify)
1284 return pr.get_property(self.uid, zproperty)
1286 def get_custom_properties(self, params=None):
1287 """
1288 Get the cProperties for the device class
1290 Arguments:
1291 params (dict): Search parameters for filter the properties on.
1293 Returns:
1294 dict(int, list(ZenossCustomProperty)): ::
1296 {
1297 'total': Total count of properties returned.
1298 'properties': List of ZenossCustomProperty objects.
1299 }
1301 """
1302 pr = PropertiesRouter(self.api_url, self.api_headers, self.ssl_verify)
1303 return pr.get_custom_properties(self.uid, params=params)
1305 def get_custom_property(self, cproperty):
1306 """
1307 Get a custom property for the device class
1309 Arguments:
1310 cproperty (str): ID of the property to get.
1312 Returns:
1313 ZenossCustomProperty:
1314 """
1315 pr = PropertiesRouter(self.api_url, self.api_headers, self.ssl_verify)
1316 return pr.get_custom_property(self.uid, cproperty)
1318 def set_property(self, zproperty, value=None):
1319 """
1320 Set the value of a configuration property
1322 Arguments:
1323 zproperty (str): The id of the property to set a value for
1324 value (str): The value to set for the property
1326 Returns:
1327 bool:
1328 """
1329 pr = PropertiesRouter(self.api_url, self.api_headers, self.ssl_verify)
1330 return pr.set_property_value(self.uid, id=zproperty, value=value)
1332 def delete_property(self, zproperty):
1333 """
1334 Delete the locally set value of a property for a device class
1336 Arguments:
1337 zproperty (str): ID of the property to delete.
1339 Returns:
1340 bool:
1341 """
1342 pr = PropertiesRouter(self.api_url, self.api_headers, self.ssl_verify)
1343 return pr.delete_property(self.uid, zproperty)
1346class ZenossDevice(DeviceRouter):
1347 """
1348 Class for Zenoss device objects
1349 """
1351 def __init__(self, url, headers, ssl_verify, device_data):
1352 super(ZenossDevice, self).__init__(url, headers, ssl_verify)
1354 unneeded_props = ['class_label', 'class_plural_label',
1355 'class_plural_short_label', 'class_short_label',
1356 'deviceClass', 'inspector_type',
1357 'ipAddress', 'meta_type', 'priorityLabel',
1358 'productionStateLabel', 'pythonClass', 'uuid', ]
1360 default_props = ['collector', 'comments', 'description', 'device',
1361 'deviceConnectionInfo', 'events', 'firstSeen',
1362 'groups', 'icon', 'id', 'hwManufacturer', 'hwModel',
1363 'lastChanged', 'lastCollected', 'links', 'locking',
1364 'memory', 'name', 'osManufacturer', 'osModel',
1365 'priority', 'productionState', 'rackSlot',
1366 'serialNumber', 'severity', 'snmpAgent',
1367 'snmpCommunity', 'snmpContact', 'snmpDescr',
1368 'snmpLocation', 'snmpSysName', 'snmpVersion',
1369 'sshLink', 'status', 'systems',
1370 'tagNumber', 'uptime', ]
1372 for i in unneeded_props:
1373 if i in device_data:
1374 device_data.pop(i)
1376 uid = device_data.pop('uid')
1377 self.uid = uid.replace('/zport/dmd/', '', 1)
1379 location = device_data.pop('location')
1380 if location:
1381 self.location = location['name']
1382 else:
1383 self.location = None
1385 self.ip_address = device_data.pop('ipAddressString')
1387 for prop in default_props:
1388 setattr(self, prop, device_data.pop(prop))
1390 self.properties = device_data
1391 self.parent = self.uid.split('/devices/')[0]
1393 def list_components(self, meta_type=None, start=0, limit=50, sort='name',
1394 dir='ASC', keys=None, name=None):
1395 """
1396 Get a list of all the components on a device. Supports pagination.
1398 Arguments:
1399 meta_type (str): Meta type of components to list
1400 start (int): Offset to start device list from, default 0
1401 limit (int): The number of results to return, default 50
1402 sort (str): Sort key for the list, default is 'name'
1403 dir (str): Sort order, either 'ASC' or 'DESC', default is 'ASC'
1404 keys (list): Keys to include in the returned data
1405 name (str): Regular expression pattern to filter on, requries
1406 the keys parameter
1408 Returns:
1409 dict(int, str, list): ::
1411 {
1412 'total': Total number of components found.
1413 'hash': Hash check to determine if components have changed
1414 'components': List of components found
1415 }
1417 """
1418 if name and not keys:
1419 warnings.warn("Filtering by name also requires a list of keys", UserWarning)
1420 name = None
1422 components_data = self._router_request(
1423 self._make_request_data(
1424 'getComponents',
1425 dict(
1426 uid='/zport/dmd/{0}'.format(self.uid),
1427 meta_type=meta_type,
1428 start=start,
1429 limit=limit,
1430 sort=sort,
1431 dir=dir,
1432 keys=keys,
1433 name=name,
1434 )
1435 )
1436 )
1438 components_list = dict(
1439 total=components_data['totalCount'],
1440 hash=components_data['hash'],
1441 components=[],
1442 )
1444 for c in components_data['data']:
1445 components_list['components'].append(
1446 c['uid'].split('/{0}/'.format(self.id))[-1])
1448 return components_list
1450 def get_components(self, meta_type=None, start=0, limit=50, sort='name',
1451 dir='ASC'):
1452 """
1453 Get component objects for all components on the device.
1454 Supports Pagination.
1456 Arguments:
1457 meta_type (str): Meta type of components to list
1458 start (int): Offset to start device list from, default 0
1459 limit (int): The number of results to return, default 50
1460 sort (str): Sort key for the list, default is 'name'
1461 dir (str): Sort order, either 'ASC' or 'DESC', default is 'ASC'
1463 Returns:
1464 list(ZenossComponent):
1465 """
1466 components_list = self.list_components(meta_type=meta_type, start=start,
1467 limit=limit, sort=sort, dir=dir)
1469 components = []
1470 for component in components_list['components']:
1471 c_info = self.get_info_by_uid(
1472 '{0}/{1}'.format(self.uid, component))
1473 components.append(
1474 ZenossComponent(
1475 self.api_url,
1476 self.api_headers,
1477 self.ssl_verify,
1478 c_info['data']
1479 )
1480 )
1482 return components
1484 def get_component(self, component):
1485 """
1486 Get a component object.
1488 Arguments:
1489 component (str): Name of the component, e.g. 'hw/cpus/0'
1491 Returns:
1492 ZenossComponent:
1493 """
1494 c_info = self.get_info_by_uid('{0}/{1}'.format(self.uid, component))
1496 return ZenossComponent(
1497 self.api_url,
1498 self.api_headers,
1499 self.ssl_verify,
1500 c_info['data']
1501 )
1503 def list_user_commands(self):
1504 """
1505 Get the list of user commands for a device.
1507 Returns:
1508 dict(str, str): ::
1510 {
1511 name: Name of the user command
1512 description: Command description
1513 }
1515 """
1516 uc_data = self._router_request(
1517 self._make_request_data(
1518 'getUserCommands',
1519 dict(uid=self.uid),
1520 )
1521 )
1523 user_commands = []
1524 for uc in uc_data:
1525 user_commands.append(
1526 dict(
1527 name=uc['id'],
1528 description=uc['description']
1529 ))
1531 return user_commands
1533 def list_local_templates(self):
1534 """
1535 Get the list of monitoring templates defined locally on a device.
1537 Returns:
1538 list:
1539 """
1540 lt_data = self._router_request(
1541 self._make_request_data(
1542 'getLocalTemplates',
1543 dict(
1544 uid=self.uid,
1545 query='',
1546 ),
1547 )
1548 )
1550 local_templates = []
1551 for lt in lt_data['data']:
1552 local_templates.append(lt['uid'].split('/')[-1])
1554 return local_templates
1556 def get_local_templates(self):
1557 """
1558 Get ZenossTemplate objects for all locally defined templates.
1560 Returns:
1561 list(ZenossTemplate):
1562 """
1563 lt_list = self.list_local_templates()
1565 local_templates = []
1566 tr = TemplateRouter(self.api_url, self.api_headers, self.ssl_verify)
1567 for lt in lt_list:
1568 local_templates.append(
1569 tr._get_template_by_uid('{0}/{1}'.format(self.uid, lt))
1570 )
1572 return local_templates
1574 def add_local_template(self, template):
1575 """
1576 Add a local template to the device.
1578 Arguments:
1579 template (str): Name of the new local template
1580 """
1581 self._router_request(
1582 self._make_request_data(
1583 'addLocalTemplate',
1584 dict(
1585 deviceUid=self.uid,
1586 templateId=template,
1587 )
1588 )
1589 )
1591 return True
1593 def delete_local_template(self, template):
1594 """
1595 Remove a local template from the device.
1597 Arguments:
1598 template (str): Name of the template to remove
1599 """
1600 self._router_request(
1601 self._make_request_data(
1602 'removeLocalTemplate',
1603 dict(
1604 deviceUid=self.uid,
1605 templateId=template,
1606 )
1607 )
1608 )
1610 return True
1612 def list_active_templates(self):
1613 """
1614 Get the list of templates active on a device, both bound and local.
1616 Returns:
1617 list(dict(str, str)): ::
1619 {
1620 'name': Template name,
1621 'label': Display label for the template,
1622 }
1624 """
1625 templates_data = self._router_request(
1626 self._make_request_data(
1627 'getTemplates',
1628 dict(id=self.uid),
1629 )
1630 )
1632 templates = []
1633 for t in templates_data:
1634 templates.append(dict(
1635 name=t['uid'].split('/')[-1],
1636 label=t['text'])
1637 )
1639 return templates
1641 def get_active_templates(self):
1642 """
1643 Get ZenossTemplate objects for all active templates on a device.
1645 Returns:
1646 list(ZenossTemplate):
1647 """
1648 templates_data = self._router_request(
1649 self._make_request_data(
1650 'getTemplates',
1651 dict(id=self.uid),
1652 )
1653 )
1655 templates = []
1656 tr = TemplateRouter(self.api_url, self.api_headers, self.ssl_verify)
1657 for t in templates_data:
1658 tuid = t['uid'].replace('/zport/dmd/', '', 1)
1659 templates.append(
1660 tr._get_template_by_uid(tuid)
1661 )
1663 return templates
1665 def list_unbound_templates(self):
1666 """
1667 Get the list of available templates that are not bound to the device.
1669 Returns:
1670 list(dict(str, str)): ::
1672 {
1673 'name': Template name,
1674 'label': Display label for the template,
1675 }
1677 """
1678 templates_data = self._router_request(
1679 self._make_request_data(
1680 'getUnboundTemplates',
1681 dict(uid=self.uid),
1682 )
1683 )
1685 templates = []
1686 for t in templates_data['data']:
1687 templates.append(dict(
1688 name=t[0],
1689 label=t[1]
1690 ))
1692 return templates
1694 def get_unbound_templates(self):
1695 """
1696 Get ZenossTemplate objects for available templates that are not bound
1697 to the device.
1699 Returns:
1700 list(ZenossTemplate):
1701 """
1702 ut_list = self.list_unbound_templates()
1703 find_path = re.compile('[(]([/].*)[)]')
1704 templates = []
1705 tr = TemplateRouter(self.api_url, self.api_headers, self.ssl_verify)
1706 for t in ut_list:
1707 m = re.search(find_path, t['label'])
1708 if m:
1709 if m.groups()[0] == "/":
1710 path = ''
1711 else:
1712 path = m.groups()[0]
1713 uid = 'Devices{0}/rrdTemplates/{1}'.format(path, t['name'])
1714 templates.append(
1715 tr._get_template_by_uid(uid)
1716 )
1718 return templates
1720 def list_bound_templates(self):
1721 """
1722 Get the list of templates bound to a device, does not include
1723 local templates.
1725 Returns:
1726 list(dict(str, str)): ::
1728 {
1729 'name': Template name,
1730 'label': Display label for the template,
1731 }
1733 """
1734 templates_data = self._router_request(
1735 self._make_request_data(
1736 'getBoundTemplates',
1737 dict(uid=self.uid),
1738 )
1739 )
1741 templates = []
1742 for t in templates_data['data']:
1743 templates.append(dict(
1744 name=t[0],
1745 label=t[1]
1746 ))
1748 return templates
1750 def get_bound_templates(self):
1751 """
1752 Get ZenossTemplate objects templates that are bound to the device.
1754 Returns:
1755 list(ZenosTemplate):
1756 """
1757 bt_list = self.list_bound_templates()
1758 find_path = re.compile('[(]([/].*)[)]')
1759 templates = []
1760 tr = TemplateRouter(self.api_url, self.api_headers, self.ssl_verify)
1761 for t in bt_list:
1762 m = re.search(find_path, t['label'])
1763 if m:
1764 if m.groups()[0] == "/":
1765 path = ''
1766 else:
1767 path = m.groups()[0]
1768 if path.endswith(self.name):
1769 path = path.replace(self.name,
1770 'devices/{0}'.format(self.name))
1771 uid = 'Devices{0}/{1}'.format(path, t['name'])
1772 else:
1773 uid = 'Devices{0}/rrdTemplates/{1}'.format(path, t['name'])
1774 templates.append(
1775 tr._get_template_by_uid(uid)
1776 )
1778 return templates
1780 def list_overridable_templates(self):
1781 """
1782 Get the list of available templates on a device that can be overridden.
1784 Returns:
1785 list(dict(str, str)): ::
1787 {
1788 'name': Template name,
1789 'label': Display label for the template,
1790 }
1792 """
1793 template_data = self._router_request(
1794 self._make_request_data(
1795 'getOverridableTemplates',
1796 dict(
1797 uid=self.uid,
1798 query='',
1799 ),
1800 )
1801 )
1803 templates = []
1804 for t in template_data['data']:
1805 templates.append(dict(
1806 name=t['uid'].split('/')[-1],
1807 label=t['label'])
1808 )
1810 return templates
1812 def get_overridable_templates(self):
1813 """
1814 Get ZenossTemplate objects for templates that can be overridden.
1816 Returns:
1817 list(ZenossTemplate):
1818 """
1819 template_data = self._router_request(
1820 self._make_request_data(
1821 'getOverridableTemplates',
1822 dict(
1823 uid=self.uid,
1824 query='',
1825 )
1826 )
1827 )
1829 templates = []
1830 tr = TemplateRouter(self.api_url, self.api_headers, self.ssl_verify)
1831 for t in template_data['data']:
1832 templates.append(
1833 tr._get_template_by_uid(t['uid'].replace('/zport/dmd/', '', 1))
1834 )
1836 return templates
1838 def set_bound_templates(self, templates):
1839 """
1840 Set a list of templates as bound to a device.
1842 Arguments:
1843 templates (list): List of template names
1844 """
1845 self._router_request(
1846 self._make_request_data(
1847 'setBoundTemplates',
1848 dict(
1849 uid=self.uid,
1850 templateIds=templates,
1851 )
1852 )
1853 )
1855 return True
1857 def bind_or_unbind_template(self, path, template):
1858 """
1859 Binds a template to the device if it's unbound, or unbinds it if
1860 it's bound.
1862 Arguments:
1863 path (str): Template's path, as given in the display label
1864 template (str): Name of the template to bind/unbind
1865 """
1866 self._router_request(
1867 self._make_request_data(
1868 'bindOrUnbindTemplate',
1869 dict(
1870 uid=self.uid,
1871 templateUid='Devices{0}/rrdtemplates/{1}'.format(path,
1872 template)
1873 )
1874 )
1875 )
1877 return True
1879 def reset_bound_templates(self):
1880 """
1881 Remove all bound templates from device.
1882 """
1883 self._router_request(
1884 self._make_request_data(
1885 'resetBoundTemplates',
1886 dict(uid=self.uid)
1887 )
1888 )
1890 return True
1892 def move(self, device_class):
1893 """
1894 Move the device to a different device class
1896 Arguments:
1897 device_class (str): Name of the device class to move the device into
1899 Returns:
1900 str: uuid of the Job Manager job for the move
1901 """
1902 job_data = self.move_devices_by_uid([self.uid], device_class)
1903 return job_data[0]['uuid']
1905 def reidentify(self, new_id):
1906 """
1907 Change the device's id in Zenoss. Note that changing the device id will
1908 cause the loss of all graph data for the device.
1910 Arguments:
1911 new_id (str): New ID for the device
1912 """
1913 return_data = self._router_request(
1914 self._make_request_data(
1915 'renameDevice',
1916 dict(
1917 uid=self.uid,
1918 newId=new_id,
1919 ),
1920 )
1921 )
1923 self.id = new_id
1924 self.name = new_id
1925 self.uid = '{0}/devices/{1}'.format(self.parent, self.uid)
1927 return True
1929 def lock(self, updates=False, deletion=False, send_event=False):
1930 """
1931 Lock the device for changes.
1933 Arguments:
1934 updates (bool): Lock for updates
1935 deletion (bool): Lock for deletion
1936 send_event (bool): Send an event when an action is blocked by locking
1938 Returns:
1939 str: Response message
1940 """
1941 return self.lock_devices_by_uid([self.uid], updates=updates,
1942 deletion=deletion,
1943 send_event=send_event)
1945 def lock_for_updates(self, send_event=False):
1946 """
1947 Lock the device for updates.
1949 Arguments:
1950 send_event (bool): Send an event when updates are blocked by locking
1952 Returns:
1953 str: Response message
1954 """
1955 return self.lock(updates=True, send_event=send_event)
1957 def lock_for_deletion(self, send_event=False):
1958 """
1959 Lock the device for updates.
1961 Arguments:
1962 send_event (bool): Send an event when deletion is blocked by locking
1964 Returns:
1965 str: Response message
1966 """
1967 return self.lock(deletion=True, send_event=send_event)
1969 def reset_ip_address(self, ip_address=''):
1970 """
1971 Reset the IP address of the device to ip_address if specified or to the
1972 result of a DNS lookup if not.
1974 Arguments:
1975 ip_address (str): IP address to set device to
1977 Returns:
1978 str: Response message
1979 """
1980 return self.reset_device_ip_addresses_by_uid([self.uid],
1981 ip_address=ip_address)
1983 def set_production_state(self, production_state):
1984 """
1985 Set the production state for the device.
1987 Arguments:
1988 production_state (int): Numeric value for the desired production
1989 state.
1991 Returns:
1992 str: Response message
1993 """
1994 message = self.set_production_state_by_uids([self.uid],
1995 production_state)
1996 self.productionState = production_state
1997 return message
1999 def set_priority(self, priority):
2000 """
2001 Set the priority for the device.
2003 Arguments:
2004 priority (int): Numeric value for the desired priority
2006 Returns:
2007 str: Reponse message
2008 """
2009 message = self.set_priority_by_uids([self.uid], priority)
2010 self.priority = priority
2011 return message
2013 def add_comment(self, comment):
2014 """
2015 Append a comment to a device.
2017 Arguments:
2018 comment (str): Desired comment text
2020 Returns:
2021 str: Reponse message
2022 """
2024 message = self.add_comment_by_uid(self.uid, comment)
2025 if len(self.comments) > 0:
2026 self.comments = f'{self.comments}\n{comment}'
2027 else:
2028 self.comments = comment
2029 return message
2031 def set_info(self, property, value):
2032 """
2033 Set attribute of a device. DOES NOT update zProps or cProps
2035 Arguments:
2036 property (str): Name of property to set
2037 value (str): Value to set property to
2039 Returns:
2040 str: Reponse message
2041 """
2043 message = self.set_info_by_uid(self.uid, property, value)
2044 return message
2047 def set_collector(self, collector):
2048 """
2049 Set the collector for the device.
2051 Arguments:
2052 collector (str): The collector to use for the device
2054 Returns:
2055 str: uuid of the Job Manager job for the change
2056 """
2057 job_data = self.set_collector_by_uids([self.uid], collector)
2058 return job_data['uuid']
2060 def delete(self, action, del_events=False, del_perf=True, **kwargs):
2061 """
2062 Remove a device from its organizer, or delete it from Zenoss altogether.
2064 Arguments:
2065 action (str): 'remove' to remove the devices from their organizer(see 'uid' below),
2066 'delete' to delete them from Zenoss
2067 del_events (bool): Remove all events for the devices
2068 del_perf (bool): Remove all perf data for the devices
2070 Optional Arguments:
2071 uid (str): If using the 'remove' action this option must
2072 be included and should be the uid of the organizer you
2073 wish to remove the device from. ie "/zport/dmd/Groups/SOMEGROUP"
2075 Returns:
2076 bool:
2077 """
2078 self.delete_devices_by_uid([self.uid], action, del_events, del_perf, **kwargs)
2080 return True
2082 def remodel(self):
2083 """
2084 Remodel the device.
2086 Returns:
2087 str: uuid of the Job Manager job for the remodel
2088 """
2089 response_data = self._router_request(
2090 self._make_request_data(
2091 'remodel',
2092 dict(deviceUid=self.uid)
2093 )
2094 )
2096 return response_data['jobId']
2098 def list_properties(self, params=None, sort=None, sort_dir='ASC'):
2099 """
2100 List the configuration properties for the device
2102 Arguments:
2103 params (dict): Search parameters to filter the properties list on.
2104 sort (str): Sort key for the properties list.
2105 sort_dir (str): Sort direction, either ASC or DESC
2107 Returns:
2108 dict(int, list(dict)): ::
2110 {
2111 'total': Total count of properties returned.
2112 'properties': List of properties found.
2113 }
2115 """
2116 pr = PropertiesRouter(self.api_url, self.api_headers, self.ssl_verify)
2117 return pr.list_properties(self.uid, params=params, sort=sort,
2118 sort_dir=sort_dir)
2120 def list_local_properties(self):
2121 """
2122 List the locally defined configuration properties for the device
2124 Returns:
2125 dict(int, list(dict)): ::
2127 {
2128 'total': Total count of properties returned.
2129 'properties': List of properties found.
2130 }
2132 """
2133 pr = PropertiesRouter(self.api_url, self.api_headers, self.ssl_verify)
2134 return pr.list_local_properties(self.uid)
2136 def list_custom_properties(self):
2137 """
2138 List the custom properties for the device
2140 Returns:
2141 dict(int, list(dict)): ::
2143 {
2144 'total': Total count of properties returned.
2145 'properties': List of properties found.
2146 }
2148 """
2149 pr = PropertiesRouter(self.api_url, self.api_headers, self.ssl_verify)
2150 return pr.list_custom_properties(self.uid)
2152 def get_properties(self, params=None):
2153 """
2154 Get the configuration properties for the device
2156 Arguments:
2157 params (dict): Search parameters for filter the properties on.
2159 Returns:
2160 dict(int, list(ZenossProperty)): ::
2162 {
2163 'total': Total count of properties returned.
2164 'properties': List of ZenossProperty objects.
2165 }
2167 """
2168 pr = PropertiesRouter(self.api_url, self.api_headers, self.ssl_verify)
2169 return pr.get_properties(self.uid, params=params)
2171 def get_property(self, zproperty):
2172 """
2173 Get a configuration property
2175 Arguments:
2176 zproperty (str): The id of the property to get
2178 Returns:
2179 ZenossProperty:
2180 """
2181 pr = PropertiesRouter(self.api_url, self.api_headers, self.ssl_verify)
2182 return pr.get_property(self.uid, zproperty)
2184 def get_custom_properties(self, params=None):
2185 """
2186 Get the cProperties for the device
2188 Arguments:
2189 params (dict): Search parameters for filter the properties on.
2191 Returns:
2192 dict(int, list(ZenossCustomProperty)): ::
2194 {
2195 'total': Total count of properties returned.
2196 'properties': List of ZenossCustomProperty objects.
2197 }
2199 """
2200 pr = PropertiesRouter(self.api_url, self.api_headers, self.ssl_verify)
2201 return pr.get_custom_properties(self.uid, params=params)
2203 def get_custom_property(self, cproperty):
2204 """
2205 Get a custom property for the device
2207 Arguments:
2208 cproperty (str): ID of the property to get.
2210 Returns:
2211 ZenossCustomProperty:
2212 """
2213 pr = PropertiesRouter(self.api_url, self.api_headers, self.ssl_verify)
2214 return pr.get_custom_property(self.uid, cproperty)
2216 def set_property(self, zproperty, value=None):
2217 """
2218 Set the value of a configuration property
2220 Arguments:
2221 zproperty (str): The id of the property to set a value for
2222 value (str): The value to set for the property
2224 Returns:
2225 bool:
2226 """
2227 pr = PropertiesRouter(self.api_url, self.api_headers, self.ssl_verify)
2228 return pr.set_property_value(self.uid, zproperty, value=value)
2230 def delete_property(self, zproperty):
2231 """
2232 Delete the locally set value of a property for a device
2234 Arguments:
2235 zproperty (str): ID of the property to delete.
2237 Returns:
2238 bool:
2239 """
2240 pr = PropertiesRouter(self.api_url, self.api_headers, self.ssl_verify)
2241 return pr.delete_property(self.uid, zproperty)
2244class ZenossComponent(DeviceRouter):
2245 """
2246 Class for Zenoss component objects
2247 """
2249 def __init__(self, url, headers, ssl_verify, device_data):
2250 super(ZenossComponent, self).__init__(url, headers, ssl_verify)
2252 unneeded_props = ['class_label', 'class_plural_label',
2253 'class_plural_short_label', 'class_short_label',
2254 'inspector_type', 'uuid']
2256 for i in unneeded_props:
2257 if i in device_data:
2258 device_data.pop(i)
2260 uid = device_data.pop('uid')
2261 self.uid = uid.replace('/zport/dmd/', '', 1)
2262 self.description = device_data.pop('description')
2263 self.device = device_data.pop('device')
2264 self.deviceName = device_data.pop('deviceName')
2265 self.events = device_data.pop('events')
2266 self.icon = device_data.pop('icon')
2267 self.id = device_data.pop('id')
2268 self.locking = device_data.pop('locking')
2269 self.meta_type = device_data.pop('meta_type')
2270 self.monitor = device_data.pop('monitor')
2271 self.monitored = device_data.pop('monitored')
2272 self.name = device_data.pop('name')
2273 self.pingStatus = device_data.pop('pingStatus')
2274 self.severity = device_data.pop('severity')
2275 self.status = device_data.pop('status')
2276 self.usesMonitorAttribute = device_data.pop('usesMonitorAttribute')
2278 self.properties = device_data
2279 dev_path = self.uid.split('/{0}/'.format(self.device))[0]
2280 self.parent = '{0}/{1}'.format(dev_path, self.device)
2282 def set_monitored(self, monitor=True):
2283 """
2284 Sets the monitored state for the component.
2286 Arguments:
2287 monitor (bool): True to monitor, False to stop monitoring
2289 Returns:
2290 str: Response message
2291 """
2292 return self._set_components_monitored_by_uids([self.uid], monitor)
2294 def lock(self, updates=False, deletion=False, send_event=False):
2295 """
2296 Lock the component for changes.
2298 Arguments:
2299 updates (bool): Lock for updates
2300 deletion (bool): Lock for deletion
2301 send_event (bool): Send an event when an action is blocked by locking
2303 Returns:
2304 str: Response message
2305 """
2306 return self._lock_components_by_uid([self.uid], updates=updates,
2307 deletion=deletion,
2308 send_event=send_event)
2310 def lock_for_updates(self, send_event=False):
2311 """
2312 Lock the component for updates.
2314 Arguments:
2315 send_event (bool): Send an event when updates are blocked by locking
2317 Returns:
2318 str: Response message
2319 """
2320 return self.lock(updates=True, send_event=send_event)
2322 def lock_for_deletion(self, send_event=False):
2323 """
2324 Lock the component for updates.
2326 Arguments:
2327 send_event (bool): Send an event when deletion is blocked by locking
2329 Returns:
2330 str: Response message
2331 """
2332 return self.lock(deletion=True, send_event=send_event)
2334 def delete(self):
2335 """
2336 Delete the component.
2338 Returns:
2339 str: Response message
2340 """
2341 return self._delete_components_by_uid([self.uid])