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
210
211 addDevice = DTMLFile('dtml/addDevice',globals())
212
213
215
216 -class Device(ManagedEntity, Commandable, Lockable, MaintenanceWindowable,
217 AdministrativeRoleable, ZenMenuable):
218 """
219 Device is a base class that represents the idea of a single computer system
220 that is made up of software running on hardware. It currently must be IP
221 enabled but maybe this will change.
222 """
223
224 implements(IEventView, IIndexed, IGloballyIdentifiable)
225
226 event_key = portal_type = meta_type = 'Device'
227
228 default_catalog = "deviceSearch"
229
230 relationshipManagerPathRestriction = '/Devices'
231
232 manageIp = ""
233 productionState = 1000
234 preMWProductionState = productionState
235 snmpAgent = ""
236 snmpDescr = ""
237 snmpOid = ""
238 snmpContact = ""
239 snmpSysName = ""
240 snmpLocation = ""
241 rackSlot = ""
242 comments = ""
243 sysedgeLicenseMode = ""
244 priority = 3
245 detailKeys = ('tagNumber', 'serialNumber',
246 'hwModel', 'hwManufacturer',
247 'osModel', 'osManufacturer',
248 'groups', 'systems', 'location')
249
250 _temp_device = False
251
252 _properties = ManagedEntity._properties + (
253 {'id':'manageIp', 'type':'string', 'mode':'w'},
254 {'id':'snmpAgent', 'type':'string', 'mode':'w'},
255 {'id':'snmpDescr', 'type':'string', 'mode':''},
256 {'id':'snmpOid', 'type':'string', 'mode':''},
257 {'id':'snmpContact', 'type':'string', 'mode':''},
258 {'id':'snmpSysName', 'type':'string', 'mode':''},
259 {'id':'snmpLocation', 'type':'string', 'mode':''},
260 {'id':'snmpLastCollection', 'type':'date', 'mode':''},
261 {'id':'snmpAgent', 'type':'string', 'mode':''},
262 {'id':'rackSlot', 'type':'string', 'mode':'w'},
263 {'id':'comments', 'type':'text', 'mode':'w'},
264 {'id':'sysedgeLicenseMode', 'type':'string', 'mode':''},
265 {'id':'priority', 'type':'int', 'mode':'w'},
266 )
267
268 _relations = ManagedEntity._relations + (
269 ("deviceClass", ToOne(ToManyCont, "Products.ZenModel.DeviceClass",
270 "devices")),
271 ("perfServer", ToOne(ToMany, "Products.ZenModel.PerformanceConf",
272 "devices")),
273 ("location", ToOne(ToMany, "Products.ZenModel.Location", "devices")),
274 ("systems", ToMany(ToMany, "Products.ZenModel.System", "devices")),
275 ("groups", ToMany(ToMany, "Products.ZenModel.DeviceGroup", "devices")),
276 ("maintenanceWindows",ToManyCont(ToOne,
277 "Products.ZenModel.MaintenanceWindow", "productionState")),
278 ("adminRoles", ToManyCont(ToOne,"Products.ZenModel.AdministrativeRole",
279 "managedObject")),
280 ('userCommands', ToManyCont(ToOne, 'Products.ZenModel.UserCommand',
281 'commandable')),
282
283 ('monitors', ToMany(ToMany, 'Products.ZenModel.StatusMonitorConf',
284 'devices')),
285 )
286
287
288 factory_type_information = (
289 {
290 'id' : 'Device',
291 'meta_type' : 'Device',
292 'description' : """Base class for all devices""",
293 'icon' : 'Device_icon.gif',
294 'product' : 'ZenModel',
295 'factory' : 'manage_addDevice',
296 'immediate_view' : 'devicedetail',
297 'actions' :
298 (
299 {'id' : 'swdetail'
300 , 'name' : 'Software'
301 , 'action' : 'deviceSoftwareDetail'
302 , 'permissions': (ZEN_VIEW, )
303 },
304 { 'id' : 'events'
305 , 'name' : 'Events'
306 , 'action' : 'viewEvents'
307 , 'permissions' : (ZEN_VIEW, )
308 },
309 { 'id' : 'perfServer'
310 , 'name' : 'Graphs'
311 , 'action' : 'viewDevicePerformance'
312 , 'permissions' : (ZEN_VIEW, )
313 },
314 { 'id' : 'edit'
315 , 'name' : 'Edit'
316 , 'action' : 'editDevice'
317 , 'permissions' : ("Change Device",)
318 },
319 )
320 },
321 )
322
323 security = ClassSecurityInfo()
324
325 - def __init__(self, id, buildRelations=True):
335
337 flag = getattr(self, '_temp_device', None)
338 if flag is None:
339 flag = self._temp_device = False
340 return flag
341
343 """
344 Return the name of this device. Default is titleOrId.
345 """
346 return self.titleOrId()
347
348
349 security.declareProtected(ZEN_MANAGE_DMD, 'changeDeviceClass')
351 """
352 Wrapper for DeviceClass.moveDevices. The primary reason to use this
353 method instead of that one is that this one returns the new path to the
354 device.
355
356 @param deviceClassPath: device class in DMD path
357 @type deviceClassPath: string
358 @param REQUEST: Zope REQUEST object
359 @type REQUEST: Zope REQUEST object
360 """
361 self.deviceClass().moveDevices(deviceClassPath, (self.id,))
362 device = self.getDmdRoot('Devices').findDevice(self.id)
363 return device.absolute_url_path()
364
366 """
367 DEPRECATED
368 """
369 import warnings
370 warnings.warn('Device.getRRDTemplate is deprecated',
371 DeprecationWarning)
372 return ManagedEntity.getRRDTemplate(self)
373
375 """
376 Returns all the templates bound to this Device
377
378 @rtype: list
379
380 >>> from Products.ZenModel.Device import manage_addDevice
381 >>> manage_addDevice(devices, 'test')
382 >>> devices.test.getRRDTemplates()
383 [<RRDTemplate at /zport/dmd/Devices/rrdTemplates/Device>]
384 """
385 if not hasattr(self, 'zDeviceTemplates'):
386 return ManagedEntity.getRRDTemplates(self)
387 result = []
388 for name in self.zDeviceTemplates:
389 template = self.getRRDTemplateByName(name)
390 if template:
391 result.append(template)
392 return result
393
394
397
398
400 """
401 Returns the available DataSource options. DataSource options
402 are used to populate the dropdown when adding a new DataSource
403 and is a string. See L{RRDTemplate.RRDTemplate.getDataSourceOptions}
404 for more information.
405
406 @rtype: list
407 @return: [(displayName, dsOption),]
408 """
409
410
411
412
413
414 templates = self.getRRDTemplates()
415 if templates:
416 return templates[0].getDataSourceOptions()
417 return []
418
419
420
421
422
423
424
425
426
428 """
429 Returns the cached sysUpTime for this device
430
431 @rtype: int
432 """
433 try:
434 return self.cacheRRDValue('sysUpTime', -1)
435 except Exception:
436 log.exception("failed getting sysUpTime")
437 return -1
438
439
441 """
442 Returns the uptime of this device
443
444 @rtype: string
445 @todo: Performance enhancement: Should move import outside of method
446 """
447 from Products.ZenEvents import Availability
448 results = Availability.query(self.dmd, device=self.id, *args, **kw)
449 if results:
450 return results[0]
451 else:
452 return None
453
454
455
457 """
458 Override from object to handle lastPollSnmpUpTime and
459 snmpLastCollection
460
461 @todo: Not sure this is needed, see getLastPollSnmpUpTime and
462 getSnmpLastCollection
463 """
464 if name == 'lastPollSnmpUpTime':
465 return self._lastPollSnmpUpTime.getStatus()
466 elif name == 'snmpLastCollection':
467 return DateTime(self._snmpLastCollection)
468 else:
469 raise AttributeError( name )
470
471
473 """
474 Override from PropertyManager to handle checks and ip creation
475
476 @todo: Not sure this is needed, see setSnmpLastCollection
477 """
478 self._wrapperCheck(value)
479 if id == 'snmpLastCollection':
480 self._snmpLastCollection = float(value)
481 else:
482 ManagedEntity._setPropValue(self, id, value)
483
484
485 - def applyDataMap(self, datamap, relname="", compname="", modname=""):
492
493
495 """
496 Return a sequence of path tuples suitable for indexing by
497 a MultiPathIndex.
498 """
499 orgs = (
500 self.systems() +
501 self.groups() +
502 [self.location()] +
503 [self.deviceClass()]
504 )
505 return [ aq_base(self).__of__(o.primaryAq()).getPhysicalPath() \
506 for o in orgs if o is not None ]
507
508
510 """
511 Trace the route to target using our routing table.
512 Wrapper method of OperatingSystem.traceRoute
513
514 @param target: Device name
515 @type target: string
516 @param ippath: IP addesses
517 @type ippath: list
518 @return: IP Addresses
519 @rtype: list
520 """
521 if ippath is None: ippath=[]
522 if isinstance(target, basestring):
523 target = self.findDevice(target)
524 if not target: raise ValueError("Target %s not found in DMD" % target)
525 return self.os.traceRoute(target, ippath)
526
527
529 """
530 Return list of monitored DeviceComponents on this device.
531 Wrapper method for getDeviceComponents
532 """
533 return self.getDeviceComponents(monitored=True,
534 collector=collector, type=type)
535
536
537 security.declareProtected(ZEN_VIEW, 'getReportableComponents')
539 """
540 Return a list of DeviceComponents on this device that should be
541 considered for reporting.
542
543 @type collector: string
544 @type type: string
545 @permission: ZEN_VIEW
546 @rtype: list
547 """
548 return self.getMonitoredComponents(collector=collector, type=type);
549
550
551 security.declareProtected(ZEN_VIEW, 'getDeviceComponents')
553 """
554 Return list of all DeviceComponents on this device.
555
556 @type monitored: boolean
557 @type collector: string
558 @type type: string
559 @permission: ZEN_VIEW
560 @rtype: list
561 """
562
563
564
565
566 if not self.componentSearch._catalog.indexes.has_key('getParentDeviceName'):
567 return self.getDeviceComponentsNoIndexGen()
568
569 query = {
570 'getParentDeviceName':self.id,
571 }
572 if collector is not None:
573 query['getCollectors'] = collector
574 if monitored is not None:
575 query['monitored'] = monitored
576 if type is not None:
577 query['meta_type'] = type
578
579 return list(getObjectsFromCatalog(self.componentSearch, query, log))
580
581
583 """
584 Return a list of all device components by walking relations. This is
585 much slower then the normal getDeviceComponents method which uses the
586 component index. It is used when rebuilding the device indexes.
587 """
588 from DeviceComponent import DeviceComponent
589 for baseObject in (self, self.os, self.hw):
590 for rel in baseObject.getRelationships():
591 if rel.meta_type != "ToManyContRelationship": continue
592 for obj in rel():
593 if not isinstance(obj, DeviceComponent): break
594 for subComp in obj.getSubComponentsNoIndexGen():
595 yield subComp
596 yield obj
597
598
607
608
610 """
611 DEPRECATED - Return the hardware manufacturer name of this device.
612
613 @rtype: string
614 @todo: Remove this method and remove the call from testDevice.py
615 """
616 return self.hw.getManufacturerName()
617
618
620 """
621 Return the hardware product name of this device.
622
623 @rtype: string
624 """
625 return self.hw.getProductName()
626
628 """
629 Return the hardware product class of this device.
630
631 @rtype: string
632 """
633 cls = self.hw.productClass()
634 if cls:
635 return cls.titleOrId()
636
638 """
639 DEPRECATED - Return the productKey of the device hardware.
640
641 @rtype: string
642 @todo: Remove this method and remove the call from testDevice.py
643 """
644 return self.hw.getProductKey()
645
646
648 """
649 DEPRECATED - Return the OS manufacturer name of this device.
650
651 @rtype: string
652 @todo: Remove this method and remove the call from testDevice.py
653 """
654 return self.os.getManufacturerName()
655
656
658 """
659 DEPRECATED - Return the OS product name of this device.
660
661 @rtype: string
662 @todo: Remove this method and remove the call from testDevice.py
663 """
664 return self.os.getProductName()
665
666
668 """
669 DEPRECATED - Return the productKey of the device OS.
670
671 @rtype: string
672 @todo: Remove this method and remove the call from testDevice.py
673 """
674 return self.os.getProductKey()
675
676
678 """
679 Set the productKey of the device OS.
680 """
681 self.os.setProductKey(prodKey, manufacturer)
682 self.index_object(idxs=('getOSProductName','getOSManufacturerName'),
683 noips=True)
684
685
686
688 """
689 DEPRECATED - Return the tag of the device HW.
690
691 @rtype: string
692 @todo: remove this method and remove the call from testDevice.py
693 """
694 return self.hw.tag
695
696
698 """
699 Set the asset tag of the device hardware.
700 """
701 self.hw.tag = assettag
702 self.index_object(idxs=('getHWTag',), noips=True)
703
704
705
707 """
708 Set the productKey of the device hardware.
709 """
710 self.hw.setProductKey(prodKey, manufacturer)
711 self.index_object(idxs=('getHWProductClass','getHWManufacturerName'),
712 noips=True)
713
714
715
717 """
718 Set the hardware serial number.
719 """
720 self.hw.serialNumber = number
721 self.index_object(idxs=('getHWSerialNumber',), noips=True)
722
724 """
725 DEPRECATED - Return the hardware serial number.
726
727 @rtype: string
728 @todo: Remove this method and remove the call from testDevice.py
729 """
730 return self.hw.serialNumber
731
732
734 """
735 Return the ips that our indirect routs point to which aren't currently
736 connected to devices.
737
738 @todo: Can be moved to zendisc.py
739 """
740 ips = []
741 for r in self.os.routes():
742 ipobj = r.nexthop()
743
744 if ipobj: ips.append(ipobj.id)
745 return ips
746
747
748 security.declareProtected(ZEN_VIEW, 'getLocationName')
750 """
751 Return the full location name ie /Location/SubLocation/Rack
752
753 @rtype: string
754 @permission: ZEN_VIEW
755 """
756 loc = self.location()
757 if loc: return loc.getOrganizerName()
758 return ""
759
760 security.declareProtected(ZEN_VIEW, 'getLocationLink')
776
777
778 security.declareProtected(ZEN_VIEW, 'getSystemNames')
780 """
781 Return the system names for this device
782
783 @rtype: list
784 @permission: ZEN_VIEW
785 """
786 return map(lambda x: x.getOrganizerName(), self.systems())
787
788
789 security.declareProtected(ZEN_VIEW, 'getSystemNamesString')
791 """
792 Return the system names for this device as a string
793
794 @rtype: string
795 @permission: ZEN_VIEW
796 """
797 return sep.join(self.getSystemNames())
798
799
800 security.declareProtected(ZEN_VIEW, 'getDeviceGroupNames')
802 """
803 Return the device group names for this device
804
805 @rtype: list
806 @permission: ZEN_VIEW
807 """
808 return map(lambda x: x.getOrganizerName(), self.groups())
809
810
811 security.declareProtected(ZEN_VIEW, 'getPerformanceServer')
820
821
822 security.declareProtected(ZEN_VIEW, 'getPerformanceServerName')
833
834
839
840 security.declareProtected(ZEN_VIEW, 'getLastChange')
842 """
843 Return DateTime of last change detected on this device.
844
845 @rtype: DateTime
846 @permission: ZEN_VIEW
847 """
848 return DateTime(float(self._lastChange))
849
850
851 security.declareProtected(ZEN_VIEW, 'getLastChangeString')
853 """
854 Return date string of last change detected on this device.
855
856 @rtype: string
857 @permission: ZEN_VIEW
858 """
859 return Time.LocalDateTimeSecsResolution(float(self._lastChange))
860
861
862 security.declareProtected(ZEN_VIEW, 'getSnmpLastCollection')
864 """
865 Return DateTime of last SNMP collection on this device.
866
867 @rtype: DateTime
868 @permission: ZEN_VIEW
869 """
870 return DateTime(float(self._snmpLastCollection))
871
872
873 security.declareProtected(ZEN_VIEW, 'getSnmpLastCollectionString')
875 """
876 Return date string of last SNMP collection on this device.
877
878 @rtype: string
879 @permission: ZEN_VIEW
880 """
881 if self._snmpLastCollection:
882 return Time.LocalDateTimeSecsResolution(float(self._snmpLastCollection))
883 return "Not Modeled"
884
885
910
912 ipMatch = self.getNetworkRoot().findIp(ip)
913 if ipMatch:
914 dev = ipMatch.device()
915 if dev and self.id != dev.id:
916 return True
917 return False
918
919 security.declareProtected(ZEN_ADMIN_DEVICE, 'setManageIp')
921 """
922 Set the manage IP, if IP is not passed perform DNS lookup.
923 If there is an error with the IP address format, the IP address
924 will be reset to the result of a DNS lookup.
925
926 @rtype: string
927 @permission: ZEN_ADMIN_DEVICE
928 """
929 message = ''
930 ip = ip.replace(' ', '')
931 origip = ip
932 ip = self._sanitizeIPaddress(ip)
933
934 if not ip:
935 try:
936 ip = getHostByName(origip)
937 if ip == '0.0.0.0':
938
939 ip = ''
940 except socket.error:
941 ip = ''
942
943 if not ip:
944 try:
945 ip = getHostByName(ipunwrap(self.id))
946 except socket.error:
947 ip = ''
948 if origip:
949 message = ("%s is an invalid IP address, "
950 "and no appropriate IP could"
951 " be found via DNS for %s") % (origip, self.id)
952 log.warn(message)
953 else:
954 message = "DNS lookup of '%s' failed to return an IP" % \
955 self.id
956
957 if ip:
958 if self._isDuplicateIp(ip):
959 message = "The IP address %s is already assigned" % ip
960 log.warn(message)
961
962 else:
963 self.manageIp = ip
964 self.index_object(idxs=('ipAddressAsInt','getDeviceIp'), noips=True)
965 notify(IndexingEvent(self, ('ipAddress',), True))
966 log.info("%s's IP address has been set to %s.",
967 self.id, ip)
968
969 return message
970
971
972 security.declareProtected(ZEN_VIEW, 'getManageIp')
974 """
975 Return the management ip for this device.
976
977 @rtype: string
978 @permission: ZEN_VIEW
979 """
980 return self.manageIp
981
982
984 """
985 DEPRECATED - Return the management ipobject for this device.
986
987 @rtype: IpAddress
988 @todo: This method may not be called anywhere, remove it.
989 """
990 if self.manageIp:
991 return self.Networks.findIp(self.manageIp)
992
993
994 security.declareProtected(ZEN_VIEW, 'getManageInterface')
996 """
997 Return the management interface of a device based on its manageIp.
998
999 @rtype: IpInterface
1000 @permission: ZEN_VIEW
1001 """
1002 ipobj = self.Networks.findIp(self.manageIp)
1003 if ipobj: return ipobj.interface()
1004
1005
1006 security.declareProtected(ZEN_VIEW, 'uptimeStr')
1008 """
1009 Return the SNMP uptime
1010
1011 @rtype: string
1012 @permission: ZEN_VIEW
1013 """
1014 ut = self.sysUpTime()
1015
1016 if ut < 0 or ut != ut:
1017 return "Unknown"
1018 elif ut == 0:
1019 return "0d:0h:0m:0s"
1020 ut = float(ut)/100.
1021 days = int(ut/86400)
1022 hour = int((ut%86400)/3600)
1023 mins = int((ut%3600)/60)
1024 secs = int(ut%60)
1025 return "%02dd:%02dh:%02dm:%02ds" % (
1026 days, hour, mins, secs)
1027
1028
1030 """
1031 Build a list of all device paths that have the python class pyclass
1032
1033 @rtype: list
1034 """
1035 dclass = self.getDmdRoot("Devices")
1036 return dclass.getPeerDeviceClassNames(self.__class__)
1037
1038
1039
1040
1041
1042
1043 security.declareProtected(ZEN_CHANGE_DEVICE, 'manage_snmpCommunity')
1045 """
1046 Reset the snmp community using the zSnmpCommunities variable.
1047
1048 @permission: ZEN_CHANGE_DEVICE
1049 """
1050 try:
1051 zSnmpCommunity, zSnmpPort, zSnmpVer, snmpname = \
1052 findCommunity(self, self.manageIp, self.getDeviceClassPath(),
1053 port=self.zSnmpPort, version=self.zSnmpVer)
1054 except NoSnmp:
1055 pass
1056 else:
1057 if self.zSnmpCommunity != zSnmpCommunity:
1058 self.setZenProperty("zSnmpCommunity", zSnmpCommunity)
1059 if self.zSnmpPort != zSnmpPort:
1060 self.setZenProperty("zSnmpPort", zSnmpPort)
1061 if self.zSnmpVer != zSnmpVer:
1062 self.setZenProperty("zSnmpVer", zSnmpVer)
1063
1064 - def setProductInfo(self, hwManufacturer="", hwProductName="",
1065 osManufacturer="", osProductName=""):
1066 if hwManufacturer and hwProductName:
1067
1068
1069 if hwManufacturer != "_no_change" and hwProductName != "_no_change":
1070 log.info("setting hardware manufacturer to %r productName to %r"
1071 % (hwManufacturer, hwProductName))
1072 self.hw.setProduct(hwProductName, hwManufacturer)
1073 else:
1074 self.hw.productClass.removeRelation()
1075
1076 if osManufacturer and osProductName:
1077
1078
1079 if osManufacturer != "_no_change" and osProductName != "_no_change":
1080 log.info("setting os manufacturer to %r productName to %r"
1081 % (osManufacturer, osProductName))
1082 self.os.setProduct(osProductName, osManufacturer)
1083 self.os.productClass().isOS = True
1084 else:
1085 self.os.productClass.removeRelation()
1086
1087
1088 security.declareProtected(ZEN_CHANGE_DEVICE, 'updateDevice')
1090 """
1091 Update the device relation and attributes, if passed. If any parameter
1092 is not passed it will not be updated; the value of any unpassed device
1093 propeties will remain the same.
1094
1095 @permission: ZEN_CHANGE_DEVICE
1096 Keyword arguments:
1097 title -- device title [string]
1098 tag -- tag number [string]
1099 serialNumber -- serial number [string]
1100 zProperties -- dict of zProperties [dict]
1101 zSnmpCommunity -- snmp community (overrides corresponding value is zProperties) [string]
1102 zSnmpPort -- snmp port (overrides corresponding value in zProperties) [string]
1103 zSnmpVer -- snmp version (overrides corresponding value in zProperties) [string]
1104 rackSlot -- rack slot number [integer]
1105 productionState -- production state of device [integer]
1106 priority -- device priority [integer]
1107 comment -- device comment [string]
1108 hwManufacturer -- hardware manufacturer [string]
1109 hwProductName -- hardware product name [string]
1110 osManufacturer -- operating system manufacturer [string]
1111 osProductName -- operating system name [string]
1112 locationPath -- location [string]
1113 groupPaths -- group paths [list]
1114 systemPaths -- systen paths [list]
1115 performanceMonitor -- collector name [string]
1116
1117 """
1118 if 'title' in kwargs and kwargs['title'] is not None:
1119 log.info("setting title to %r" % kwargs['title'])
1120 self.title = kwargs['title']
1121 if 'tag' in kwargs and kwargs['tag'] is not None:
1122 log.info("setting tag to %r" % kwargs['tag'])
1123 self.hw.tag = kwargs['tag']
1124 if 'serialNumber' in kwargs and kwargs['serialNumber'] is not None:
1125 log.info("setting serialNumber to %r" % kwargs['serialNumber'])
1126 self.hw.serialNumber = kwargs['serialNumber']
1127
1128
1129 if 'zProperties' in kwargs and kwargs['zProperties'] is not None:
1130 zProperties = kwargs['zProperties']
1131 else:
1132 zProperties = {}
1133
1134
1135 zpropUpdate = dict((name, kwargs[name]) for name in ('zSnmpCommunity', 'zSnmpPort', 'zSnmpVer')
1136 if name in kwargs)
1137 zProperties.update(zpropUpdate)
1138
1139
1140 for prop, value in zProperties.items():
1141 if value and getattr(self, prop) != value:
1142 self.setZenProperty(prop, value)
1143
1144 if 'rackSlot' in kwargs:
1145 log.info("setting rackSlot to %r" % kwargs["rackSlot"])
1146 self.rackSlot = kwargs["rackSlot"]
1147
1148 if 'productionState' in kwargs:
1149 log.info("setting productionState to %r" % kwargs["productionState"])
1150 self.setProdState(kwargs["productionState"])
1151
1152 if 'priority' in kwargs:
1153 log.info("setting priority to %r" % kwargs["priority"])
1154 self.setPriority(kwargs["priority"])
1155
1156 if 'comments' in kwargs:
1157 log.info("setting comments to %r" % kwargs["comments"])
1158 self.comments = kwargs["comments"]
1159
1160 self.setProductInfo(hwManufacturer=kwargs.get("hwManufacturer","_no_change"),
1161 hwProductName=kwargs.get("hwProductName","_no_change"),
1162 osManufacturer=kwargs.get("osManufacturer","_no_change"),
1163 osProductName=kwargs.get("osProductName","_no_change"))
1164
1165 if kwargs.get("locationPath", False):
1166 log.info("setting location to %r" % kwargs["locationPath"])
1167 self.setLocation(kwargs["locationPath"])
1168
1169 if kwargs.get("groupPaths",False):
1170 log.info("setting group %r" % kwargs["groupPaths"])
1171 self.setGroups(kwargs["groupPaths"])
1172
1173 if kwargs.get("systemPaths",False):
1174 log.info("setting system %r" % kwargs["systemPaths"])
1175 self.setSystems(kwargs["systemPaths"])
1176
1177 if 'performanceMonitor' in kwargs and \
1178 kwargs["performanceMonitor"] != self.getPerformanceServerName():
1179 log.info("setting performance monitor to %r" \
1180 % kwargs["performanceMonitor"])
1181 self.setPerformanceMonitor(kwargs["performanceMonitor"])
1182
1183 self.setLastChange()
1184 self.index_object()
1185 notify(IndexingEvent(self))
1186
1187 security.declareProtected(ZEN_CHANGE_DEVICE, 'manage_editDevice')
1188 - def manage_editDevice(self,
1189 tag="", serialNumber="",
1190 zSnmpCommunity="", zSnmpPort=161, zSnmpVer="",
1191 rackSlot="", productionState=1000, comments="",
1192 hwManufacturer="", hwProductName="",
1193 osManufacturer="", osProductName="",
1194 locationPath="", groupPaths=[], systemPaths=[],
1195 performanceMonitor="localhost", priority=3,
1196 zProperties=None, title=None, REQUEST=None):
1197 """
1198 Edit the device relation and attributes. This method will update device
1199 properties because of the default values that are passed. Calling this
1200 method using a **kwargs dict will result in default values being set for
1201 many device properties. To update only a subset of these properties use
1202 updateDevice(**kwargs).
1203
1204 @param locationPath: path to a Location
1205 @type locationPath: string
1206 @param groupPaths: paths to DeviceGroups
1207 @type groupPaths: list
1208 @param systemPaths: paths to Systems
1209 @type systemPaths: list
1210 @param performanceMonitor: name of PerformanceMonitor
1211 @type performanceMonitor: string
1212 @permission: ZEN_CHANGE_DEVICE
1213 """
1214 self.updateDevice(
1215 tag=tag, serialNumber=serialNumber,
1216 zSnmpCommunity=zSnmpCommunity, zSnmpPort=zSnmpPort, zSnmpVer=zSnmpVer,
1217 rackSlot=rackSlot, productionState=productionState, comments=comments,
1218 hwManufacturer=hwManufacturer, hwProductName=hwProductName,
1219 osManufacturer=osManufacturer, osProductName=osProductName,
1220 locationPath=locationPath, groupPaths=groupPaths, systemPaths=systemPaths,
1221 performanceMonitor=performanceMonitor, priority=priority,
1222 zProperties=zProperties, title=title, REQUEST=REQUEST)
1223 if REQUEST:
1224 from Products.ZenUtils.Time import SaveMessage
1225 IMessageSender(self).sendToBrowser("Saved", SaveMessage())
1226 return self.callZenScreen(REQUEST)
1227
1228
1230 """
1231 Changes the title to newTitle and reindexes the object
1232 """
1233 super(Device, self).setTitle(newTitle)
1234 self.index_object()
1235 notify(IndexingEvent(self, ('name',), True))
1236
1238 """
1239 Returns true if the device production state >= zProdStateThreshold.
1240
1241 @rtype: boolean
1242 """
1243 return self.productionState >= self.zProdStateThreshold
1244
1245
1247 """
1248 Returns true if the device is subject to SNMP monitoring
1249
1250 @rtype: boolean
1251 """
1252 return (self.monitorDevice()
1253 and self.getManageIp()
1254 and not self.zSnmpMonitorIgnore)
1255
1256
1258 """
1259 Return the numeric device priority.
1260
1261 @rtype: int
1262 """
1263 return self.priority
1264
1265
1267 """
1268 Return the device priority as a string.
1269
1270 @rtype: string
1271 """
1272 return self.convertPriority(self.priority)
1273
1275 """
1276 Return the pingStatus as a string
1277
1278 @rtype: string
1279 """
1280 return self.convertStatus(self.getPingStatus())
1281
1283 """
1284 Return the snmpStatus as a string
1285
1286 @rtype: string
1287 """
1288 return self.convertStatus(self.getSnmpStatus())
1289
1290 security.declareProtected(ZEN_CHANGE_DEVICE_PRODSTATE, 'setProdState')
1291 - def setProdState(self, state, maintWindowChange=False, REQUEST=None):
1307
1308 security.declareProtected(ZEN_CHANGE_DEVICE, 'setPriority')
1324
1325 security.declareProtected(ZEN_CHANGE_DEVICE, 'setLastChange')
1327 """
1328 Set the changed datetime for this device.
1329
1330 @param value: secs since the epoch, default is now
1331 @type value: float
1332 @permission: ZEN_CHANGE_DEVICE
1333 """
1334 if value is None:
1335 value = time.time()
1336 self._lastChange = float(value)
1337
1338 security.declareProtected(ZEN_CHANGE_DEVICE, 'setSnmpLastCollection')
1340 """
1341 Set the last time snmp collection occurred.
1342
1343 @param value: secs since the epoch, default is now
1344 @type value: float
1345 @permission: ZEN_CHANGE_DEVICE
1346 """
1347 if value is None:
1348 value = time.time()
1349 self._snmpLastCollection = float(value)
1350
1351
1352 security.declareProtected(ZEN_CHANGE_DEVICE, 'addManufacturer')
1353 - def addManufacturer(self, newHWManufacturerName=None,
1354 newSWManufacturerName=None, REQUEST=None):
1355 """
1356 DEPRECATED -
1357 Add either a hardware or software manufacturer to the database.
1358
1359 @permission: ZEN_CHANGE_DEVICE
1360 @todo: Doesn't really do work on a device object.
1361 Already exists on ZDeviceLoader
1362 """
1363 mname = newHWManufacturerName
1364 field = 'hwManufacturer'
1365 if not mname:
1366 mname = newSWManufacturerName
1367 field = 'osManufacturer'
1368 self.getDmdRoot("Manufacturers").createManufacturer(mname)
1369 if REQUEST:
1370 REQUEST[field] = mname
1371 messaging.IMessageSender(self).sendToBrowser(
1372 'Manufacturer Added',
1373 'The %s manufacturer has been created.' % mname
1374 )
1375 return self.callZenScreen(REQUEST)
1376
1377
1378 security.declareProtected(ZEN_CHANGE_DEVICE, 'setHWProduct')
1379 - def setHWProduct(self, newHWProductName=None, hwManufacturer=None,
1380 REQUEST=None):
1408
1409
1410 security.declareProtected(ZEN_CHANGE_DEVICE, 'setOSProduct')
1411 - def setOSProduct(self, newOSProductName=None, osManufacturer=None, REQUEST=None):
1437
1438
1439 security.declareProtected(ZEN_CHANGE_DEVICE, 'setLocation')
1454
1455
1456 - def addLocation(self, newLocationPath, REQUEST=None):
1457 """
1458 DEPRECATED
1459 Add a new location and relate it to this device
1460
1461 @todo: Doesn't really do work on a device object.
1462 Already exists on ZDeviceLoader
1463 """
1464 self.getDmdRoot("Locations").createOrganizer(newLocationPath)
1465 if REQUEST:
1466 REQUEST['locationPath'] = newLocationPath
1467 messaging.IMessageSender(self).sendToBrowser(
1468 'Location Added',
1469 'Location %s has been created.' % newLocationPath
1470 )
1471 return self.callZenScreen(REQUEST)
1472
1473
1474 security.declareProtected(ZEN_CHANGE_DEVICE, 'setPerformanceMonitor')
1499
1500
1501 security.declareProtected(ZEN_CHANGE_DEVICE, 'setGroups')
1503 """
1504 Set the list of groups for this device based on a list of paths
1505
1506 @permission: ZEN_CHANGE_DEVICE
1507 """
1508 objGetter = self.getDmdRoot("Groups").createOrganizer
1509 self._setRelations("groups", objGetter, groupPaths)
1510 self.index_object()
1511 notify(IndexingEvent(self, 'path', False))
1512
1513
1514 security.declareProtected(ZEN_CHANGE_DEVICE, 'addDeviceGroup')
1531
1532
1533 security.declareProtected(ZEN_CHANGE_DEVICE, 'setSystems')
1535 """
1536 Set a list of systems to this device using their system paths
1537
1538 @permission: ZEN_CHANGE_DEVICE
1539 """
1540 objGetter = self.getDmdRoot("Systems").createOrganizer
1541 self._setRelations("systems", objGetter, systemPaths)
1542 self.index_object()
1543 notify(IndexingEvent(self, 'path', False))
1544
1545
1546 security.declareProtected(ZEN_CHANGE_DEVICE, 'addSystem')
1547 - def addSystem(self, newSystemPath, REQUEST=None):
1563
1564
1565 security.declareProtected(ZEN_CHANGE_DEVICE, 'setTerminalServer')
1567 """
1568 Set the terminal server of this device
1569
1570 @param termservername: device name of terminal server
1571 @permission: ZEN_CHANGE_DEVICE
1572 """
1573 termserver = self.findDevice(termservername)
1574 if termserver:
1575 self.addRelation('termserver', termserver)
1576
1577
1579 """
1580 Set related objects to this device
1581
1582 @param relName: name of the relation to set
1583 @param objGetter: method to get the relation
1584 @param relPaths: list of relationship paths
1585 """
1586 if not isinstance(relPaths, (list, tuple)):
1587 relPaths = [relPaths,]
1588 relPaths = filter(lambda x: x.strip(), relPaths)
1589 rel = getattr(self, relName, None)
1590 if not rel:
1591 raise AttributeError( "Relation %s not found" % relName)
1592 curRelIds = {}
1593 for value in rel.objectValuesAll():
1594 curRelIds[value.getOrganizerName()] = value
1595 for path in relPaths:
1596 if not path in curRelIds:
1597 robj = objGetter(path)
1598 self.addRelation(relName, robj)
1599 else:
1600 del curRelIds[path]
1601 for obj in curRelIds.values():
1602 self.removeRelation(relName, obj)
1603 self.setAdminLocalRoles()
1604
1605
1607 """
1608 Return the expanded zComment property
1609
1610 @rtype: HTML output
1611 """
1612 from Products.ZenUtils.ZenTales import talesEval
1613 try:
1614 return talesEval('string:' + self.zLinks, self)
1615 except Exception, ex:
1616 import cgi
1617 return "<i class='errortitle'>%s</i>" % cgi.escape(str(ex))
1618
1619
1620
1621
1622
1623 security.declareProtected(ZEN_VIEW, 'device')
1625 """
1626 Support DeviceResultInt mixin class. Returns itself
1627
1628 @permission: ZEN_VIEW
1629 """
1630 return self
1631
1632
1633
1634
1635
1636
1637
1639 """
1640 Returns true if the device has more SNMP failures
1641 than maxFailures on its status mon.
1642
1643 @rtype: boolean
1644 """
1645 statusmon = self.monitors()
1646 if len(statusmon) > 0:
1647 statusmon = statusmon[0]
1648 return statusmon.maxFailures < self.getSnmpStatusNumber()
1649 return False
1650
1651
1652
1653 security.declareProtected(ZEN_MANAGE_DEVICE_STATUS,
1654 'getLastPollSnmpUpTime')
1656 """
1657 Get the value of the snmpUpTime status object
1658
1659 @permission: ZEN_MANAGE_DEVICE_STATUS
1660 """
1661 return self._lastPollSnmpUpTime.getStatus()
1662
1663
1664
1665 security.declareProtected(ZEN_MANAGE_DEVICE_STATUS,
1666 'setLastPollSnmpUpTime')
1668 """
1669 Set the value of the snmpUpTime status object
1670
1671 @permission: ZEN_MANAGE_DEVICE_STATUS
1672 """
1673 self._lastPollSnmpUpTime.setStatus(value)
1674
1675
1676 - def snmpAgeCheck(self, hours):
1677 """
1678 Returns True if SNMP data was collected more than 24 hours ago
1679 """
1680 lastcoll = self.getSnmpLastCollection()
1681 hours = hours/24.0
1682 if DateTime() > lastcoll + hours: return 1
1683
1684
1686 """
1687 Apply zProperties inherited from Product Contexts.
1688 """
1689 self._applyProdContext(self.hw.getProductContext())
1690 self._applyProdContext(self.os.getProductContext())
1691 for soft in self.os.software():
1692 self._applyProdContext(soft.getProductContext())
1693
1694
1695 - def _applyProdContext(self, context):
1696 """
1697 Apply zProperties taken for the product context passed in.
1698
1699 @param context: list of tuples returned from
1700 getProductContext on a MEProduct.
1701 """
1702 for name, value in context:
1703 if name == "zDeviceClass" and value:
1704 log.info("move device to %s", value)
1705 self.moveDevices(value, self.id)
1706 elif name == "zDeviceGroup" and value:
1707 log.info("add device to group %s", value)
1708 self.addDeviceGroup(value)
1709 elif name == "zSystem" and value:
1710 log.info("add device to system %s", value)
1711 self.addSystem(value)
1712
1713
1714
1715
1716
1717
1718
1719 security.declareProtected(ZEN_MANAGE_DEVICE, 'collectDevice')
1720 - def collectDevice(self, setlog=True, REQUEST=None, generateEvents=False,
1721 background=False, write=None):
1722 """
1723 Collect the configuration of this device AKA Model Device
1724
1725 @param setlog: If true, set up the output log of this process
1726 @permission: ZEN_MANAGE_DEVICE
1727 @todo: generateEvents param is not being used.
1728 """
1729 unused(generateEvents)
1730 xmlrpc = isXmlRpc(REQUEST)
1731 perfConf = self.getPerformanceServer()
1732 if perfConf is None:
1733 msg = "Device %s in unknown state -- remove and remodel" % self.titleOrId()
1734 if write is not None:
1735 write(msg)
1736 log.error("Unable to get collector info: %s", msg)
1737 if xmlrpc: return 1
1738 return
1739
1740 perfConf.collectDevice(self, setlog, REQUEST, generateEvents,
1741 background, write)
1742
1743 if xmlrpc: return 0
1744
1745
1746 security.declareProtected(ZEN_DELETE_DEVICE, 'deleteDevice')
1747 - def deleteDevice(self, deleteStatus=False, deleteHistory=False,
1748 deletePerf=False, REQUEST=None):
1749 """
1750 Delete device from the database
1751
1752 NB: deleteHistory is disabled for the 2.2 release. In some
1753 circumstances it was causing many subprocesses to be spawned
1754 and creating a gridlock situation.
1755
1756 NOTE: deleteStatus no longer deletes events from the summary
1757 table, but closes them.
1758
1759 @permission: ZEN_ADMIN_DEVICE
1760 """
1761 parent = self.getPrimaryParent()
1762 if deleteStatus:
1763
1764 zep = getFacade('zep')
1765 tagFilter = { 'tag_uuids': [IGlobalIdentifier(self).getGUID()] }
1766 eventFilter = { 'tag_filter': [ tagFilter ] }
1767 log.debug("Closing events for device: %s", self.getId())
1768 zep.closeEventSummaries(eventFilter=eventFilter)
1769 if deletePerf:
1770 perfserv = self.getPerformanceServer()
1771 if perfserv:
1772 perfserv.deleteRRDFiles(self.id)
1773 parent._delObject(self.getId())
1774 if REQUEST:
1775 if parent.getId()=='devices':
1776 parent = parent.getPrimaryParent()
1777 REQUEST['RESPONSE'].redirect(parent.absolute_url() +
1778 "/deviceOrganizerStatus"
1779 '?message=Device deleted')
1780
1781
1782 security.declareProtected(ZEN_ADMIN_DEVICE, 'renameDevice')
1784 """
1785 Rename device from the DMD. Disallow assignment of
1786 an id that already exists in the system.
1787
1788 @permission: ZEN_ADMIN_DEVICE
1789 @param newId: new name
1790 @type newId: string
1791 @param REQUEST: Zope REQUEST object
1792 @type REQUEST: Zope REQUEST object
1793 """
1794 parent = self.getPrimaryParent()
1795 path = self.absolute_url_path()
1796 oldId = self.getId()
1797 if newId is None:
1798 return path
1799
1800 if not isinstance(newId, unicode):
1801 newId = self.prepId(newId)
1802
1803 newId = newId.strip()
1804
1805 if newId == '' or newId == oldId:
1806 return path
1807
1808 device = self.dmd.Devices.findDeviceByIdExact( newId )
1809 if device:
1810 message = 'Device already exists with id %s' % newId
1811 raise DeviceExistsError( message, device )
1812
1813
1814 try:
1815
1816
1817 if self.title:
1818 self.title = newId
1819 parent.manage_renameObject(oldId, newId)
1820 self.renameDeviceInPerformance(oldId, newId)
1821 self.setLastChange()
1822 if sendUserAction and REQUEST:
1823 sendUserAction(ActionTargetType.Device, ActionName.Rename,
1824 device=self.getPrimaryId(), old=oldId)
1825
1826 return self.absolute_url_path()
1827
1828 except CopyError, e:
1829 raise Exception("Device rename failed.")
1830
1851
1852
1862
1863
1870
1871
1873 """
1874 IpAddresses aren't contained underneath Device, so manage_beforeDelete
1875 won't propagate. Thus we must remove those links explicitly.
1876 """
1877 cat = self.dmd.ZenLinkManager._getCatalog(layer=3)
1878 brains = cat(deviceId=self.id)
1879 for brain in brains:
1880 brain.getObject().unindex_links()
1881
1882
1902
1903
1905 """
1906 Called by Commandable.doCommand() to ascertain objects on which
1907 a UserCommand should be executed.
1908 """
1909 return [self]
1910
1919
1921 """
1922 Returns a URL to redirect to after a command has executed
1923 used by Commandable
1924 """
1925 return self.getPrimaryUrlPath() + '/deviceManagement'
1926
1928 """
1929 Returns HTML Event Summary of a device
1930 """
1931 html = []
1932 html.append("<table width='100%' cellspacing='1' cellpadding='3'>")
1933 html.append("<tr>")
1934 def evsummarycell(ev):
1935 if ev[1]-ev[2]>=0: klass = '%s empty thin' % ev[0]
1936 else: klass = '%s thin' % ev[0]
1937 h = '<th align="center" width="16%%" class="%s">%s/%s</th>' % (
1938 klass, ev[1], ev[2])
1939 return h
1940 info = self.getEventSummary(severity)
1941 html += map(evsummarycell, info)
1942 html.append('</tr></table>')
1943 return '\n'.join(html)
1944
1946 """
1947 Returns data ready for serialization
1948 """
1949 url, classurl = map(urlquote,
1950 (self.getDeviceUrl(), self.getDeviceClassPath()))
1951 id = '<a class="tablevalues" href="%s">%s</a>' % (
1952 url, self.titleOrId())
1953 ip = self.getDeviceIp()
1954 if self.checkRemotePerm(ZEN_VIEW, self.deviceClass()):
1955 path = '<a href="/zport/dmd/Devices%s">%s</a>' % (classurl,classurl)
1956 else:
1957 path = classurl
1958 prod = self.getProdState()
1959 evsum = getEventPillME(self, 1, minSeverity)[0]
1960 return [id, ip, path, prod, evsum, self.id]
1961
1963 """
1964 Add export of our child objects.
1965 """
1966 map(lambda o: o.exportXml(ofile, ignorerels), (self.hw, self.os))
1967
1969 """
1970 Returns a list of possible options for a given zProperty
1971 """
1972 if propname == 'zCollectorPlugins':
1973 from Products.DataCollector.Plugins import loadPlugins
1974 names = [ldr.pluginName for ldr in loadPlugins(self.dmd)]
1975 names.sort()
1976 return names
1977 if propname == 'zCommandProtocol':
1978 return ['ssh', 'telnet']
1979 if propname == 'zSnmpVer':
1980 return ['v1', 'v2c', 'v3']
1981 if propname == 'zSnmpAuthType':
1982 return ['', 'MD5', 'SHA']
1983 if propname == 'zSnmpPrivType':
1984 return ['', 'DES', 'AES']
1985 return ManagedEntity.zenPropertyOptions(self, propname)
1986
1987 security.declareProtected(ZEN_MANAGE_DEVICE, 'pushConfig')
1989 """
1990 This will result in a push of all the devices to live collectors
1991
1992 @permission: ZEN_MANAGE_DEVICE
1993 """
1994 self._p_changed = True
1995 if REQUEST:
1996 messaging.IMessageSender(self).sendToBrowser(
1997 'Changes Pushed',
1998 'Changes to %s pushed to collectors.' % self.id
1999 )
2000 return self.callZenScreen(REQUEST)
2001
2002 security.declareProtected(ZEN_EDIT_LOCAL_TEMPLATES, 'bindTemplates')
2004 """
2005 This will bind available templates to the zDeviceTemplates
2006
2007 @permission: ZEN_EDIT_LOCAL_TEMPLATES
2008 """
2009 return self.setZenProperty('zDeviceTemplates', ids, REQUEST)
2010
2011 security.declareProtected(ZEN_EDIT_LOCAL_TEMPLATES, 'removeZDeviceTemplates')
2025
2026 security.declareProtected(ZEN_EDIT_LOCAL_TEMPLATES, 'addLocalTemplate')
2043
2045 """
2046 Returns all available templates for this device
2047 """
2048
2049 templates = self.objectValues('RRDTemplate')
2050
2051
2052 templates += [t for t in self.deviceClass().getRRDTemplates()
2053 if t.id not in [r.id for r in templates]]
2054 def cmpTemplates(a, b):
2055 return cmp(a.id.lower(), b.id.lower())
2056 templates.sort(cmpTemplates)
2057 return [ t for t in templates
2058 if isinstance(self, t.getTargetPythonClass()) ]
2059
2060
2061 security.declareProtected(ZEN_VIEW, 'getLinks')
2076
2077 security.declareProtected(ZEN_VIEW, 'getXMLEdges')
2078 - def getXMLEdges(self, depth=3, filter="/", start=()):
2086
2087 security.declareProtected(ZEN_VIEW, 'getPrettyLink')
2089 """
2090 Gets a link to this device, plus an icon
2091
2092 @rtype: HTML text
2093 @permission: ZEN_VIEW
2094 """
2095 template = ("<div class='device-icon-container'>"
2096 "<img class='device-icon' src='%s'/> "
2097 "</div>%s")
2098 icon = self.getIconPath()
2099 href = altHref if altHref else self.getPrimaryUrlPath()
2100 name = self.titleOrId()
2101
2102 rendered = template % (icon, name)
2103
2104 if not self.checkRemotePerm(ZEN_VIEW, self):
2105 return rendered
2106 else:
2107 return "<a %s href='%s' class='prettylink'>%s</a>" % \
2108 ('target=' + target if target else '', href, rendered)
2109
2110
2112 """
2113 Get a list of dictionaries containing everything needed to match
2114 processes against the global list of process classes. Used by process
2115 modeler plugins.
2116 """
2117 matchers = []
2118 for pc in self.getDmdRoot("Processes").getSubOSProcessClassesSorted():
2119 matchers.append({
2120 'regex': pc.regex,
2121 'ignoreParameters': pc.ignoreParameters,
2122 'getPrimaryDmdId': pc.getPrimaryDmdId(),
2123 })
2124
2125 return matchers
2126
2128 """
2129 Returns either 4 or 6 depending on the version
2130 of the manageIp ip adddress
2131 """
2132 from ipaddr import IPAddress
2133 try:
2134 ip = self.getManageIp()
2135 return IPAddress(ip).version
2136 except ValueError:
2137
2138 pass
2139
2140 return 4
2141
2143 """
2144 This method gets the ip address prefix used for this device when running
2145 snmpwalk.
2146 @rtype: string
2147 @return: Prefix used for snmwalk for this device
2148 """
2149 if self.manageIpVersion() == 6:
2150 return "udp6:"
2151 return ""
2152
2154 """
2155 Used by the user commands this returns which ping command
2156 this device should use.
2157 @rtype: string
2158 @return "ping" or "ping6" depending on if the manageIp is ipv6 or not
2159 """
2160 if self.manageIpVersion() == 6:
2161 return "ping6"
2162 return "ping"
2163
2165 """
2166 Used by the user commands this returns which traceroute command
2167 this device should use.
2168 @rtype: string
2169 @return "traceroute" or "traceroute6" depending on if the manageIp is ipv6 or not
2170 """
2171 if self.manageIpVersion() == 6:
2172 return "traceroute6"
2173 return "traceroute"
2174
2237
2238 - def getStatus(self, statusclass=None, **kwargs):
2239 """
2240 Return the status number for this device of class statClass.
2241 """
2242 from Products.ZenEvents.ZenEventClasses import Status_Ping
2243 if statusclass == Status_Ping:
2244 from Products.Zuul import getFacade
2245 from Products.ZenEvents.events2.proxy import EventProxy
2246 from zenoss.protocols.protobufs.zep_pb2 import STATUS_NEW, STATUS_ACKNOWLEDGED, \
2247 SEVERITY_CRITICAL, SEVERITY_ERROR, SEVERITY_WARNING
2248
2249 zep = getFacade('zep', self)
2250 event_filter = zep.createEventFilter(tags=[self.getUUID()],
2251 severity=[SEVERITY_WARNING,SEVERITY_ERROR,SEVERITY_CRITICAL],
2252 status=[STATUS_NEW,STATUS_ACKNOWLEDGED],
2253 event_class=filter(None, [statusclass]),
2254 details={EventProxy.DEVICE_IP_ADDRESS_DETAIL_KEY: self.getManageIp()})
2255 result = zep.getEventSummaries(0, filter=event_filter, limit=0)
2256 return int(result['total'])
2257
2258 return super(Device, self).getStatus(statusclass, **kwargs)
2259
2260
2268
2273
2275 ip = self.getManageIp()
2276 if ip:
2277 ip = ip.partition('/')[0]
2278 return str(numbip(ip))
2279
2280 InitializeClass(Device)
2281