1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 __doc__ = """Device
16 Base device (remote computer) class
17 """
18
19 import os
20 import shutil
21 import time
22 import socket
23 import logging
24 log = logging.getLogger("zen.Device")
25
26 from _mysql_exceptions import OperationalError
27
28 from urllib import quote as urlquote
29 from ipaddr import IPAddress
30 from Acquisition import aq_base
31 from zope.event import notify
32 from AccessControl.PermissionRole import rolesForPermissionOn
33 from Products.Zuul.catalog.events import IndexingEvent
34 from Products.ZenUtils.Utils import isXmlRpc, unused, getObjectsFromCatalog
35 from Products.ZenUtils import Time
36
37 import RRDView
38 from Products import Zuul
39 from Products.Zuul.interfaces import IInfo
40 from Products.ZenUtils.jsonutils import json
41 from Products.ZenUtils.IpUtil import checkip, IpAddressError, maskToBits, \
42 ipunwrap, getHostByName
43 from Products.ZenModel.interfaces import IIndexed
44 from Products.ZenUtils.guid.interfaces import IGloballyIdentifiable, IGlobalIdentifier
45
46
47 from ManagedEntity import ManagedEntity
48
49 from AccessControl import ClassSecurityInfo
50 from Globals import DTMLFile
51 from Globals import InitializeClass
52 from DateTime import DateTime
53 from zExceptions import NotFound
54 from ZODB.POSException import POSError
55
56
57
58 from Products.DataCollector.ApplyDataMap import ApplyDataMap
59
60 from Products.ZenRelations.RelSchema import *
61 from Commandable import Commandable
62 from Lockable import Lockable
63 from MaintenanceWindowable import MaintenanceWindowable
64 from AdministrativeRoleable import AdministrativeRoleable
65 from ZenMenuable import ZenMenuable
66
67 from OperatingSystem import OperatingSystem
68 from DeviceHW import DeviceHW
69
70 from ZenStatus import ZenStatus
71 from Products.ZenModel.Exceptions import *
72 from ZenossSecurity import *
73 from Products.ZenUtils.FakeRequest import FakeRequest
74 from Products.ZenUtils.Utils import edgesToXML
75 from Products.ZenUtils import NetworkTree
76
77 from zope.interface import implements
78 from EventView import IEventView
79 from Products.ZenWidgets.interfaces import IMessageSender
80 from Products.ZenWidgets import messaging
81 from Products.ZenEvents.browser.EventPillsAndSummaries import getEventPillME
82 from OFS.CopySupport import CopyError
83 from Products.Zuul import getFacade
84 from Products.Zuul.utils import allowedRolesAndUsers
85 from Products.ZenUtils.IpUtil import numbip
86 from Products.ZenMessaging.actions import sendUserAction
87 from Products.ZenMessaging.actions.constants import ActionTargetType, ActionName
88
89
91 """
92 Return the default network root.
93 """
94 return context.getDmdRoot('Networks')
95
96
117
118
119 -def manage_createDevice(context, deviceName, devicePath="/Discovered",
120 tag="", serialNumber="",
121 zSnmpCommunity="", zSnmpPort=161, zSnmpVer="",
122 rackSlot="", productionState=1000, comments="",
123 hwManufacturer="", hwProductName="",
124 osManufacturer="", osProductName="",
125 locationPath="", groupPaths=[], systemPaths=[],
126 performanceMonitor="localhost",
127 discoverProto="snmp", priority=3, manageIp="",
128 zProperties=None, title=None):
129 """
130 Device factory creates a device and sets up its relations and collects its
131 configuration. SNMP Community discovery also happens here. If an IP is
132 passed for deviceName it will be used for collection and the device name
133 will be set to the SNMP SysName (or ptr if SNMP Fails and ptr is valid)
134
135 @rtype: Device
136 """
137 manageIp = manageIp.replace(' ', '')
138 checkDeviceExists(context, deviceName, manageIp, performanceMonitor)
139 deviceName = context.prepId(deviceName)
140 log.info("device name '%s' for ip '%s'", deviceName, manageIp)
141 deviceClass = context.getDmdRoot("Devices").createOrganizer(devicePath)
142 deviceName = context.prepId(deviceName)
143 device = deviceClass.createInstance(deviceName)
144 device.setManageIp(manageIp)
145 device.manage_editDevice(
146 tag, serialNumber,
147 zSnmpCommunity, zSnmpPort, zSnmpVer,
148 rackSlot, productionState, comments,
149 hwManufacturer, hwProductName,
150 osManufacturer, osProductName,
151 locationPath, groupPaths, systemPaths,
152 performanceMonitor, priority, zProperties,
153 title)
154 return device
155
156
159 """
160 Find the SNMP community and version for an ip address using zSnmpCommunities.
161
162 @rtype: tuple of (community, port, version, device name)
163 """
164 from pynetsnmp.SnmpSession import SnmpSession
165
166 devroot = context.getDmdRoot('Devices').createOrganizer(devicePath)
167 communities = []
168 if community: communities.append(community)
169 communities.extend(getattr(devroot, "zSnmpCommunities", []))
170 if not port: port = getattr(devroot, "zSnmpPort", 161)
171 versions = ('v2c', 'v1')
172 if not version: version = getattr(devroot, 'zSnmpVer', None)
173 if version: versions = (version,)
174 timeout = getattr(devroot, "zSnmpTimeout", 2)
175 retries = getattr(devroot, "zSnmpTries", 2)
176 session = SnmpSession(ip, timeout=timeout, port=port, retries=retries)
177 oid = '.1.3.6.1.2.1.1.5.0'
178 goodcommunity = ""
179 goodversion = ""
180 devname = ""
181 for version in versions:
182 session.setVersion(version)
183 for community in communities:
184 session.community = community
185 try:
186 devname = session.get(oid).values()[0]
187 goodcommunity = session.community
188 goodversion = version
189 break
190 except (SystemExit, KeyboardInterrupt, POSError): raise
191 except: pass
192 if goodcommunity:
193 break
194 else:
195 raise NoSnmp("No SNMP found for IP = %s" % ip)
196 return (goodcommunity, port, goodversion, devname)
197
214
215 addDevice = DTMLFile('dtml/addDevice',globals())
216
217
219
220 -class Device(ManagedEntity, Commandable, Lockable, MaintenanceWindowable,
221 AdministrativeRoleable, ZenMenuable):
222 """
223 Device is a base class that represents the idea of a single computer system
224 that is made up of software running on hardware. It currently must be IP
225 enabled but maybe this will change.
226 """
227
228 implements(IEventView, IIndexed, IGloballyIdentifiable)
229
230 event_key = portal_type = meta_type = 'Device'
231
232 default_catalog = "deviceSearch"
233
234 relationshipManagerPathRestriction = '/Devices'
235
236 manageIp = ""
237 productionState = 1000
238 preMWProductionState = productionState
239 snmpAgent = ""
240 snmpDescr = ""
241 snmpOid = ""
242 snmpContact = ""
243 snmpSysName = ""
244 snmpLocation = ""
245 rackSlot = ""
246 comments = ""
247 sysedgeLicenseMode = ""
248 priority = 3
249 detailKeys = ('tagNumber', 'serialNumber',
250 'hwModel', 'hwManufacturer',
251 'osModel', 'osManufacturer',
252 'groups', 'systems', 'location')
253
254 _temp_device = False
255
256 _properties = ManagedEntity._properties + (
257 {'id':'manageIp', 'type':'string', 'mode':'w'},
258 {'id':'snmpAgent', 'type':'string', 'mode':'w'},
259 {'id':'snmpDescr', 'type':'string', 'mode':''},
260 {'id':'snmpOid', 'type':'string', 'mode':''},
261 {'id':'snmpContact', 'type':'string', 'mode':''},
262 {'id':'snmpSysName', 'type':'string', 'mode':''},
263 {'id':'snmpLocation', 'type':'string', 'mode':''},
264 {'id':'snmpLastCollection', 'type':'date', 'mode':''},
265 {'id':'snmpAgent', 'type':'string', 'mode':''},
266 {'id':'rackSlot', 'type':'string', 'mode':'w'},
267 {'id':'comments', 'type':'text', 'mode':'w'},
268 {'id':'sysedgeLicenseMode', 'type':'string', 'mode':''},
269 {'id':'priority', 'type':'int', 'mode':'w'},
270 )
271
272 _relations = ManagedEntity._relations + (
273 ("deviceClass", ToOne(ToManyCont, "Products.ZenModel.DeviceClass",
274 "devices")),
275 ("perfServer", ToOne(ToMany, "Products.ZenModel.PerformanceConf",
276 "devices")),
277 ("location", ToOne(ToMany, "Products.ZenModel.Location", "devices")),
278 ("systems", ToMany(ToMany, "Products.ZenModel.System", "devices")),
279 ("groups", ToMany(ToMany, "Products.ZenModel.DeviceGroup", "devices")),
280 ("maintenanceWindows",ToManyCont(ToOne,
281 "Products.ZenModel.MaintenanceWindow", "productionState")),
282 ("adminRoles", ToManyCont(ToOne,"Products.ZenModel.AdministrativeRole",
283 "managedObject")),
284 ('userCommands', ToManyCont(ToOne, 'Products.ZenModel.UserCommand',
285 'commandable')),
286
287 ('monitors', ToMany(ToMany, 'Products.ZenModel.StatusMonitorConf',
288 'devices')),
289 )
290
291
292 factory_type_information = (
293 {
294 'id' : 'Device',
295 'meta_type' : 'Device',
296 'description' : """Base class for all devices""",
297 'icon' : 'Device_icon.gif',
298 'product' : 'ZenModel',
299 'factory' : 'manage_addDevice',
300 'immediate_view' : 'devicedetail',
301 'actions' :
302 (
303 {'id' : 'swdetail'
304 , 'name' : 'Software'
305 , 'action' : 'deviceSoftwareDetail'
306 , 'permissions': (ZEN_VIEW, )
307 },
308 { 'id' : 'events'
309 , 'name' : 'Events'
310 , 'action' : 'viewEvents'
311 , 'permissions' : (ZEN_VIEW, )
312 },
313 { 'id' : 'perfServer'
314 , 'name' : 'Graphs'
315 , 'action' : 'viewDevicePerformance'
316 , 'permissions' : (ZEN_VIEW, )
317 },
318 { 'id' : 'edit'
319 , 'name' : 'Edit'
320 , 'action' : 'editDevice'
321 , 'permissions' : ("Change Device",)
322 },
323 )
324 },
325 )
326
327 security = ClassSecurityInfo()
328
329 - def __init__(self, id, buildRelations=True):
339
341 flag = getattr(self, '_temp_device', None)
342 if flag is None:
343 flag = self._temp_device = False
344 return flag
345
347 """
348 Return the name of this device. Default is titleOrId.
349 """
350 return self.titleOrId()
351
352
353 security.declareProtected(ZEN_MANAGE_DMD, 'changeDeviceClass')
355 """
356 Wrapper for DeviceClass.moveDevices. The primary reason to use this
357 method instead of that one is that this one returns the new path to the
358 device.
359
360 @param deviceClassPath: device class in DMD path
361 @type deviceClassPath: string
362 @param REQUEST: Zope REQUEST object
363 @type REQUEST: Zope REQUEST object
364 """
365 self.deviceClass().moveDevices(deviceClassPath, (self.id,))
366 device = self.getDmdRoot('Devices').findDevice(self.id)
367 if sendUserAction and REQUEST:
368 sendUserAction(ActionTargetType.Device, 'SetDeviceClass',
369 device=self.getPrimaryId(),
370 deviceclass=deviceClassPath)
371 return device.absolute_url_path()
372
374 """
375 DEPRECATED
376 """
377 import warnings
378 warnings.warn('Device.getRRDTemplate is deprecated',
379 DeprecationWarning)
380 return ManagedEntity.getRRDTemplate(self)
381
383 """
384 Returns all the templates bound to this Device
385
386 @rtype: list
387
388 >>> from Products.ZenModel.Device import manage_addDevice
389 >>> manage_addDevice(devices, 'test')
390 >>> devices.test.getRRDTemplates()
391 [<RRDTemplate at /zport/dmd/Devices/rrdTemplates/Device>]
392 """
393 if not hasattr(self, 'zDeviceTemplates'):
394 return ManagedEntity.getRRDTemplates(self)
395 result = []
396 for name in self.zDeviceTemplates:
397 template = self.getRRDTemplateByName(name)
398 if template:
399 result.append(template)
400 return result
401
402
405
406
408 """
409 Returns the available DataSource options. DataSource options
410 are used to populate the dropdown when adding a new DataSource
411 and is a string. See L{RRDTemplate.RRDTemplate.getDataSourceOptions}
412 for more information.
413
414 @rtype: list
415 @return: [(displayName, dsOption),]
416 """
417
418
419
420
421
422 templates = self.getRRDTemplates()
423 if templates:
424 return templates[0].getDataSourceOptions()
425 return []
426
427
428
429
430
431
432
433
434
436 """
437 Returns the cached sysUpTime for this device
438
439 @rtype: int
440 """
441 try:
442 return self.cacheRRDValue('sysUpTime', -1)
443 except Exception:
444 log.exception("failed getting sysUpTime")
445 return -1
446
447
449 """
450 Returns the uptime of this device
451
452 @rtype: string
453 @todo: Performance enhancement: Should move import outside of method
454 """
455 from Products.ZenEvents import Availability
456 results = Availability.query(self.dmd, device=self.id, *args, **kw)
457 if results:
458 return results[0]
459 else:
460 return None
461
462
463
465 """
466 Override from object to handle lastPollSnmpUpTime and
467 snmpLastCollection
468
469 @todo: Not sure this is needed, see getLastPollSnmpUpTime and
470 getSnmpLastCollection
471 """
472 if name == 'lastPollSnmpUpTime':
473 return self._lastPollSnmpUpTime.getStatus()
474 elif name == 'snmpLastCollection':
475 return DateTime(self._snmpLastCollection)
476 else:
477 raise AttributeError( name )
478
479
481 """
482 Override from PropertyManager to handle checks and ip creation
483
484 @todo: Not sure this is needed, see setSnmpLastCollection
485 """
486 self._wrapperCheck(value)
487 if id == 'snmpLastCollection':
488 self._snmpLastCollection = float(value)
489 else:
490 ManagedEntity._setPropValue(self, id, value)
491
492
493 - def applyDataMap(self, datamap, relname="", compname="", modname=""):
500
501
503 """
504 Return a sequence of path tuples suitable for indexing by
505 a MultiPathIndex.
506 """
507 orgs = (
508 self.systems() +
509 self.groups() +
510 [self.location()] +
511 [self.deviceClass()]
512 )
513 return [ aq_base(self).__of__(o.primaryAq()).getPhysicalPath() \
514 for o in orgs if o is not None ]
515
516
518 """
519 Trace the route to target using our routing table.
520 Wrapper method of OperatingSystem.traceRoute
521
522 @param target: Device name
523 @type target: string
524 @param ippath: IP addesses
525 @type ippath: list
526 @return: IP Addresses
527 @rtype: list
528 """
529 if ippath is None: ippath=[]
530 if isinstance(target, basestring):
531 target = self.findDevice(target)
532 if not target: raise ValueError("Target %s not found in DMD" % target)
533 return self.os.traceRoute(target, ippath)
534
535
537 """
538 Return list of monitored DeviceComponents on this device.
539 Wrapper method for getDeviceComponents
540 """
541 return self.getDeviceComponents(monitored=True,
542 collector=collector, type=type)
543
544
545 security.declareProtected(ZEN_VIEW, 'getReportableComponents')
547 """
548 Return a list of DeviceComponents on this device that should be
549 considered for reporting.
550
551 @type collector: string
552 @type type: string
553 @permission: ZEN_VIEW
554 @rtype: list
555 """
556 return self.getMonitoredComponents(collector=collector, type=type);
557
558
559 security.declareProtected(ZEN_VIEW, 'getDeviceComponents')
561 """
562 Return list of all DeviceComponents on this device.
563
564 @type monitored: boolean
565 @type collector: string
566 @type type: string
567 @permission: ZEN_VIEW
568 @rtype: list
569 """
570
571
572
573
574 if not self.componentSearch._catalog.indexes.has_key('getParentDeviceName'):
575 return self.getDeviceComponentsNoIndexGen()
576
577 query = {
578 'getParentDeviceName':self.id,
579 }
580 if collector is not None:
581 query['getCollectors'] = collector
582 if monitored is not None:
583 query['monitored'] = monitored
584 if type is not None:
585 query['meta_type'] = type
586
587 return list(getObjectsFromCatalog(self.componentSearch, query, log))
588
589
591 """
592 Return a list of all device components by walking relations. This is
593 much slower then the normal getDeviceComponents method which uses the
594 component index. It is used when rebuilding the device indexes.
595 """
596 from DeviceComponent import DeviceComponent
597 for baseObject in (self, self.os, self.hw):
598 for rel in baseObject.getRelationships():
599 if rel.meta_type != "ToManyContRelationship": continue
600 for obj in rel():
601 if not isinstance(obj, DeviceComponent): break
602 for subComp in obj.getSubComponentsNoIndexGen():
603 yield subComp
604 yield obj
605
606
615
616
618 """
619 DEPRECATED - Return the hardware manufacturer name of this device.
620
621 @rtype: string
622 @todo: Remove this method and remove the call from testDevice.py
623 """
624 return self.hw.getManufacturerName()
625
626
628 """
629 Return the hardware product name of this device.
630
631 @rtype: string
632 """
633 return self.hw.getProductName()
634
636 """
637 Return the hardware product class of this device.
638
639 @rtype: string
640 """
641 cls = self.hw.productClass()
642 if cls:
643 return cls.titleOrId()
644
646 """
647 DEPRECATED - Return the productKey of the device hardware.
648
649 @rtype: string
650 @todo: Remove this method and remove the call from testDevice.py
651 """
652 return self.hw.getProductKey()
653
654
656 """
657 DEPRECATED - Return the OS manufacturer name of this device.
658
659 @rtype: string
660 @todo: Remove this method and remove the call from testDevice.py
661 """
662 return self.os.getManufacturerName()
663
664
666 """
667 DEPRECATED - Return the OS product name of this device.
668
669 @rtype: string
670 @todo: Remove this method and remove the call from testDevice.py
671 """
672 return self.os.getProductName()
673
674
676 """
677 DEPRECATED - Return the productKey of the device OS.
678
679 @rtype: string
680 @todo: Remove this method and remove the call from testDevice.py
681 """
682 return self.os.getProductKey()
683
684
686 """
687 Set the productKey of the device OS.
688 """
689 self.os.setProductKey(prodKey, manufacturer)
690 self.index_object(idxs=('getOSProductName','getOSManufacturerName'),
691 noips=True)
692
693
694
696 """
697 DEPRECATED - Return the tag of the device HW.
698
699 @rtype: string
700 @todo: remove this method and remove the call from testDevice.py
701 """
702 return self.hw.tag
703
704
706 """
707 Set the asset tag of the device hardware.
708 """
709 self.hw.tag = assettag
710 self.index_object(idxs=('getHWTag',), noips=True)
711
712
713
715 """
716 Set the productKey of the device hardware.
717 """
718 self.hw.setProductKey(prodKey, manufacturer)
719 self.index_object(idxs=('getHWProductClass','getHWManufacturerName'),
720 noips=True)
721
722
723
725 """
726 Set the hardware serial number.
727 """
728 self.hw.serialNumber = number
729 self.index_object(idxs=('getHWSerialNumber',), noips=True)
730
732 """
733 DEPRECATED - Return the hardware serial number.
734
735 @rtype: string
736 @todo: Remove this method and remove the call from testDevice.py
737 """
738 return self.hw.serialNumber
739
740
742 """
743 Return the ips that our indirect routs point to which aren't currently
744 connected to devices.
745
746 @todo: Can be moved to zendisc.py
747 """
748 ips = []
749 for r in self.os.routes():
750 ipobj = r.nexthop()
751
752 if ipobj: ips.append(ipobj.id)
753 return ips
754
755
756 security.declareProtected(ZEN_VIEW, 'getLocationName')
758 """
759 Return the full location name ie /Location/SubLocation/Rack
760
761 @rtype: string
762 @permission: ZEN_VIEW
763 """
764 loc = self.location()
765 if loc: return loc.getOrganizerName()
766 return ""
767
768 security.declareProtected(ZEN_VIEW, 'getLocationLink')
784
785
786 security.declareProtected(ZEN_VIEW, 'getSystemNames')
788 """
789 Return the system names for this device
790
791 @rtype: list
792 @permission: ZEN_VIEW
793 """
794 return map(lambda x: x.getOrganizerName(), self.systems())
795
796
797 security.declareProtected(ZEN_VIEW, 'getSystemNamesString')
799 """
800 Return the system names for this device as a string
801
802 @rtype: string
803 @permission: ZEN_VIEW
804 """
805 return sep.join(self.getSystemNames())
806
807
808 security.declareProtected(ZEN_VIEW, 'getDeviceGroupNames')
810 """
811 Return the device group names for this device
812
813 @rtype: list
814 @permission: ZEN_VIEW
815 """
816 return map(lambda x: x.getOrganizerName(), self.groups())
817
818
819 security.declareProtected(ZEN_VIEW, 'getPerformanceServer')
828
829
830 security.declareProtected(ZEN_VIEW, 'getPerformanceServerName')
841
842
847
848 security.declareProtected(ZEN_VIEW, 'getLastChange')
850 """
851 Return DateTime of last change detected on this device.
852
853 @rtype: DateTime
854 @permission: ZEN_VIEW
855 """
856 return DateTime(float(self._lastChange))
857
858
859 security.declareProtected(ZEN_VIEW, 'getLastChangeString')
861 """
862 Return date string of last change detected on this device.
863
864 @rtype: string
865 @permission: ZEN_VIEW
866 """
867 return Time.LocalDateTimeSecsResolution(float(self._lastChange))
868
869
870 security.declareProtected(ZEN_VIEW, 'getSnmpLastCollection')
872 """
873 Return DateTime of last SNMP collection on this device.
874
875 @rtype: DateTime
876 @permission: ZEN_VIEW
877 """
878 return DateTime(float(self._snmpLastCollection))
879
880
881 security.declareProtected(ZEN_VIEW, 'getSnmpLastCollectionString')
883 """
884 Return date string of last SNMP collection on this device.
885
886 @rtype: string
887 @permission: ZEN_VIEW
888 """
889 if self._snmpLastCollection:
890 return Time.LocalDateTimeSecsResolution(float(self._snmpLastCollection))
891 return "Not Modeled"
892
893
918
920 ipMatch = self.getNetworkRoot().findIp(ip)
921 if ipMatch:
922 dev = ipMatch.device()
923 if dev and self.id != dev.id:
924 return True
925 return False
926
927 security.declareProtected(ZEN_ADMIN_DEVICE, 'setManageIp')
929 """
930 Set the manage IP, if IP is not passed perform DNS lookup.
931 If there is an error with the IP address format, the IP address
932 will be reset to the result of a DNS lookup.
933
934 @rtype: string
935 @permission: ZEN_ADMIN_DEVICE
936 """
937 message = ''
938 ip = ip.replace(' ', '')
939 origip = ip
940 ip = self._sanitizeIPaddress(ip)
941
942 if not ip:
943 try:
944 ip = getHostByName(origip)
945 if ip == '0.0.0.0':
946
947 ip = ''
948 except socket.error:
949 ip = ''
950
951 if not ip:
952 try:
953 ip = getHostByName(ipunwrap(self.id))
954 except socket.error:
955 ip = ''
956 if origip:
957 message = ("%s is an invalid IP address, "
958 "and no appropriate IP could"
959 " be found via DNS for %s") % (origip, self.id)
960 log.warn(message)
961 else:
962 message = "DNS lookup of '%s' failed to return an IP" % \
963 self.id
964
965 if ip:
966 if self._isDuplicateIp(ip):
967 message = "The IP address %s is already assigned" % ip
968 log.warn(message)
969
970 else:
971 self.manageIp = ip
972 self.index_object(idxs=('ipAddressAsInt','getDeviceIp'), noips=True)
973 notify(IndexingEvent(self, ('ipAddress',), True))
974 log.info("%s's IP address has been set to %s.",
975 self.id, ip)
976 if sendUserAction and REQUEST:
977 sendUserAction(ActionTargetType.Device, 'ResetIP',
978 device=self.getPrimaryId(), ip=ip)
979
980 return message
981
982
983 security.declareProtected(ZEN_VIEW, 'getManageIp')
985 """
986 Return the management ip for this device.
987
988 @rtype: string
989 @permission: ZEN_VIEW
990 """
991 return self.manageIp
992
993
995 """
996 DEPRECATED - Return the management ipobject for this device.
997
998 @rtype: IpAddress
999 @todo: This method may not be called anywhere, remove it.
1000 """
1001 if self.manageIp:
1002 return self.Networks.findIp(self.manageIp)
1003
1004
1005 security.declareProtected(ZEN_VIEW, 'getManageInterface')
1007 """
1008 Return the management interface of a device based on its manageIp.
1009
1010 @rtype: IpInterface
1011 @permission: ZEN_VIEW
1012 """
1013 ipobj = self.Networks.findIp(self.manageIp)
1014 if ipobj: return ipobj.interface()
1015
1016
1017 security.declareProtected(ZEN_VIEW, 'uptimeStr')
1019 """
1020 Return the SNMP uptime
1021
1022 @rtype: string
1023 @permission: ZEN_VIEW
1024 """
1025 ut = self.sysUpTime()
1026
1027 if ut < 0 or ut != ut:
1028 return "Unknown"
1029 elif ut == 0:
1030 return "0d:0h:0m:0s"
1031 ut = float(ut)/100.
1032 days = int(ut/86400)
1033 hour = int((ut%86400)/3600)
1034 mins = int((ut%3600)/60)
1035 secs = int(ut%60)
1036 return "%02dd:%02dh:%02dm:%02ds" % (
1037 days, hour, mins, secs)
1038
1039
1041 """
1042 Build a list of all device paths that have the python class pyclass
1043
1044 @rtype: list
1045 """
1046 dclass = self.getDmdRoot("Devices")
1047 return dclass.getPeerDeviceClassNames(self.__class__)
1048
1049
1050
1051
1052
1053
1054 security.declareProtected(ZEN_CHANGE_DEVICE, 'manage_snmpCommunity')
1056 """
1057 Reset the snmp community using the zSnmpCommunities variable.
1058
1059 @permission: ZEN_CHANGE_DEVICE
1060 """
1061 try:
1062 zSnmpCommunity, zSnmpPort, zSnmpVer, snmpname = \
1063 findCommunity(self, self.manageIp, self.getDeviceClassPath(),
1064 port=self.zSnmpPort, version=self.zSnmpVer)
1065 except NoSnmp:
1066 pass
1067 else:
1068 if self.zSnmpCommunity != zSnmpCommunity:
1069 self.setZenProperty("zSnmpCommunity", zSnmpCommunity)
1070 if self.zSnmpPort != zSnmpPort:
1071 self.setZenProperty("zSnmpPort", zSnmpPort)
1072 if self.zSnmpVer != zSnmpVer:
1073 self.setZenProperty("zSnmpVer", zSnmpVer)
1074
1075 - def setProductInfo(self, hwManufacturer="", hwProductName="",
1076 osManufacturer="", osProductName=""):
1077 if hwManufacturer and hwProductName:
1078
1079
1080 if hwManufacturer != "_no_change" and hwProductName != "_no_change":
1081 log.info("setting hardware manufacturer to %r productName to %r"
1082 % (hwManufacturer, hwProductName))
1083 self.hw.setProduct(hwProductName, hwManufacturer)
1084 else:
1085 self.hw.productClass.removeRelation()
1086
1087 if osManufacturer and osProductName:
1088
1089
1090 if osManufacturer != "_no_change" and osProductName != "_no_change":
1091 log.info("setting os manufacturer to %r productName to %r"
1092 % (osManufacturer, osProductName))
1093 self.os.setProduct(osProductName, osManufacturer)
1094 self.os.productClass().isOS = True
1095 else:
1096 self.os.productClass.removeRelation()
1097
1098
1099 security.declareProtected(ZEN_CHANGE_DEVICE, 'updateDevice')
1101 """
1102 Update the device relation and attributes, if passed. If any parameter
1103 is not passed it will not be updated; the value of any unpassed device
1104 propeties will remain the same.
1105
1106 @permission: ZEN_CHANGE_DEVICE
1107 Keyword arguments:
1108 title -- device title [string]
1109 tag -- tag number [string]
1110 serialNumber -- serial number [string]
1111 zProperties -- dict of zProperties [dict]
1112 zSnmpCommunity -- snmp community (overrides corresponding value is zProperties) [string]
1113 zSnmpPort -- snmp port (overrides corresponding value in zProperties) [string]
1114 zSnmpVer -- snmp version (overrides corresponding value in zProperties) [string]
1115 rackSlot -- rack slot number [integer]
1116 productionState -- production state of device [integer]
1117 priority -- device priority [integer]
1118 comment -- device comment [string]
1119 hwManufacturer -- hardware manufacturer [string]
1120 hwProductName -- hardware product name [string]
1121 osManufacturer -- operating system manufacturer [string]
1122 osProductName -- operating system name [string]
1123 locationPath -- location [string]
1124 groupPaths -- group paths [list]
1125 systemPaths -- systen paths [list]
1126 performanceMonitor -- collector name [string]
1127
1128 """
1129 if 'title' in kwargs and kwargs['title'] is not None:
1130 log.info("setting title to %r" % kwargs['title'])
1131 self.title = kwargs['title']
1132 if 'tag' in kwargs and kwargs['tag'] is not None:
1133 log.info("setting tag to %r" % kwargs['tag'])
1134 self.hw.tag = kwargs['tag']
1135 if 'serialNumber' in kwargs and kwargs['serialNumber'] is not None:
1136 log.info("setting serialNumber to %r" % kwargs['serialNumber'])
1137 self.hw.serialNumber = kwargs['serialNumber']
1138
1139
1140 if 'zProperties' in kwargs and kwargs['zProperties'] is not None:
1141 zProperties = kwargs['zProperties']
1142 else:
1143 zProperties = {}
1144
1145
1146 zpropUpdate = dict((name, kwargs[name]) for name in ('zSnmpCommunity', 'zSnmpPort', 'zSnmpVer')
1147 if name in kwargs)
1148 zProperties.update(zpropUpdate)
1149
1150
1151 for prop, value in zProperties.items():
1152 if value and getattr(self, prop) != value:
1153 self.setZenProperty(prop, value)
1154
1155 if 'rackSlot' in kwargs:
1156 log.info("setting rackSlot to %r" % kwargs["rackSlot"])
1157 self.rackSlot = kwargs["rackSlot"]
1158
1159 if 'productionState' in kwargs:
1160 log.info("setting productionState to %r" % kwargs["productionState"])
1161 self.setProdState(kwargs["productionState"])
1162
1163 if 'priority' in kwargs:
1164 log.info("setting priority to %r" % kwargs["priority"])
1165 self.setPriority(kwargs["priority"])
1166
1167 if 'comments' in kwargs:
1168 log.info("setting comments to %r" % kwargs["comments"])
1169 self.comments = kwargs["comments"]
1170
1171 self.setProductInfo(hwManufacturer=kwargs.get("hwManufacturer","_no_change"),
1172 hwProductName=kwargs.get("hwProductName","_no_change"),
1173 osManufacturer=kwargs.get("osManufacturer","_no_change"),
1174 osProductName=kwargs.get("osProductName","_no_change"))
1175
1176 if kwargs.get("locationPath", False):
1177 log.info("setting location to %r" % kwargs["locationPath"])
1178 self.setLocation(kwargs["locationPath"])
1179
1180 if kwargs.get("groupPaths",False):
1181 log.info("setting group %r" % kwargs["groupPaths"])
1182 self.setGroups(kwargs["groupPaths"])
1183
1184 if kwargs.get("systemPaths",False):
1185 log.info("setting system %r" % kwargs["systemPaths"])
1186 self.setSystems(kwargs["systemPaths"])
1187
1188 if 'performanceMonitor' in kwargs and \
1189 kwargs["performanceMonitor"] != self.getPerformanceServerName():
1190 log.info("setting performance monitor to %r" \
1191 % kwargs["performanceMonitor"])
1192 self.setPerformanceMonitor(kwargs["performanceMonitor"])
1193
1194 self.setLastChange()
1195 self.index_object()
1196 notify(IndexingEvent(self))
1197
1198 security.declareProtected(ZEN_CHANGE_DEVICE, 'manage_editDevice')
1199 - def manage_editDevice(self,
1200 tag="", serialNumber="",
1201 zSnmpCommunity="", zSnmpPort=161, zSnmpVer="",
1202 rackSlot="", productionState=1000, comments="",
1203 hwManufacturer="", hwProductName="",
1204 osManufacturer="", osProductName="",
1205 locationPath="", groupPaths=[], systemPaths=[],
1206 performanceMonitor="localhost", priority=3,
1207 zProperties=None, title=None, REQUEST=None):
1208 """
1209 Edit the device relation and attributes. This method will update device
1210 properties because of the default values that are passed. Calling this
1211 method using a **kwargs dict will result in default values being set for
1212 many device properties. To update only a subset of these properties use
1213 updateDevice(**kwargs).
1214
1215 @param locationPath: path to a Location
1216 @type locationPath: string
1217 @param groupPaths: paths to DeviceGroups
1218 @type groupPaths: list
1219 @param systemPaths: paths to Systems
1220 @type systemPaths: list
1221 @param performanceMonitor: name of PerformanceMonitor
1222 @type performanceMonitor: string
1223 @permission: ZEN_CHANGE_DEVICE
1224 """
1225 self.updateDevice(
1226 tag=tag, serialNumber=serialNumber,
1227 zSnmpCommunity=zSnmpCommunity, zSnmpPort=zSnmpPort, zSnmpVer=zSnmpVer,
1228 rackSlot=rackSlot, productionState=productionState, comments=comments,
1229 hwManufacturer=hwManufacturer, hwProductName=hwProductName,
1230 osManufacturer=osManufacturer, osProductName=osProductName,
1231 locationPath=locationPath, groupPaths=groupPaths, systemPaths=systemPaths,
1232 performanceMonitor=performanceMonitor, priority=priority,
1233 zProperties=zProperties, title=title, REQUEST=REQUEST)
1234 if REQUEST:
1235 from Products.ZenUtils.Time import SaveMessage
1236 IMessageSender(self).sendToBrowser("Saved", SaveMessage())
1237 if sendUserAction:
1238
1239
1240
1241 sendUserAction(
1242 ActionTargetType.Device, 'Edit', device=self.getPrimaryId())
1243 return self.callZenScreen(REQUEST)
1244
1245
1247 """
1248 Changes the title to newTitle and reindexes the object
1249 """
1250 super(Device, self).setTitle(newTitle)
1251 self.index_object()
1252 notify(IndexingEvent(self, ('name',), True))
1253
1255 """
1256 Returns true if the device production state >= zProdStateThreshold.
1257
1258 @rtype: boolean
1259 """
1260 return self.productionState >= self.zProdStateThreshold
1261
1262
1264 """
1265 Returns true if the device is subject to SNMP monitoring
1266
1267 @rtype: boolean
1268 """
1269 return (self.monitorDevice()
1270 and self.getManageIp()
1271 and not self.zSnmpMonitorIgnore)
1272
1273
1275 """
1276 Return the numeric device priority.
1277
1278 @rtype: int
1279 """
1280 return self.priority
1281
1282
1284 """
1285 Return the device priority as a string.
1286
1287 @rtype: string
1288 """
1289 return self.convertPriority(self.priority)
1290
1292 """
1293 Return the pingStatus as a string
1294
1295 @rtype: string
1296 """
1297 return self.convertStatus(self.getPingStatus())
1298
1300 """
1301 Return the snmpStatus as a string
1302
1303 @rtype: string
1304 """
1305 return self.convertStatus(self.getSnmpStatus())
1306
1307 security.declareProtected(ZEN_CHANGE_DEVICE_PRODSTATE, 'setProdState')
1308 - def setProdState(self, state, maintWindowChange=False, REQUEST=None):
1309 """
1310 Set the device's production state.
1311
1312 @parameter state: new production state
1313 @type state: int
1314 @parameter maintWindowChange: are we resetting state from inside a MW?
1315 @type maintWindowChange: boolean
1316 @permission: ZEN_CHANGE_DEVICE
1317 """
1318
1319 ret = super(Device, self).setProdState(state, maintWindowChange, REQUEST)
1320 for component in self.getDeviceComponents():
1321 if isinstance(component, ManagedEntity) and self.productionState == component.productionState:
1322 notify(IndexingEvent(component.primaryAq(), ('productionState',), True))
1323 if sendUserAction and REQUEST:
1324 sendUserAction(ActionTargetType.Device, 'EditProductionState',
1325 device=self.getPrimaryId(),
1326 productionState=state,
1327 maintenanceWindowChange=maintWindowChange)
1328 return ret
1329
1330 security.declareProtected(ZEN_CHANGE_DEVICE, 'setPriority')
1349
1350 security.declareProtected(ZEN_CHANGE_DEVICE, 'setLastChange')
1352 """
1353 Set the changed datetime for this device.
1354
1355 @param value: secs since the epoch, default is now
1356 @type value: float
1357 @permission: ZEN_CHANGE_DEVICE
1358 """
1359 if value is None:
1360 value = time.time()
1361 self._lastChange = float(value)
1362
1363 security.declareProtected(ZEN_CHANGE_DEVICE, 'setSnmpLastCollection')
1365 """
1366 Set the last time snmp collection occurred.
1367
1368 @param value: secs since the epoch, default is now
1369 @type value: float
1370 @permission: ZEN_CHANGE_DEVICE
1371 """
1372 if value is None:
1373 value = time.time()
1374 self._snmpLastCollection = float(value)
1375
1376
1377 security.declareProtected(ZEN_CHANGE_DEVICE, 'addManufacturer')
1378 - def addManufacturer(self, newHWManufacturerName=None,
1379 newSWManufacturerName=None, REQUEST=None):
1380 """
1381 DEPRECATED -
1382 Add either a hardware or software manufacturer to the database.
1383
1384 @permission: ZEN_CHANGE_DEVICE
1385 @todo: Doesn't really do work on a device object.
1386 Already exists on ZDeviceLoader
1387 """
1388 mname = newHWManufacturerName
1389 field = 'hwManufacturer'
1390 if not mname:
1391 mname = newSWManufacturerName
1392 field = 'osManufacturer'
1393 self.getDmdRoot("Manufacturers").createManufacturer(mname)
1394 if REQUEST:
1395 REQUEST[field] = mname
1396 messaging.IMessageSender(self).sendToBrowser(
1397 'Manufacturer Added',
1398 'The %s manufacturer has been created.' % mname
1399 )
1400 if sendUserAction:
1401 sendUserAction(ActionTargetType.Device, 'AddManufacturer',
1402 device=self.getPrimaryId(),
1403 manufacturer=mname)
1404 return self.callZenScreen(REQUEST)
1405
1406
1407 security.declareProtected(ZEN_CHANGE_DEVICE, 'setHWProduct')
1408 - def setHWProduct(self, newHWProductName=None, hwManufacturer=None,
1409 REQUEST=None):
1410 """
1411 DEPRECATED -
1412 Adds a new hardware product
1413
1414 @permission: ZEN_CHANGE_DEVICE
1415 @todo: Doesn't really do work on a device object.
1416 Already exists on ZDeviceLoader
1417 """
1418 added = False
1419 if newHWProductName and hwManufacturer:
1420 self.getDmdRoot("Manufacturers").createHardwareProduct(
1421 newHWProductName, hwManufacturer)
1422 added = True
1423 if REQUEST:
1424 if added:
1425 messaging.IMessageSender(self).sendToBrowser(
1426 'Product Set',
1427 'Hardware product has been set to %s.' % newHWProductName
1428 )
1429 REQUEST['hwProductName'] = newHWProductName
1430 if sendUserAction:
1431 sendUserAction(ActionTargetType.Device, 'SetHWProduct',
1432 device=self.getPrimaryId(),
1433 manufacturer=hwManufacturer,
1434 product=newHWProductName)
1435 else:
1436 messaging.IMessageSender(self).sendToBrowser(
1437 'Set Product Failed',
1438 'Hardware product could not be set to %s.'%newHWProductName,
1439 priority=messaging.WARNING
1440 )
1441 return self.callZenScreen(REQUEST)
1442
1443
1444 security.declareProtected(ZEN_CHANGE_DEVICE, 'setOSProduct')
1445 - def setOSProduct(self, newOSProductName=None, osManufacturer=None, REQUEST=None):
1446 """
1447 DEPRECATED
1448 Adds a new os product
1449
1450 @permission: ZEN_CHANGE_DEVICE
1451 @todo: Doesn't really do work on a device object.
1452 Already exists on ZDeviceLoader
1453 """
1454 if newOSProductName:
1455 self.getDmdRoot("Manufacturers").createSoftwareProduct(
1456 newOSProductName, osManufacturer, isOS=True)
1457 if REQUEST:
1458 if newOSProductName:
1459 messaging.IMessageSender(self).sendToBrowser(
1460 'Product Set',
1461 'OS product has been set to %s.' % newOSProductName
1462 )
1463 REQUEST['osProductName'] = newOSProductName
1464 if sendUserAction:
1465 sendUserAction(ActionTargetType.Device, 'SetOSProduct',
1466 device=self.getPrimaryId(),
1467 manufacturer=osManufacturer,
1468 product=newOSProductName)
1469 else:
1470 messaging.IMessageSender(self).sendToBrowser(
1471 'Set Product Failed',
1472 'OS product could not be set to %s.' % newOSProductName,
1473 priority=messaging.WARNING
1474 )
1475 return self.callZenScreen(REQUEST)
1476
1477
1478 security.declareProtected(ZEN_CHANGE_DEVICE, 'setLocation')
1480 """
1481 Set the location of a device. If the location is new it will be created.
1482
1483 @permission: ZEN_CHANGE_DEVICE
1484 """
1485 if not locationPath:
1486 self.location.removeRelation()
1487 else:
1488 locobj = self.getDmdRoot("Locations").createOrganizer(locationPath)
1489 self.addRelation("location", locobj)
1490 self.setAdminLocalRoles()
1491 self.index_object()
1492 notify(IndexingEvent(self, 'path', False))
1493 if sendUserAction and REQUEST:
1494 action = 'SetLocation' if locationPath else 'RemoveFromLocation'
1495 sendUserAction(ActionTargetType.Device, action,
1496 device=self.getPrimaryId(),
1497 location=locationPath)
1498
1499
1500 - def addLocation(self, newLocationPath, REQUEST=None):
1501 """
1502 DEPRECATED
1503 Add a new location and relate it to this device
1504
1505 @todo: Doesn't really do work on a device object.
1506 Already exists on ZDeviceLoader
1507 """
1508 self.getDmdRoot("Locations").createOrganizer(newLocationPath)
1509 if REQUEST:
1510 REQUEST['locationPath'] = newLocationPath
1511 messaging.IMessageSender(self).sendToBrowser(
1512 'Location Added',
1513 'Location %s has been created.' % newLocationPath
1514 )
1515 if sendUserAction:
1516 sendUserAction(ActionTargetType.Device, 'SetLocation',
1517 device=self.getPrimaryId(),
1518 location=newLocationPath)
1519 return self.callZenScreen(REQUEST)
1520
1521
1522 security.declareProtected(ZEN_CHANGE_DEVICE, 'setPerformanceMonitor')
1551
1552
1553 security.declareProtected(ZEN_CHANGE_DEVICE, 'setGroups')
1555 """
1556 Set the list of groups for this device based on a list of paths
1557
1558 @permission: ZEN_CHANGE_DEVICE
1559 """
1560 objGetter = self.getDmdRoot("Groups").createOrganizer
1561 self._setRelations("groups", objGetter, groupPaths)
1562 self.index_object()
1563 notify(IndexingEvent(self, 'path', False))
1564
1565
1566 security.declareProtected(ZEN_CHANGE_DEVICE, 'addDeviceGroup')
1568 """
1569 DEPRECATED?
1570 Add a device group to the database and this device
1571
1572 @permission: ZEN_CHANGE_DEVICE
1573 @todo: Already exists on ZDeviceLoader
1574 """
1575 group = self.getDmdRoot("Groups").createOrganizer(newDeviceGroupPath)
1576 self.addRelation("groups", group)
1577 if REQUEST:
1578 messaging.IMessageSender(self).sendToBrowser(
1579 'Group Added',
1580 'Group %s has been created.' % newDeviceGroupPath
1581 )
1582 if sendUserAction:
1583 sendUserAction(ActionTargetType.Device, 'AddToGroup',
1584 device=self.getPrimaryId(),
1585 group=newDeviceGroupPath)
1586 return self.callZenScreen(REQUEST)
1587
1588
1589 security.declareProtected(ZEN_CHANGE_DEVICE, 'setSystems')
1591 """
1592 Set a list of systems to this device using their system paths
1593
1594 @permission: ZEN_CHANGE_DEVICE
1595 """
1596 objGetter = self.getDmdRoot("Systems").createOrganizer
1597 self._setRelations("systems", objGetter, systemPaths)
1598 self.index_object()
1599 notify(IndexingEvent(self, 'path', False))
1600
1601
1602 security.declareProtected(ZEN_CHANGE_DEVICE, 'addSystem')
1603 - def addSystem(self, newSystemPath, REQUEST=None):
1623
1624
1625 security.declareProtected(ZEN_CHANGE_DEVICE, 'setTerminalServer')
1627 """
1628 Set the terminal server of this device
1629
1630 @param termservername: device name of terminal server
1631 @permission: ZEN_CHANGE_DEVICE
1632 """
1633 termserver = self.findDevice(termservername)
1634 if termserver:
1635 self.addRelation('termserver', termserver)
1636
1637
1639 """
1640 Set related objects to this device
1641
1642 @param relName: name of the relation to set
1643 @param objGetter: method to get the relation
1644 @param relPaths: list of relationship paths
1645 """
1646 if not isinstance(relPaths, (list, tuple)):
1647 relPaths = [relPaths,]
1648 relPaths = filter(lambda x: x.strip(), relPaths)
1649 rel = getattr(self, relName, None)
1650 if not rel:
1651 raise AttributeError( "Relation %s not found" % relName)
1652 curRelIds = {}
1653 for value in rel.objectValuesAll():
1654 curRelIds[value.getOrganizerName()] = value
1655 for path in relPaths:
1656 if not path in curRelIds:
1657 robj = objGetter(path)
1658 self.addRelation(relName, robj)
1659 else:
1660 del curRelIds[path]
1661 for obj in curRelIds.values():
1662 self.removeRelation(relName, obj)
1663 self.setAdminLocalRoles()
1664
1665
1667 """
1668 Return the expanded zComment property
1669
1670 @rtype: HTML output
1671 """
1672 from Products.ZenUtils.ZenTales import talesEval
1673 try:
1674 return talesEval('string:' + self.zLinks, self)
1675 except Exception, ex:
1676 import cgi
1677 return "<i class='errortitle'>%s</i>" % cgi.escape(str(ex))
1678
1679
1680
1681
1682
1683 security.declareProtected(ZEN_VIEW, 'device')
1685 """
1686 Support DeviceResultInt mixin class. Returns itself
1687
1688 @permission: ZEN_VIEW
1689 """
1690 return self
1691
1692
1693
1694
1695
1696
1697
1699 """
1700 Returns true if the device has more SNMP failures
1701 than maxFailures on its status mon.
1702
1703 @rtype: boolean
1704 """
1705 statusmon = self.monitors()
1706 if len(statusmon) > 0:
1707 statusmon = statusmon[0]
1708 return statusmon.maxFailures < self.getSnmpStatusNumber()
1709 return False
1710
1711
1712
1713 security.declareProtected(ZEN_MANAGE_DEVICE_STATUS,
1714 'getLastPollSnmpUpTime')
1716 """
1717 Get the value of the snmpUpTime status object
1718
1719 @permission: ZEN_MANAGE_DEVICE_STATUS
1720 """
1721 return self._lastPollSnmpUpTime.getStatus()
1722
1723
1724
1725 security.declareProtected(ZEN_MANAGE_DEVICE_STATUS,
1726 'setLastPollSnmpUpTime')
1728 """
1729 Set the value of the snmpUpTime status object
1730
1731 @permission: ZEN_MANAGE_DEVICE_STATUS
1732 """
1733 self._lastPollSnmpUpTime.setStatus(value)
1734
1735
1736 - def snmpAgeCheck(self, hours):
1737 """
1738 Returns True if SNMP data was collected more than 24 hours ago
1739 """
1740 lastcoll = self.getSnmpLastCollection()
1741 hours = hours/24.0
1742 if DateTime() > lastcoll + hours: return 1
1743
1744
1746 """
1747 Apply zProperties inherited from Product Contexts.
1748 """
1749 self._applyProdContext(self.hw.getProductContext())
1750 self._applyProdContext(self.os.getProductContext())
1751 for soft in self.os.software():
1752 self._applyProdContext(soft.getProductContext())
1753
1754
1755 - def _applyProdContext(self, context):
1756 """
1757 Apply zProperties taken for the product context passed in.
1758
1759 @param context: list of tuples returned from
1760 getProductContext on a MEProduct.
1761 """
1762 for name, value in context:
1763 if name == "zDeviceClass" and value:
1764 log.info("move device to %s", value)
1765 self.moveDevices(value, self.id)
1766 elif name == "zDeviceGroup" and value:
1767 log.info("add device to group %s", value)
1768 self.addDeviceGroup(value)
1769 elif name == "zSystem" and value:
1770 log.info("add device to system %s", value)
1771 self.addSystem(value)
1772
1773
1774
1775
1776
1777
1778
1779 security.declareProtected(ZEN_MANAGE_DEVICE, 'collectDevice')
1780 - def collectDevice(self, setlog=True, REQUEST=None, generateEvents=False,
1781 background=False, write=None):
1782 """
1783 Collect the configuration of this device AKA Model Device
1784
1785 @param setlog: If true, set up the output log of this process
1786 @permission: ZEN_MANAGE_DEVICE
1787 @todo: generateEvents param is not being used.
1788 """
1789 unused(generateEvents)
1790 xmlrpc = isXmlRpc(REQUEST)
1791 perfConf = self.getPerformanceServer()
1792 if perfConf is None:
1793 msg = "Device %s in unknown state -- remove and remodel" % self.titleOrId()
1794 if write is not None:
1795 write(msg)
1796 log.error("Unable to get collector info: %s", msg)
1797 if xmlrpc: return 1
1798 return
1799
1800 perfConf.collectDevice(self, setlog, REQUEST, generateEvents,
1801 background, write)
1802
1803 if sendUserAction and REQUEST:
1804 sendUserAction(ActionTargetType.Device, 'Remodel',
1805 device=self.getPrimaryId())
1806 if xmlrpc: return 0
1807
1808
1809 security.declareProtected(ZEN_DELETE_DEVICE, 'deleteDevice')
1810 - def deleteDevice(self, deleteStatus=False, deleteHistory=False,
1811 deletePerf=False, REQUEST=None):
1812 """
1813 Delete device from the database
1814
1815 NB: deleteHistory is disabled for the 2.2 release. In some
1816 circumstances it was causing many subprocesses to be spawned
1817 and creating a gridlock situation.
1818
1819 NOTE: deleteStatus no longer deletes events from the summary
1820 table, but closes them.
1821
1822 @permission: ZEN_ADMIN_DEVICE
1823 """
1824 parent = self.getPrimaryParent()
1825 if deleteStatus:
1826
1827 zep = getFacade('zep')
1828 tagFilter = { 'tag_uuids': [IGlobalIdentifier(self).getGUID()] }
1829 eventFilter = { 'tag_filter': [ tagFilter ] }
1830 log.debug("Closing events for device: %s", self.getId())
1831 zep.closeEventSummaries(eventFilter=eventFilter)
1832 if deletePerf:
1833 perfserv = self.getPerformanceServer()
1834 if perfserv:
1835 perfserv.deleteRRDFiles(self.id)
1836 parent._delObject(self.getId())
1837 if REQUEST:
1838 if parent.getId()=='devices':
1839 parent = parent.getPrimaryParent()
1840 if sendUserAction:
1841 sendUserAction(ActionTargetType.Device, ActionName.Delete,
1842 device=self.getPrimaryId(),
1843 deleteStatus=deleteStatus,
1844 deleteHistory=deleteHistory,
1845 deletePerf=deletePerf)
1846 REQUEST['RESPONSE'].redirect(parent.absolute_url() +
1847 "/deviceOrganizerStatus"
1848 '?message=Device deleted')
1849
1850
1851 security.declareProtected(ZEN_ADMIN_DEVICE, 'renameDevice')
1853 """
1854 Rename device from the DMD. Disallow assignment of
1855 an id that already exists in the system.
1856
1857 @permission: ZEN_ADMIN_DEVICE
1858 @param newId: new name
1859 @type newId: string
1860 @param REQUEST: Zope REQUEST object
1861 @type REQUEST: Zope REQUEST object
1862 """
1863 parent = self.getPrimaryParent()
1864 path = self.absolute_url_path()
1865 oldId = self.getId()
1866 if newId is None:
1867 return path
1868
1869 if not isinstance(newId, unicode):
1870 newId = self.prepId(newId)
1871
1872 newId = newId.strip()
1873
1874 if newId == '' or newId == oldId:
1875 return path
1876
1877 device = self.dmd.Devices.findDeviceByIdExact( newId )
1878 if device:
1879 message = 'Device already exists with id %s' % newId
1880 raise DeviceExistsError( message, device )
1881
1882
1883 try:
1884
1885
1886 if self.title:
1887 self.title = newId
1888 parent.manage_renameObject(oldId, newId)
1889 self.renameDeviceInPerformance(oldId, newId)
1890 self.setLastChange()
1891 if sendUserAction and REQUEST:
1892 sendUserAction(ActionTargetType.Device, ActionName.Rename,
1893 device=self.getPrimaryId(), old=oldId)
1894
1895 return self.absolute_url_path()
1896
1897 except CopyError, e:
1898 raise Exception("Device rename failed.")
1899
1920
1921
1931
1932
1939
1940
1942 """
1943 IpAddresses aren't contained underneath Device, so manage_beforeDelete
1944 won't propagate. Thus we must remove those links explicitly.
1945 """
1946 cat = self.dmd.ZenLinkManager._getCatalog(layer=3)
1947 brains = cat(deviceId=self.id)
1948 for brain in brains:
1949 brain.getObject().unindex_links()
1950
1951
1971
1972
1974 """
1975 Called by Commandable.doCommand() to ascertain objects on which
1976 a UserCommand should be executed.
1977 """
1978 return [self]
1979
1988
1990 """
1991 Returns a URL to redirect to after a command has executed
1992 used by Commandable
1993 """
1994 return self.getPrimaryUrlPath() + '/deviceManagement'
1995
1997 """
1998 Returns HTML Event Summary of a device
1999 """
2000 html = []
2001 html.append("<table width='100%' cellspacing='1' cellpadding='3'>")
2002 html.append("<tr>")
2003 def evsummarycell(ev):
2004 if ev[1]-ev[2]>=0: klass = '%s empty thin' % ev[0]
2005 else: klass = '%s thin' % ev[0]
2006 h = '<th align="center" width="16%%" class="%s">%s/%s</th>' % (
2007 klass, ev[1], ev[2])
2008 return h
2009 info = self.getEventSummary(severity)
2010 html += map(evsummarycell, info)
2011 html.append('</tr></table>')
2012 return '\n'.join(html)
2013
2015 """
2016 Returns data ready for serialization
2017 """
2018 url, classurl = map(urlquote,
2019 (self.getDeviceUrl(), self.getDeviceClassPath()))
2020 id = '<a class="tablevalues" href="%s">%s</a>' % (
2021 url, self.titleOrId())
2022 ip = self.getDeviceIp()
2023 if self.checkRemotePerm(ZEN_VIEW, self.deviceClass()):
2024 path = '<a href="/zport/dmd/Devices%s">%s</a>' % (classurl,classurl)
2025 else:
2026 path = classurl
2027 prod = self.getProdState()
2028 evsum = getEventPillME(self, 1, minSeverity)[0]
2029 return [id, ip, path, prod, evsum, self.id]
2030
2032 """
2033 Add export of our child objects.
2034 """
2035 map(lambda o: o.exportXml(ofile, ignorerels), (self.hw, self.os))
2036
2038 """
2039 Returns a list of possible options for a given zProperty
2040 """
2041 if propname == 'zCollectorPlugins':
2042 from Products.DataCollector.Plugins import loadPlugins
2043 names = [ldr.pluginName for ldr in loadPlugins(self.dmd)]
2044 names.sort()
2045 return names
2046 if propname == 'zCommandProtocol':
2047 return ['ssh', 'telnet']
2048 if propname == 'zSnmpVer':
2049 return ['v1', 'v2c', 'v3']
2050 if propname == 'zSnmpAuthType':
2051 return ['', 'MD5', 'SHA']
2052 if propname == 'zSnmpPrivType':
2053 return ['', 'DES', 'AES']
2054 return ManagedEntity.zenPropertyOptions(self, propname)
2055
2056 security.declareProtected(ZEN_MANAGE_DEVICE, 'pushConfig')
2058 """
2059 This will result in a push of all the devices to live collectors
2060
2061 @permission: ZEN_MANAGE_DEVICE
2062 """
2063 self._p_changed = True
2064 if REQUEST:
2065 messaging.IMessageSender(self).sendToBrowser(
2066 'Changes Pushed',
2067 'Changes to %s pushed to collectors.' % self.id
2068 )
2069 if sendUserAction:
2070 sendUserAction(ActionTargetType.Device, 'PushChanges',
2071 device=self.getPrimaryId())
2072 return self.callZenScreen(REQUEST)
2073
2074 security.declareProtected(ZEN_EDIT_LOCAL_TEMPLATES, 'bindTemplates')
2076 """
2077 This will bind available templates to the zDeviceTemplates
2078
2079 @permission: ZEN_EDIT_LOCAL_TEMPLATES
2080 """
2081 result = self.setZenProperty('zDeviceTemplates', ids, REQUEST)
2082 if sendUserAction and REQUEST:
2083 sendUserAction(ActionTargetType.Device, 'BindTemplates',
2084 device=self.getPrimaryId(), templates=ids)
2085 return result
2086
2087 security.declareProtected(ZEN_EDIT_LOCAL_TEMPLATES, 'removeZDeviceTemplates')
2104
2105 security.declareProtected(ZEN_EDIT_LOCAL_TEMPLATES, 'addLocalTemplate')
2125
2127 """
2128 Returns all available templates for this device
2129 """
2130
2131 templates = self.objectValues('RRDTemplate')
2132
2133
2134 templates += [t for t in self.deviceClass().getRRDTemplates()
2135 if t.id not in [r.id for r in templates]]
2136 def cmpTemplates(a, b):
2137 return cmp(a.id.lower(), b.id.lower())
2138 templates.sort(cmpTemplates)
2139 return [ t for t in templates
2140 if isinstance(self, t.getTargetPythonClass()) ]
2141
2142
2143 security.declareProtected(ZEN_VIEW, 'getLinks')
2158
2159 security.declareProtected(ZEN_VIEW, 'getXMLEdges')
2160 - def getXMLEdges(self, depth=3, filter="/", start=()):
2168
2169 security.declareProtected(ZEN_VIEW, 'getPrettyLink')
2171 """
2172 Gets a link to this device, plus an icon
2173
2174 @rtype: HTML text
2175 @permission: ZEN_VIEW
2176 """
2177 template = ("<div class='device-icon-container'>"
2178 "<img class='device-icon' src='%s'/> "
2179 "</div>%s")
2180 icon = self.getIconPath()
2181 href = altHref if altHref else self.getPrimaryUrlPath()
2182 name = self.titleOrId()
2183
2184 rendered = template % (icon, name)
2185
2186 if not self.checkRemotePerm(ZEN_VIEW, self):
2187 return rendered
2188 else:
2189 return "<a %s href='%s' class='prettylink'>%s</a>" % \
2190 ('target=' + target if target else '', href, rendered)
2191
2192
2194 """
2195 Get a list of dictionaries containing everything needed to match
2196 processes against the global list of process classes. Used by process
2197 modeler plugins.
2198 """
2199 matchers = []
2200 for pc in self.getDmdRoot("Processes").getSubOSProcessClassesSorted():
2201 matchers.append({
2202 'regex': pc.regex,
2203 'ignoreParameters': pc.ignoreParameters,
2204 'getPrimaryDmdId': pc.getPrimaryDmdId(),
2205 })
2206
2207 return matchers
2208
2210 """
2211 Returns either 4 or 6 depending on the version
2212 of the manageIp ip adddress
2213 """
2214 from ipaddr import IPAddress
2215 try:
2216 ip = self.getManageIp()
2217 return IPAddress(ip).version
2218 except ValueError:
2219
2220 pass
2221
2222 return 4
2223
2225 """
2226 This method gets the ip address prefix used for this device when running
2227 snmpwalk.
2228 @rtype: string
2229 @return: Prefix used for snmwalk for this device
2230 """
2231 if self.manageIpVersion() == 6:
2232 return "udp6:"
2233 return ""
2234
2236 """
2237 Used by the user commands this returns which ping command
2238 this device should use.
2239 @rtype: string
2240 @return "ping" or "ping6" depending on if the manageIp is ipv6 or not
2241 """
2242 if self.manageIpVersion() == 6:
2243 return "ping6"
2244 return "ping"
2245
2247 """
2248 Used by the user commands this returns which traceroute command
2249 this device should use.
2250 @rtype: string
2251 @return "traceroute" or "traceroute6" depending on if the manageIp is ipv6 or not
2252 """
2253 if self.manageIpVersion() == 6:
2254 return "traceroute6"
2255 return "traceroute"
2256
2319
2320 - def getStatus(self, statusclass=None, **kwargs):
2321 """
2322 Return the status number for this device of class statClass.
2323 """
2324 from Products.ZenEvents.ZenEventClasses import Status_Ping
2325 if statusclass == Status_Ping:
2326 from Products.Zuul import getFacade
2327 from Products.ZenEvents.events2.proxy import EventProxy
2328 from zenoss.protocols.protobufs.zep_pb2 import STATUS_NEW, STATUS_ACKNOWLEDGED, \
2329 SEVERITY_CRITICAL, SEVERITY_ERROR, SEVERITY_WARNING
2330
2331 zep = getFacade('zep', self)
2332 event_filter = zep.createEventFilter(tags=[self.getUUID()],
2333 severity=[SEVERITY_WARNING,SEVERITY_ERROR,SEVERITY_CRITICAL],
2334 status=[STATUS_NEW,STATUS_ACKNOWLEDGED],
2335 event_class=filter(None, [statusclass]),
2336 details={EventProxy.DEVICE_IP_ADDRESS_DETAIL_KEY: self.getManageIp()})
2337 result = zep.getEventSummaries(0, filter=event_filter, limit=0)
2338 return int(result['total'])
2339
2340 return super(Device, self).getStatus(statusclass, **kwargs)
2341
2342
2350
2355
2357 ip = self.getManageIp()
2358 if ip:
2359 ip = ip.partition('/')[0]
2360 return str(numbip(ip))
2361
2362 InitializeClass(Device)
2363