1
2
3
4
5
6
7
8
9
10
11
12
13
14 import os
15 import sys
16 import re
17 import time
18 import types
19 import socket
20 import logging
21 log = logging.getLogger("zen.Device")
22 from popen2 import Popen4
23
24 from _mysql_exceptions import OperationalError
25
26 from Products.ZenUtils.Graphics import NetworkGraph
27 from Products.ZenUtils.Utils import setWebLoggingStream, clearWebLoggingStream
28 from Products.ZenUtils.Utils import zenPath
29 from Products.ZenUtils import Time
30 import RRDView
31
32
33 from ManagedEntity import ManagedEntity
34
35 from AccessControl import ClassSecurityInfo
36 from Globals import DTMLFile
37 from Globals import InitializeClass
38 from Acquisition import aq_base
39 from DateTime import DateTime
40 from App.Dialogs import MessageDialog
41
42 from ZODB.POSException import POSError
43 from ZenossSecurity import *
44
45
46 from Products.DataCollector.ApplyDataMap import ApplyDataMap
47
48 from Products.ZenRelations.RelSchema import *
49 from Products.ZenUtils.IpUtil import isip
50 from Products.ZenEvents.ZenEventClasses import Status_Snmp
51 from UserCommand import UserCommand
52 from Commandable import Commandable
53 from Lockable import Lockable
54 from MaintenanceWindowable import MaintenanceWindowable
55 from AdministrativeRoleable import AdministrativeRoleable
56 from ZenMenuable import ZenMenuable
57
58 from OperatingSystem import OperatingSystem
59 from DeviceHW import DeviceHW
60
61 from ZenStatus import ZenStatus
62 from Exceptions import *
63 from ZenossSecurity import *
64 from Products.ZenUtils.Utils import edgesToXML
65 from Products.ZenUtils import NetworkTree
66
67 -def manage_createDevice(context, deviceName, devicePath="/Discovered",
68 tag="", serialNumber="",
69 zSnmpCommunity="", zSnmpPort=161, zSnmpVer="",
70 rackSlot=0, productionState=1000, comments="",
71 hwManufacturer="", hwProductName="",
72 osManufacturer="", osProductName="",
73 locationPath="", groupPaths=[], systemPaths=[],
74 statusMonitors=["localhost"], performanceMonitor="localhost",
75 discoverProto="snmp", priority=3):
76 """
77 Device factory creates a device and sets up its relations and collects its
78 configuration. SNMP Community discovery also happens here. If an IP is
79 passed for deviceName it will be used for collection and the device name
80 will be set to the SNMP SysName (or ptr if SNMP Fails and ptr is valid)
81
82 @rtype: Device
83 """
84 if isip(deviceName):
85 ip = deviceName
86 deviceName = ""
87 ipobj = context.getDmdRoot('Networks').findIp(ip)
88 if ipobj:
89 dev = ipobj.device()
90 if dev:
91 raise DeviceExistsError("Ip %s exists on %s" % (ip, deviceName))
92 else:
93 deviceName = context.prepId(deviceName)
94 try: ip = socket.gethostbyname(deviceName)
95 except socket.error: ip = ""
96 if context.getDmdRoot("Devices").findDevice(deviceName):
97 raise DeviceExistsError("Device %s already exists" % deviceName)
98 if not ip:
99 raise NoIPAddress("No IP found for name %s" % deviceName)
100 if discoverProto == "snmp":
101 zSnmpCommunity, zSnmpPort, zSnmpVer, snmpname = \
102 findCommunity(context, ip, devicePath,
103 zSnmpCommunity, zSnmpPort, zSnmpVer)
104 log.debug("device community = %s", zSnmpCommunity)
105 log.debug("device version = %s", zSnmpVer)
106 log.debug("device name = %s", snmpname)
107 if not deviceName:
108 try:
109 if snmpname and socket.gethostbyname(snmpname):
110 deviceName = snmpname
111 except socket.error: pass
112 try:
113 if (not deviceName and ipobj and ipobj.ptrName
114 and socket.gethostbyname(ipobj.ptrName)):
115 deviceName = ipobj.ptrName
116 except socket.error: pass
117 if not deviceName and snmpname:
118 deviceName = snmpname
119 if not deviceName:
120 log.warn("unable to name device using ip '%s'", ip)
121 deviceName = ip
122 elif discoverProto == "command":
123 raise ZenModelError("discover protocol 'ssh' not implemented yet")
124 if not deviceName:
125 deviceName = ip
126 log.info("device name '%s' for ip '%s'", deviceName, ip)
127 deviceClass = context.getDmdRoot("Devices").createOrganizer(devicePath)
128 deviceName = context.prepId(deviceName)
129 device = deviceClass.createInstance(deviceName)
130 device.setManageIp(ip)
131 device.manage_editDevice(
132 tag, serialNumber,
133 zSnmpCommunity, zSnmpPort, zSnmpVer,
134 rackSlot, productionState, comments,
135 hwManufacturer, hwProductName,
136 osManufacturer, osProductName,
137 locationPath, groupPaths, systemPaths,
138 statusMonitors, performanceMonitor, priority)
139
140
141
142
143
144
145
146
147
148
149 return device
150
151
154 """
155 Find the SNMP community and version for an p address using zSnmpCommunities.
156
157 @rtype: tuple of (community, port, version, device name)
158 """
159 try:
160 from pynetsnmp.SnmpSession import SnmpSession
161 except:
162 from Products.DataCollector.SnmpSession import SnmpSession
163
164 devroot = context.getDmdRoot('Devices').createOrganizer(devicePath)
165 communities = []
166 if community: communities.append(community)
167 communities.extend(getattr(devroot, "zSnmpCommunities", []))
168 if not port: port = getattr(devroot, "zSnmpPort", 161)
169 versions = ('v2c', 'v1')
170 if version: versions = (version)
171 timeout = getattr(devroot, "zSnmpTimeout", 2)
172 retries = getattr(devroot, "zSnmpTries", 2)
173 session = SnmpSession(ip, timeout=timeout, port=port, retries=retries)
174 sysTableOid = '.1.3.6.1.2.1.1'
175 oid = '.1.3.6.1.2.1.1.5.0'
176 goodcommunity = ""
177 goodversion = ""
178 devname = ""
179 for version in versions:
180 session.setVersion(version)
181 for community in communities:
182 session.community = community
183 try:
184 devname = session.get(oid).values()[0]
185 goodcommunity = session.community
186 goodversion = version
187 break
188 except (SystemExit, KeyboardInterrupt, POSError): raise
189 except: pass
190 if goodcommunity:
191 break
192 else:
193 raise NoSnmp("no snmp found for ip = %s" % ip)
194 return (goodcommunity, port, goodversion, devname)
195
205
206
207 addDevice = DTMLFile('dtml/addDevice',globals())
208
209
210 -class Device(ManagedEntity, Commandable, Lockable, MaintenanceWindowable,
211 AdministrativeRoleable, ZenMenuable):
212 """
213 Device is a base class that represents the idea of a single computer system
214 that is made up of software running on hardware. It currently must be IP
215 enabled but maybe this will change.
216 """
217
218 event_key = portal_type = meta_type = 'Device'
219
220 default_catalog = "deviceSearch"
221
222 relationshipManagerPathRestriction = '/Devices'
223
224 manageIp = ""
225 productionState = 1000
226 snmpAgent = ""
227 snmpDescr = ""
228 snmpOid = ""
229 snmpContact = ""
230 snmpSysName = ""
231 snmpLocation = ""
232 rackSlot = 0
233 comments = ""
234 sysedgeLicenseMode = ""
235 priority = 3
236
237 _properties = ManagedEntity._properties + (
238 {'id':'manageIp', 'type':'string', 'mode':'w'},
239 {'id':'productionState', 'type':'keyedselection', 'mode':'w',
240 'select_variable':'getProdStateConversions','setter':'setProdState'},
241 {'id':'snmpAgent', 'type':'string', 'mode':'w'},
242 {'id':'snmpDescr', 'type':'string', 'mode':''},
243 {'id':'snmpOid', 'type':'string', 'mode':''},
244 {'id':'snmpContact', 'type':'string', 'mode':''},
245 {'id':'snmpSysName', 'type':'string', 'mode':''},
246 {'id':'snmpLocation', 'type':'string', 'mode':''},
247 {'id':'snmpLastCollection', 'type':'date', 'mode':''},
248 {'id':'snmpAgent', 'type':'string', 'mode':''},
249 {'id':'rackSlot', 'type':'int', 'mode':'w'},
250 {'id':'comments', 'type':'text', 'mode':'w'},
251 {'id':'sysedgeLicenseMode', 'type':'string', 'mode':''},
252 {'id':'priority', 'type':'int', 'mode':'w'},
253 )
254
255 _relations = ManagedEntity._relations + (
256 ("deviceClass", ToOne(ToManyCont, "Products.ZenModel.DeviceClass",
257 "devices")),
258
259
260 ("monitors", ToMany(ToMany, "Products.ZenModel.StatusMonitorConf",
261 "devices")),
262 ("perfServer", ToOne(ToMany, "Products.ZenModel.PerformanceConf",
263 "devices")),
264 ("location", ToOne(ToMany, "Products.ZenModel.Location", "devices")),
265 ("systems", ToMany(ToMany, "Products.ZenModel.System", "devices")),
266 ("groups", ToMany(ToMany, "Products.ZenModel.DeviceGroup", "devices")),
267 ("maintenanceWindows",ToManyCont(ToOne,
268 "Products.ZenModel.MaintenanceWindow", "productionState")),
269 ("adminRoles", ToManyCont(ToOne,"Products.ZenModel.AdministrativeRole",
270 "managedObject")),
271 ('userCommands', ToManyCont(ToOne, 'Products.ZenModel.UserCommand',
272 'commandable')),
273
274
275 )
276
277
278 factory_type_information = (
279 {
280 'id' : 'Device',
281 'meta_type' : 'Device',
282 'description' : """Base class for all devices""",
283 'icon' : 'Device_icon.gif',
284 'product' : 'ZenModel',
285 'factory' : 'manage_addDevice',
286 'immediate_view' : 'deviceStatus',
287 'actions' :
288 (
289 { 'id' : 'status'
290 , 'name' : 'Status'
291 , 'action' : 'deviceStatus'
292 , 'permissions' : (ZEN_VIEW, )
293 },
294 { 'id' : 'osdetail'
295 , 'name' : 'OS'
296 , 'action' : 'os/deviceOsDetail'
297 , 'permissions' : (ZEN_VIEW, )
298 },
299 { 'id' : 'hwdetail'
300 , 'name' : 'Hardware'
301 , 'action' : 'deviceHardwareDetail'
302 , 'permissions' : (ZEN_VIEW, )
303 },
304 { 'id' : 'swdetail'
305 , 'name' : 'Software'
306 , 'action' : 'deviceSoftwareDetail'
307 , 'permissions' : (ZEN_VIEW, )
308 },
309 { 'id' : 'events'
310 , 'name' : 'Events'
311 , 'action' : 'viewEvents'
312 , 'permissions' : (ZEN_VIEW, )
313 },
314 { 'id' : 'historyEvents'
315 , 'name' : 'History'
316 , 'action' : 'viewHistoryEvents'
317 , 'permissions' : (ZEN_VIEW, )
318 },
319 { 'id' : 'perfServer'
320 , 'name' : 'Perf'
321 , 'action' : 'viewDevicePerformance'
322 , 'permissions' : (ZEN_VIEW, )
323 },
324
325
326
327
328
329 { 'id' : 'edit'
330 , 'name' : 'Edit'
331 , 'action' : 'editDevice'
332 , 'permissions' : ("Change Device",)
333 },
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359 )
360 },
361 )
362
363 security = ClassSecurityInfo()
364
375
376
385
387 """
388 Returns all the templates bound to this Device
389
390 @rtype: list
391
392 >>> from Products.ZenModel.Device import manage_addDevice
393 >>> manage_addDevice(devices, 'test')
394 >>> devices.test.getRRDTemplates()
395 [<RRDTemplate at /zport/dmd/Devices/rrdTemplates/Device>]
396 """
397 if not hasattr(self, 'zDeviceTemplates'):
398 return ManagedEntity.getRRDTemplates(self)
399 result = []
400 for name in self.zDeviceTemplates:
401 template = self.getRRDTemplateByName(name)
402 if template:
403 result.append(template)
404 return result
405
406
409
410
412 """
413 Returns the available DataSource options. DataSource options
414 are used to populate the dropdown when adding a new DataSource
415 and is a string. See L{RRDTemplate.RRDTemplate.getDataSourceOptions}
416 for more information.
417
418 @rtype: list
419 @return: [(displayName, dsOption),]
420 """
421
422
423
424
425
426 templates = self.getRRDTemplates()
427 if templates:
428 return templates[0].getDataSourceOptions()
429 return []
430
431
432
433
434
435
436
437
438
440 """
441 Returns the cached sysUpTime for this device
442
443 @rtype: int
444 """
445 try:
446 return self.cacheRRDValue('sysUpTime', -1)
447 except Exception:
448 log.exception("failed getting sysUpTime")
449 return -1
450
451
453 """
454 Returns the uptime of this device
455
456 @rtype: string
457 @todo: Performance enhancement: Should move import outside of method
458 """
459 from Products.ZenEvents import Availability
460 results = Availability.query(self.dmd, device=self.id, *args, **kw)
461 if results:
462 return results[0]
463 else:
464 return None
465
466
468 """
469 Override from object to handle lastPollSnmpUpTime and
470 snmpLastCollection
471
472 @todo: Not sure this is needed, see getLastPollSnmpUpTime and
473 getSnmpLastCollection
474 """
475 if name == 'lastPollSnmpUpTime':
476 return self._lastPollSnmpUpTime.getStatus()
477 elif name == 'snmpLastCollection':
478 return DateTime(self._snmpLastCollection)
479 else:
480 raise AttributeError, name
481
482
484 """
485 Override from PropertyManager to handle checks and ip creation
486
487 @todo: Not sure this is needed, see setSnmpLastCollection
488 """
489 self._wrapperCheck(value)
490 if id == 'snmpLastCollection':
491 self._snmpLastCollection = float(value)
492 else:
493 ManagedEntity._setPropValue(self, id, value)
494
495
496 - def applyDataMap(self, datamap, relname="", compname="", modname=""):
503
504
506 """
507 Trace the route to target using our routing table.
508 Wrapper method of OperatingSystem.traceRoute
509
510 @param target: Device name
511 @type target: string
512 @param ippath: IP addesses
513 @type ippath: list
514 @return: IP Addresses
515 @rtype: list
516 """
517 if ippath is None: ippath=[]
518 if type(target) in types.StringTypes:
519 target = self.findDevice(target)
520 if not target: raise ValueError("target %s not found in dmd",target)
521 return self.os.traceRoute(target, ippath)
522
523
525 """
526 Return list of monitored DeviceComponents on this device.
527 Wrapper method for getDeviceComponents
528 """
529 return self.getDeviceComponents(monitored=True,
530 collector=collector, type=type)
531
532 security.declareProtected(ZEN_VIEW, 'getDeviceComponents')
534 """
535 Return list of all DeviceComponents on this device.
536
537 @type monitored: boolean
538 @type collector: string
539 @type type: string
540 @permission: ZEN_VIEW
541 @rtype: list
542 """
543 query = {
544 'getParentDeviceName':self.id,
545 }
546 if collector is not None:
547 query['getCollectors'] = collector
548 if monitored is not None:
549 query['monitored'] = monitored
550 if type is not None:
551 query['meta_type'] = type
552 brains = self.componentSearch(query)
553 return [c.getObject() for c in brains]
554
555
557 """
558 Return a list of all device components by walking relations. This is
559 much slower then the normal getDeviceComponents method which uses the
560 component index. It is used when rebuilding the device indexes.
561 """
562 from DeviceComponent import DeviceComponent
563 for baseObject in (self, self.os, self.hw):
564 for rel in baseObject.getRelationships():
565 if rel.meta_type != "ToManyContRelationship": continue
566 for obj in rel():
567 if not isinstance(obj, DeviceComponent): break
568 yield obj
569
570
572 """
573 Returns a tuple of SNMP Connection Info
574
575 @rtype: tuple (devname, (ip, port),
576 (community, version, timeout, tries), zMaxOIDPerRequest)
577
578 >>> from Products.ZenModel.Device import manage_addDevice
579 >>> manage_addDevice(devices, 'test')
580 >>> devices.test.getSnmpConnInfo()
581 ('test', ('', 161), ('public', 'v1', 2.5, 2), 40)
582 """
583 return (self.id,
584 (self.manageIp, self.zSnmpPort),
585 (self.zSnmpCommunity, self.zSnmpVer,
586 self.zSnmpTimeout, self.zSnmpTries),
587 self.zMaxOIDPerRequest)
588
589
591 """
592 Returns process monitoring configuration
593
594 @rtype: tuple (lastChangeTimeInSecs, (devname, (ip, port),
595 (community, version, timeout, tries), zMaxOIDPerRequest),
596 list of configs, list of thresholds)
597 """
598 if not self.snmpMonitorDevice():
599 return None
600 procs = self.getMonitoredComponents(collector='zenprocess')
601 if not procs:
602 return None
603 config = [ p.getOSProcessConf() for p in procs ]
604 threshs = [t for p in procs for t in p.getThresholdInstances('SNMP')]
605 return (float(self.getLastChange()),
606 self.getSnmpConnInfo(),
607 config,
608 threshs)
609
610
612 """
613 Return information for snmp collection on this device
614
615 @rtype: tuple (lastChangeTimeInSecs, (devname, (ip, port),
616 (community, version, timeout, tries), zMaxOIDPerRequest),
617 list of thresholds,
618 list of oids)
619
620 >>> from Products.ZenModel.Device import manage_addDevice
621 >>> manage_addDevice(devices, 'test')
622 >>> devices.test.getSnmpOidTargets()
623 (0.0, ('test', ('', 161), ('public', 'v1', 2.5, 2), 40), [],
624 [('sysUpTime', '1.3.6.1.2.1.1.3.0', 'Devices/test/sysUpTime_sysUpTime',
625 'GAUGE', '', (None, None))])
626 """
627 if not self.snmpMonitorDevice(): return None
628 oids, threshs = (super(Device, self).getSnmpOidTargets())
629 for o in self.os.getMonitoredComponents(collector="zenperfsnmp"):
630 o, t = o.getSnmpOidTargets()
631 oids.extend(o)
632 threshs.extend(t)
633 return (float(self.getLastChange()),
634 self.getSnmpConnInfo(),
635 threshs,
636 oids)
637
638
640 """
641 Return list of command definitions on this device
642
643 @rtype: tuple (lastChangeTimeInSecs, (devname, (ip, port),
644 (community, version, timeout, tries), zMaxOIDPerRequest),
645 list of thresholds,
646 list of commands)
647 """
648 if not self.monitorDevice():
649 return []
650 cmds, threshs = (super(Device, self).getDataSourceCommands())
651 for o in self.getMonitoredComponents(collector="zencommand"):
652 c, t = o.getDataSourceCommands()
653 cmds.extend(c)
654 threshs.extend(t)
655 if cmds:
656 return (float(self.getLastChange()),
657 self.id, self.getManageIp(), self.zCommandPort,
658 self.zCommandUsername, self.zCommandPassword,
659 self.zCommandLoginTimeout, self.zCommandCommandTimeout,
660 self.zKeyPath,self.zMaxOIDPerRequest,
661 cmds, threshs)
662
663
665 """
666 Return information for xmlrpc collection on this device
667
668 @rtype: tuple (devname, xmlRpcStatus,
669 (url, methodName),
670 [(name, path, type, createCmd, thresholds)])
671 """
672 targets = (super(Device, self).getXmlRpcTargets())
673 return (self.id, self.getXmlRpcStatus(), targets)
674
675
677 """
678 DEPRECATED - Return the hardware manufacturer name of this device.
679
680 @rtype: string
681 @todo: Remove this method and remove the call from testDevice.py
682 """
683 return self.hw.getManufacturerName()
684
685
687 """
688 Return the hardware product name of this device.
689
690 @rtype: string
691 """
692 return self.hw.getProductName()
693
694
696 """
697 DEPRECATED - Return the productKey of the device hardware.
698
699 @rtype: string
700 @todo: Remove this method and remove the call from testDevice.py
701 """
702 return self.hw.getProductKey()
703
704
706 """
707 DEPRECATED - Return the OS manufacturer name of this device.
708
709 @rtype: string
710 @todo: Remove this method and remove the call from testDevice.py
711 """
712 return self.os.getManufacturerName()
713
714
716 """
717 DEPRECATED - Return the OS product name of this device.
718
719 @rtype: string
720 @todo: Remove this method and remove the call from testDevice.py
721 """
722 return self.os.getProductName()
723
724
726 """
727 DEPRECATED - Return the productKey of the device OS.
728
729 @rtype: string
730 @todo: Remove this method and remove the call from testDevice.py
731 """
732 return self.os.getProductKey()
733
734
736 """
737 Set the productKey of the device OS.
738 """
739 self.os.setProductKey(prodKey)
740
741
743 """
744 Set the productKey of the device hardware.
745 """
746 self.hw.setProductKey(prodKey)
747
748
750 """
751 Set the hardware serial number.
752 """
753 self.hw.serialNumber = number
754
755
757 """
758 DEPRECATED - Return the hardware serial number.
759
760 @rtype: string
761 @todo: Remove this method and remove the call from testDevice.py
762 """
763 return self.hw.serialNumber
764
765
767 """
768 Return the ips that our indirect routs point to which aren't currently
769 connected to devices.
770
771 @todo: Can be moved to zendisc.py
772 """
773 ips = []
774 for r in self.os.routes():
775 ipobj = r.nexthop()
776
777 if ipobj: ips.append(ipobj.id)
778 return ips
779
780
781 security.declareProtected(ZEN_VIEW, 'getLocationName')
783 """
784 Return the full location name ie /Location/SubLocation/Rack
785
786 @rtype: string
787 @permission: ZEN_VIEW
788 """
789 loc = self.location()
790 if loc: return loc.getOrganizerName()
791 return ""
792
793 security.declareProtected(ZEN_VIEW, 'getLocationLink')
795 """
796 Return a link to the device's location.
797
798 @rtype: string
799 @permission: ZEN_VIEW
800 """
801 loc = self.location()
802 if loc:
803 if self.checkRemotePerm("View", loc):
804 return "<a href='%s'>%s</a>" % (loc.getPrimaryUrlPath(),
805 loc.getOrganizerName())
806 else:
807 return loc.getOrganizerName()
808 return "None"
809
810
811 security.declareProtected(ZEN_VIEW, 'getSystemNames')
813 """
814 Return the system names for this device
815
816 @rtype: list
817 @permission: ZEN_VIEW
818 """
819 return map(lambda x: x.getOrganizerName(), self.systems())
820
821
822 security.declareProtected(ZEN_VIEW, 'getSystemNamesString')
824 """
825 Return the system names for this device as a string
826
827 @rtype: string
828 @permission: ZEN_VIEW
829 """
830 return sep.join(self.getSystemNames())
831
832
833 security.declareProtected(ZEN_VIEW, 'getDeviceGroupNames')
835 """
836 Return the device group names for this device
837
838 @rtype: list
839 @permission: ZEN_VIEW
840 """
841 return map(lambda x: x.getOrganizerName(), self.groups())
842
843
844 security.declareProtected(ZEN_VIEW, 'getStatusMonitorNames')
846 """
847 Return status monitor names
848
849 @rtype: string
850 @permission: ZEN_VIEW
851 """
852 return map(lambda x: x.getId(), self.monitors())
853
854
855 security.declareProtected(ZEN_VIEW, 'getPerformanceServer')
864
865
866 security.declareProtected(ZEN_VIEW, 'getPerformanceServerName')
877
878
879 security.declareProtected(ZEN_VIEW, 'getLastChange')
881 """
882 Return DateTime of last change detected on this device.
883
884 @rtype: DateTime
885 @permission: ZEN_VIEW
886 """
887 return DateTime(float(self._lastChange))
888
889
890 security.declareProtected(ZEN_VIEW, 'getLastChangeString')
892 """
893 Return date string of last change detected on this device.
894
895 @rtype: string
896 @permission: ZEN_VIEW
897 """
898 return Time.LocalDateTime(float(self._lastChange))
899
900
901 security.declareProtected(ZEN_VIEW, 'getSnmpLastCollection')
903 """
904 Return DateTime of last SNMP collection on this device.
905
906 @rtype: DateTime
907 @permission: ZEN_VIEW
908 """
909 return DateTime(float(self._snmpLastCollection))
910
911
912 security.declareProtected(ZEN_VIEW, 'getSnmpLastCollectionString')
914 """
915 Return date string of last SNMP collection on this device.
916
917 @rtype: string
918 @permission: ZEN_VIEW
919 """
920 return Time.LocalDateTime(float(self._snmpLastCollection))
921
922
923 security.declareProtected(ZEN_ADMIN_DEVICE, 'setManageIp')
942
943
944 security.declareProtected(ZEN_VIEW, 'getManageIp')
946 """
947 Return the management ip for this device.
948
949 @rtype: string
950 @permission: ZEN_VIEW
951 """
952 return self.manageIp
953
954
956 """
957 DEPRECATED - Return the management ipobject for this device.
958
959 @rtype: IpAddress
960 @todo: This method may not be called anywhere, remove it.
961 """
962 if self.manageIp:
963 return self.Networks.findIp(self.manageIp)
964
965
966 security.declareProtected(ZEN_VIEW, 'getManageInterface')
968 """
969 Return the management interface of a device based on its manageIp.
970
971 @rtype: IpInterface
972 @permission: ZEN_VIEW
973 """
974 ipobj = self.Networks.findIp(self.manageIp)
975 if ipobj: return ipobj.interface()
976
977
978 security.declareProtected(ZEN_VIEW, 'uptimeStr')
980 """"
981 Return the SNMP uptime
982
983 @rtype: string
984 @permission: ZEN_VIEW
985 """
986 ut = self.sysUpTime()
987 if ut < 0:
988 return "Unknown"
989 elif ut == 0:
990 return "0d:0h:0m:0s"
991 ut = float(ut)/100.
992 days = ut/86400
993 hour = (ut%86400)/3600
994 mins = (ut%3600)/60
995 secs = ut%60
996 return "%02dd:%02dh:%02dm:%02ds" % (
997 days, hour, mins, secs)
998
999
1001 """
1002 Build a list of all device paths that have the python class pyclass
1003
1004 @rtype: list
1005 """
1006 dclass = self.getDmdRoot("Devices")
1007 return dclass.getPeerDeviceClassNames(self.__class__)
1008
1009
1011 """
1012 DEPRECATED - Return true if pydot is installed.
1013
1014 @todo: This method may not be called anywhere, remove it.
1015 """
1016 try:
1017 import pydot
1018 return True
1019 except ImportError:
1020 return False
1021
1022
1023 security.declareProtected(ZEN_VIEW, 'getRouterGraph')
1025 """
1026 Return a graph representing the relative routers
1027
1028 @rtype: graph
1029 @permission: ZEN_VIEW
1030 """
1031 from Products.ZenStatus import pingtree
1032 node = pingtree.buildTree(self)
1033 g = NetworkGraph(node=node, parentName=self.id)
1034
1035 self.REQUEST.RESPONSE.setHeader('Content-Type', 'image/%s' % g.format)
1036 return g.render()
1037
1038
1039 security.declareProtected(ZEN_VIEW, 'getNetworkGraph')
1041 """
1042 Return a graph representing the relative routers as well as the
1043 networks
1044
1045 @rtype: graph
1046 @permission: ZEN_VIEW
1047 """
1048 from Products.ZenStatus import pingtree
1049 node = pingtree.buildTree(self)
1050 g = NetworkGraph(node=node, parentName=self.id)
1051
1052 self.REQUEST.RESPONSE.setHeader('Content-Type', 'image/%s' % g.format)
1053 return g.render(withNetworks=True)
1054
1055
1056
1057
1058
1059 security.declareProtected(ZEN_CHANGE_DEVICE, 'manage_snmpCommunity')
1061 """Reset the snmp community using the zSnmpCommunities variable.
1062 """
1063 try:
1064 zSnmpCommunity, zSnmpPort, zSnmpVer, snmpname = \
1065 findCommunity(self, self.manageIp, self.getDeviceClassPath(),
1066 port=self.zSnmpPort, version=self.zSnmpVer)
1067 except NoSnmp:
1068 pass
1069 else:
1070 if self.zSnmpCommunity != zSnmpCommunity:
1071 self.setZenProperty("zSnmpCommunity", zSnmpCommunity)
1072 if self.zSnmpPort != zSnmpPort:
1073 self.setZenProperty("zSnmpPort", zSnmpPort)
1074 if self.zSnmpVer != zSnmpVer:
1075 self.setZenProperty("zSnmpVer", zSnmpVer)
1076
1077
1078 security.declareProtected(ZEN_CHANGE_DEVICE, 'manage_editDevice')
1079 - def manage_editDevice(self,
1080 tag="", serialNumber="",
1081 zSnmpCommunity="", zSnmpPort=161, zSnmpVer="",
1082 rackSlot=0, productionState=1000, comments="",
1083 hwManufacturer="", hwProductName="",
1084 osManufacturer="", osProductName="",
1085 locationPath="", groupPaths=[], systemPaths=[],
1086 statusMonitors=["localhost"], performanceMonitor="localhost",
1087 priority=3, REQUEST=None):
1140
1141
1143 """Is device production state >= zProdStateThreshold.
1144 """
1145 return self.productionState >= self.zProdStateThreshold
1146
1147
1149 "Is this device subject to SNMP monitoring?"
1150 return (self.monitorDevice()
1151 and not self.zSnmpMonitorIgnore
1152 and self.zSnmpCommunity)
1153
1154
1159
1164
1169
1174
1175 security.declareProtected(ZEN_CHANGE_DEVICE, 'setProdState')
1199
1200 security.declareProtected(ZEN_CHANGE_DEVICE, 'setPriority')
1222
1223 security.declareProtected(ZEN_CHANGE_DEVICE, 'setLastChange')
1225 """Set the changed datetime for this device. value default is now.
1226 """
1227 if value is None:
1228 value = time.time()
1229 self._lastChange = float(value)
1230
1231 security.declareProtected(ZEN_CHANGE_DEVICE, 'setSnmpLastCollection')
1233 """Set the last time snmp collection occurred. value default is now.
1234 """
1235 if value is None:
1236 value = time.time()
1237 self._snmpLastCollection = float(value)
1238
1239
1240 security.declareProtected(ZEN_CHANGE_DEVICE, 'addManufacturer')
1243 """Add a manufacturer to the database"""
1244 mname = newHWManufacturerName
1245 field = 'hwManufacturer'
1246 if not mname:
1247 mname = newSWManufacturerName
1248 field = 'osManufacturer'
1249 self.getDmdRoot("Manufacturers").createManufacturer(mname)
1250 if REQUEST:
1251 REQUEST[field] = mname
1252 REQUEST['message'] = ("Added Manufacturer %s at time:" % mname)
1253 return self.callZenScreen(REQUEST)
1254
1255
1256 security.declareProtected(ZEN_CHANGE_DEVICE, 'setHWProduct')
1259 """set the productName of this device"""
1260 added = False
1261 if newHWProductName and hwManufacturer:
1262 self.getDmdRoot("Manufacturers").createHardwareProduct(
1263 newHWProductName, hwManufacturer)
1264 added = True
1265 if REQUEST:
1266 if added:
1267 REQUEST['message'] = "Hardware product set"
1268 REQUEST['hwProductName'] = newHWProductName
1269 else:
1270 REQUEST['message'] = "Hardware product was not set"
1271 return self.callZenScreen(REQUEST)
1272
1273
1274 security.declareProtected(ZEN_CHANGE_DEVICE, 'setOSProduct')
1287
1288
1289 security.declareProtected(ZEN_CHANGE_DEVICE, 'setLocation')
1298
1299
1307
1308
1309 security.declareProtected(ZEN_CHANGE_DEVICE, 'setPerformanceMonitor')
1327
1328
1329 security.declareProtected(ZEN_CHANGE_DEVICE, 'setStatusMonitors')
1336
1337
1338 security.declareProtected(ZEN_CHANGE_DEVICE, 'addStatusMonitor')
1350
1351
1352 security.declareProtected(ZEN_CHANGE_DEVICE, 'setGroups')
1354 """set the list of groups for this device based on a list of paths"""
1355 objGetter = self.getDmdRoot("Groups").createOrganizer
1356 self._setRelations("groups", objGetter, groupPaths)
1357
1358
1359 security.declareProtected(ZEN_CHANGE_DEVICE, 'addDeviceGroup')
1367
1368
1369 security.declareProtected(ZEN_CHANGE_DEVICE, 'setSystems')
1371 """set a list of systems to this device using their system paths"""
1372 objGetter = self.getDmdRoot("Systems").createOrganizer
1373 self._setRelations("systems", objGetter, systemPaths)
1374
1375
1376 security.declareProtected(ZEN_CHANGE_DEVICE, 'addSystem')
1384
1385
1386 security.declareProtected(ZEN_CHANGE_DEVICE, 'setTerminalServer')
1388 termserver = self.findDevice(termservername)
1389 if termserver:
1390 self.addRelation('termserver', termserver)
1391
1392
1413
1414
1423
1424
1425
1426
1427
1428 security.declareProtected(ZEN_VIEW, 'device')
1430 """support DeviceResultInt mixin class"""
1431 return self
1432
1433
1434
1435
1436
1437
1438
1440 """Device has more SNMP failures than maxFailures on its status mon."""
1441 statusmon = self.monitors()
1442 if len(statusmon) > 0:
1443 statusmon = statusmon[0]
1444 return statusmon.maxFailures < self.getSnmpStatusNumber()
1445 return False
1446
1447
1448 security.declareProtected(ZEN_MANAGE_DEVICE_STATUS,
1449 'getLastPollSnmpUpTime')
1451 """set the value of the snmpUpTime status object"""
1452 return self._lastPollSnmpUpTime.getStatus()
1453
1454
1455 security.declareProtected(ZEN_MANAGE_DEVICE_STATUS,
1456 'setLastPollSnmpUpTime')
1458 """set the value of the snmpUpTime status object"""
1459 self._lastPollSnmpUpTime.setStatus(value)
1460
1461
1462 - def snmpAgeCheck(self, hours):
1463 lastcoll = self.getSnmpLastCollection()
1464 hours = hours/24.0
1465 if DateTime() > lastcoll + hours: return 1
1466
1467
1469 """Apply zProperties inherited from Product Contexts.
1470 """
1471 self._applyProdContext(self.hw.getProductContext())
1472 self._applyProdContext(self.os.getProductContext())
1473 for soft in self.os.software():
1474 self._applyProdContext(soft.getProductContext())
1475
1476
1477 - def _applyProdContext(self, context):
1478 """Apply zProperties taken for the product context passed in.
1479 context is a list of tuples returned from getProductContext
1480 on a MEProduct.
1481 """
1482 for name, value in context:
1483 if name == "zDeviceClass" and value:
1484 log.info("move device to %s", value)
1485 self.moveDevices(value, self.id)
1486 elif name == "zDeviceGroup" and value:
1487 log.info("add device to group %s", value)
1488 self.addDeviceGroup(value)
1489 elif name == "zSystem" and value:
1490 log.info("add device to system %s", value)
1491 self.addSystem(value)
1492
1493
1494
1495
1496
1497
1498
1499 security.declareProtected(ZEN_MANAGE_DEVICE, 'collectDevice')
1501 """collect the configuration of this device.
1502 """
1503 response = None
1504 if REQUEST and setlog:
1505 response = REQUEST.RESPONSE
1506 dlh = self.deviceLoggingHeader()
1507 idx = dlh.rindex("</table>")
1508 dlh = dlh[:idx]
1509 idx = dlh.rindex("</table>")
1510 dlh = dlh[:idx]
1511 response.write(str(dlh[:idx]))
1512 handler = setWebLoggingStream(response)
1513
1514 try:
1515 zm = zenPath('bin', 'zenmodeler')
1516 zenmodelerCmd = [zm, 'run', '--now','-F','-d', self.id]
1517 if REQUEST: zenmodelerCmd.append("--weblog")
1518 log.info('Executing command: %s' % ' '.join(zenmodelerCmd))
1519 f = Popen4(zenmodelerCmd)
1520 while 1:
1521 s = f.fromchild.readline()
1522 if not s:
1523 break
1524 elif response:
1525 response.write(s)
1526 response.flush()
1527 else:
1528 sys.stdout.write(s)
1529 except (SystemExit, KeyboardInterrupt): raise
1530 except ZentinelException, e:
1531 log.critical(e)
1532 except: raise
1533
1534 if REQUEST and setlog:
1535 response.write(self.loggingFooter())
1536 clearWebLoggingStream(handler)
1537 REQUEST['message'] = "Configuration collected"
1538
1539
1540
1541
1542
1543
1544 security.declareProtected(ZEN_ADMIN_DEVICE, 'deleteDevice')
1557
1558 security.declareProtected(ZEN_MANAGE_DEVICE, 'manage_deleteHeartbeat')
1565
1566
1567 security.declareProtected(ZEN_ADMIN_DEVICE, 'renameDevice')
1579
1580
1587
1588
1593
1594
1596 """
1597 Device only propagates beforeDelete if we are being deleted or copied.
1598 Moving and renaming don't propagate.
1599 """
1600 super(Device,self).manage_beforeDelete(item, container)
1601 self.unindex_object()
1602
1603
1621
1622
1624 """ Called by Commandable.doCommand() to ascertain objects on which
1625 a UserCommand should be executed.
1626 """
1627 return [self]
1628
1634
1637
1639 html = []
1640 html.append("<table width='100%' cellspacing='1' cellpadding='3'>")
1641 html.append("<tr>")
1642 def evsummarycell(ev):
1643 if ev[1]-ev[2]>=0: klass = '%s empty thin' % ev[0]
1644 else: klass = '%s thin' % ev[0]
1645 h = '<th align="center" width="16%%" class="%s">%s/%s</th>' % (
1646 klass, ev[1], ev[2])
1647 return h
1648 info = self.getEventSummary(severity)
1649 html += map(evsummarycell, info)
1650 html.append('</tr></table>')
1651 return '\n'.join(html)
1652
1670
1672 """Add export of our child objects.
1673 """
1674 map(lambda o: o.exportXml(ofile, ignorerels), (self.hw, self.os))
1675
1683
1684 security.declareProtected(ZEN_MANAGE_DEVICE, 'pushConfig')
1686 "This will result in a push of all the devices to live collectors"
1687 self._p_changed = True
1688 if REQUEST:
1689 REQUEST['message'] = 'Changes to %s pushed to collectors' % self.id
1690 return self.callZenScreen(REQUEST)
1691
1692 security.declareProtected(ZEN_EDIT_LOCAL_TEMPLATES, 'bindTemplates')
1694 "This will bind available templates to the zDeviceTemplates"
1695 return self.setZenProperty('zDeviceTemplates', ids, REQUEST)
1696
1697 security.declareProtected(ZEN_EDIT_LOCAL_TEMPLATES, 'removeZDeviceTemplates')
1703
1704 security.declareProtected(ZEN_EDIT_LOCAL_TEMPLATES, 'addLocalTemplate')
1714
1716 "Returns all available templates for this device"
1717
1718 templates = self.objectValues('RRDTemplate')
1719
1720
1721 templates += [t for t in self.deviceClass().getRRDTemplates()
1722 if t.id not in [r.id for r in templates]]
1723 def cmpTemplates(a, b):
1724 return cmp(a.id.lower(), b.id.lower())
1725 templates.sort(cmpTemplates)
1726 return templates
1727
1728 security.declareProtected(ZEN_VIEW, 'getLinks')
1739
1740 security.declareProtected(ZEN_VIEW, 'getXMLEdges')
1741 - def getXMLEdges(self, depth=3, filter="/", start=()):
1747
1748 security.declareProtected(ZEN_VIEW, 'getPrettyLink')
1750 """ Gets a link to this device, plus an icon """
1751 template = ("<div class='device-icon-container'>"
1752 "<img class='device-icon' src='%s'/> "
1753 "</div>%s")
1754 icon = self.getIconPath()
1755 href = self.getPrimaryUrlPath().replace('%','%%')
1756 name = self.id
1757 linktemplate = "<a href='"+href+"' class='prettylink'>%s</a>"
1758 rendered = template % (icon, name)
1759 if not self.checkRemotePerm("View", self):
1760 return rendered
1761 else:
1762 return linktemplate % rendered
1763
1764 security.declareProtected(ZEN_VIEW, 'getEventPill')
1766 """ Gets an event pill representing the highest severity """
1767 pill = self.ZenEventManager.getEventPillME(self, showGreen=showGreen)
1768 if type(pill)==type([]) and len(pill)==1: return pill[0]
1769 return pill
1770
1774
1775
1776 InitializeClass(Device)
1777