| Trees | Indices | Help |
|
|---|
|
|
1 ###########################################################################
2 #
3 # This program is part of Zenoss Core, an open source monitoring platform.
4 # Copyright (C) 2007, Zenoss Inc.
5 #
6 # This program is free software; you can redistribute it and/or modify it
7 # under the terms of the GNU General Public License version 2 as published by
8 # the Free Software Foundation.
9 #
10 # For complete information please visit: http://www.zenoss.com/oss/
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 # base classes for device
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 #from Products.SnmpCollector.SnmpCollector import findSnmpCommunity
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 # Not sure why this was important but it causes issues if
140 # we are adding an alias to an existing box. It will take
141 # away that boxes IP. It also seems to make a network with
142 # the wrong netmask.
143 # if discoverProto == "none":
144 # from Products.ZenModel.IpInterface import IpInterface
145 # tmpInterface = IpInterface('eth0')
146 # device.os.interfaces._setObject('eth0', tmpInterface)
147 # interface = device.getDeviceComponents()[0]
148 # interface.addIpAddress(device.getManageIp())
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 #keep trying until we run out
190 if goodcommunity:
191 break
192 else:
193 raise NoSnmp("no snmp found for ip = %s" % ip)
194 return (goodcommunity, port, goodversion, devname)
195
197 """
198 Creates a device
199 """
200 serv = Device(id)
201 context._setObject(serv.id, serv)
202 if REQUEST is not None:
203 REQUEST['message'] = "Device created"
204 REQUEST['RESPONSE'].redirect(context.absolute_url()+'/manage_main')
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" #device ZCatalog
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 #("termserver", ToOne(ToMany, "Products.ZenModel.TerminalServer",
259 # "devices")),
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 #("dhcpubrclients", ToMany(ToMany, "Products.ZenModel.UBRRouter",
274 # "dhcpservers")),
275 )
276
277 # Screen action bindings (and tab definitions)
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 # { 'id' : 'perfConf'
325 # , 'name' : 'PerfConf'
326 # , 'action' : 'objTemplates'
327 # , 'permissions' : ("Change Device", )
328 # },
329 { 'id' : 'edit'
330 , 'name' : 'Edit'
331 , 'action' : 'editDevice'
332 , 'permissions' : ("Change Device",)
333 },
334 # { 'id' : 'management'
335 # , 'name' : 'Administration'
336 # , 'action' : 'deviceManagement'
337 # , 'permissions' : ("Change Device",)
338 # },
339 # { 'id' : 'custom'
340 # , 'name' : 'Custom'
341 # , 'action' : 'deviceCustomEdit'
342 # , 'permissions' : (ZEN_VIEW, )
343 # },
344 # { 'id' : 'config'
345 # , 'name' : 'zProperties'
346 # , 'action' : 'zPropertyEdit'
347 # , 'permissions' : (ZEN_VIEW,)
348 # },
349 # { 'id' : 'viewHistory'
350 # , 'name' : 'Modifications'
351 # , 'action' : 'viewHistory'
352 # , 'permissions' : (ZEN_VIEW, )
353 # },
354 # { 'id' : 'zProperties'
355 # , 'name' : 'zProperties'
356 # , 'action' : 'zPropertyEdit'
357 # , 'permissions' : ( ZEN_VIEW, )
358 # },
359 )
360 },
361 )
362
363 security = ClassSecurityInfo()
364
366 ManagedEntity.__init__(self, id)
367 os = OperatingSystem()
368 self._setObject(os.id, os)
369 hw = DeviceHW()
370 self._setObject(hw.id, hw)
371 #self.commandStatus = "Not Tested"
372 self._lastPollSnmpUpTime = ZenStatus(0)
373 self._snmpLastCollection = 0
374 self._lastChange = 0
375
376
378 """
379 DEPRECATED
380 """
381 import warnings
382 warnings.warn('Device.getRRDTemplate is deprecated',
383 DeprecationWarning)
384 return ManagedEntity.getRRDTemplate(self)
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 # This is an unfortunate hack. Called from the device templates
422 # page where we show multiple templates now. This only really
423 # works because getDataSourceOptions() returns the same values
424 # for every template. Ideally we would be able to pass some sort
425 # of context to the Add DataSource dialog that calls this method.
426 templates = self.getRRDTemplates()
427 if templates:
428 return templates[0].getDataSourceOptions()
429 return []
430
431 # security.declareProtected('Manage DMD', 'manage_resequenceRRDGraphs')
432 # def manage_resequenceRRDGraphs(self, templateId, seqmap=(), origseq=(), REQUEST=None):
433 # """Reorder the sequecne of the RRDGraphs.
434 # """
435 # template = self.getRRDTemplateByName(templateId)
436 # return template.manage_resequenceRRDGraphs(seqmap, origseq, REQUEST)
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
497 """
498 Apply a datamap passed as a list of dicts through XML-RPC.
499 """
500 adm = ApplyDataMap()
501 adm.applyDataMap(self, datamap, relname=relname,
502 compname=compname, modname=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
740
741
747
748
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 #if ipobj and not ipobj.device():
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')
857 """
858 Return the device performance server
859
860 @rtype: PerformanceMonitor
861 @permission: ZEN_VIEW
862 """
863 return self.perfServer()
864
865
866 security.declareProtected(ZEN_VIEW, 'getPerformanceServerName')
868 """
869 Return the device performance server name
870
871 @rtype: string
872 @permission: ZEN_VIEW
873 """
874 cr = self.perfServer()
875 if cr: return cr.getId()
876 return ''
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')
925 """
926 Set the manage IP, if IP is not passed perform DNS lookup.
927
928 @rtype: string
929 @permission: ZEN_ADMIN_DEVICE
930 """
931 if not ip:
932 try: ip = socket.gethostbyname(self.id)
933 except socket.error: ip = ""
934 self.manageIp = ip
935 self.index_object()
936 if REQUEST:
937 if ip: REQUEST['message'] = "Manage IP set"
938 else: REQUEST['message'] = "Not a valid IP"
939 return self.callZenScreen(REQUEST)
940 else:
941 return self.manageIp
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 #g.format = 'svg'
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 #g.format = 'svg'
1052 self.REQUEST.RESPONSE.setHeader('Content-Type', 'image/%s' % g.format)
1053 return g.render(withNetworks=True)
1054
1055 ####################################################################
1056 # Edit functions used to manage device relations and other attributes
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):
1088 """edit device relations and attributes"""
1089 self.hw.tag = tag
1090 self.hw.serialNumber = serialNumber
1091 for prop in ('zSnmpCommunity', 'zSnmpVer', 'zSnmpPort'):
1092 passedIn = locals()[prop]
1093 if passedIn and getattr(self, prop) != passedIn:
1094 self.setZenProperty(prop, passedIn)
1095
1096 self.rackSlot = rackSlot
1097 self.setProdState(productionState)
1098 self.setPriority(priority)
1099 self.comments = comments
1100
1101 if hwManufacturer and hwProductName:
1102 log.info("setting hardware manufacturer to %s productName to %s"
1103 % (hwManufacturer, hwProductName))
1104 self.hw.setProduct(hwProductName, hwManufacturer)
1105 else:
1106 self.hw.productClass.removeRelation()
1107
1108 if osManufacturer and osProductName:
1109 log.info("setting os manufacturer to %s productName to %s"
1110 % (osManufacturer, osProductName))
1111 self.os.setProduct(osProductName, osManufacturer)
1112 self.os.productClass().isOS = True
1113 else:
1114 self.os.productClass.removeRelation()
1115
1116 if locationPath:
1117 log.info("setting location to %s" % locationPath)
1118 self.setLocation(locationPath)
1119
1120 if groupPaths:
1121 log.info("setting group %s" % groupPaths)
1122 self.setGroups(groupPaths)
1123
1124 if systemPaths:
1125 log.info("setting system %s" % systemPaths)
1126 self.setSystems(systemPaths)
1127
1128 log.info("setting status monitor to %s" % statusMonitors)
1129 self.setStatusMonitors(statusMonitors)
1130
1131 log.info("setting performance monitor to %s" % performanceMonitor)
1132 self.setPerformanceMonitor(performanceMonitor)
1133
1134 self.setLastChange()
1135 self.index_object()
1136 if REQUEST:
1137 from Products.ZenUtils.Time import SaveMessage
1138 REQUEST['message'] = SaveMessage()
1139 return self.callZenScreen(REQUEST)
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
1156 """Return the prodstate as a string.
1157 """
1158 return self.convertProdState(self.productionState)
1159
1161 """Return the device priority as a string.
1162 """
1163 return self.convertPriority(self.priority)
1164
1166 """Return the pingStatus as a string
1167 """
1168 return self.convertStatus(self.getPingStatus())
1169
1171 """Return the snmpStatus as a string
1172 """
1173 return self.convertStatus(self.getSnmpStatus())
1174
1175 security.declareProtected(ZEN_CHANGE_DEVICE, 'setProdState')
1177 """Set a device's production state as an integer.
1178 """
1179 self.productionState = int(state)
1180 self.index_object()
1181 try:
1182 zem = self.dmd.ZenEventManager
1183 conn = zem.connect()
1184 try:
1185 curs = conn.cursor()
1186 curs.execute(
1187 "update status set prodState=%d where device='%s'" % (
1188 self.productionState, self.id))
1189 finally: zem.close(conn)
1190 except OperationalError:
1191 log.exception("failed to update events with new prodState")
1192 if REQUEST:
1193 REQUEST['message'] = "Failed to update events with new production state"
1194 return self.callZenScreen(REQUEST)
1195
1196 if REQUEST:
1197 REQUEST['message'] = "Production state set"
1198 return self.callZenScreen(REQUEST)
1199
1200 security.declareProtected(ZEN_CHANGE_DEVICE, 'setPriority')
1202 """ Set a device's priority as an integer.
1203 """
1204 self.priority = int(priority)
1205 try:
1206 zem = self.dmd.ZenEventManager
1207 conn = zem.connect()
1208 try:
1209 curs = conn.cursor()
1210 curs.execute("update status set DevicePriority=%d where device='%s'" % (
1211 self.priority, self.id))
1212 finally: zem.close(conn)
1213 except OperationalError:
1214 log.exception("failed to update events with new priority")
1215 if REQUEST:
1216 REQUEST['message'] = "Failed to update events with new priority"
1217 return self.callZenScreen(REQUEST)
1218
1219 if REQUEST:
1220 REQUEST['message'] = "Priority set"
1221 return self.callZenScreen(REQUEST)
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')
1241 - def addManufacturer(self, newHWManufacturerName=None,
1242 newSWManufacturerName=None, REQUEST=None):
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')
1276 """set the productName of this device"""
1277 if newOSProductName:
1278 self.getDmdRoot("Manufacturers").createSoftwareProduct(
1279 newOSProductName, osManufacturer, isOS=True)
1280 if REQUEST:
1281 if newOSProductName:
1282 REQUEST['message'] = "OS Product set"
1283 REQUEST['osProductName'] = newOSProductName
1284 else:
1285 REQUEST['message'] = "OS Product was not set"
1286 return self.callZenScreen(REQUEST)
1287
1288
1289 security.declareProtected(ZEN_CHANGE_DEVICE, 'setLocation')
1291 """set the location of a device within a generic location path"""
1292 if not locationPath:
1293 self.location.removeRelation()
1294 else:
1295 locobj = self.getDmdRoot("Locations").createOrganizer(locationPath)
1296 self.addRelation("location", locobj)
1297 self.setAdminLocalRoles()
1298
1299
1301 """Add a new location and relate it to this device"""
1302 locobj = self.getDmdRoot("Locations").createOrganizer(newLocationPath)
1303 if REQUEST:
1304 REQUEST['locationPath'] = newLocationPath
1305 REQUEST['message'] = "Added Location %s at time:" % newLocationPath
1306 return self.callZenScreen(REQUEST)
1307
1308
1309 security.declareProtected(ZEN_CHANGE_DEVICE, 'setPerformanceMonitor')
1310 - def setPerformanceMonitor(self, performanceMonitor,
1311 newPerformanceMonitor=None, REQUEST=None):
1312 """set the performance monitor for this device if newPerformanceMonitor
1313 is passed in create it"""
1314 if newPerformanceMonitor:
1315 #self.dmd.RenderServer.moveRRDFiles(self.id,
1316 # newPerformanceMonitor, performanceMonitor, REQUEST)
1317 performanceMonitor = newPerformanceMonitor
1318
1319 obj = self.getDmdRoot("Monitors").getPerformanceMonitor(
1320 performanceMonitor)
1321 self.addRelation("perfServer", obj)
1322 self.setLastChange()
1323
1324 if REQUEST:
1325 REQUEST['message'] = "Set Performance %s at time:" % performanceMonitor
1326 return self.callZenScreen(REQUEST)
1327
1328
1329 security.declareProtected(ZEN_CHANGE_DEVICE, 'setStatusMonitors')
1331 """Set Status Monitor by list statusMonitors
1332 """
1333 objGetter = self.getDmdRoot("Monitors").getStatusMonitor
1334 self._setRelations("monitors", objGetter, statusMonitors)
1335 self.setLastChange()
1336
1337
1338 security.declareProtected(ZEN_CHANGE_DEVICE, 'addStatusMonitor')
1340 """add new status monitor to the database and this device"""
1341 if newStatusMonitor:
1342 mon = self.getDmdRoot("Monitors").getStatusMonitor(newStatusMonitor)
1343 self.addRelation("monitors", mon)
1344 self.setLastChange()
1345 if REQUEST:
1346 if newStatusMonitor:
1347 REQUEST['message'] = "Added Monitor %s at time:" % \
1348 newStatusMonitor
1349 return self.callZenScreen(REQUEST)
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')
1361 """add a device group to the database and this device"""
1362 group = self.getDmdRoot("Groups").createOrganizer(newDeviceGroupPath)
1363 self.addRelation("groups", group)
1364 if REQUEST:
1365 REQUEST['message'] = "Added Group %s at time:" % newDeviceGroupPath
1366 return self.callZenScreen(REQUEST)
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')
1378 """add a systems to this device using its system path"""
1379 sys = self.getDmdRoot("Systems").createOrganizer(newSystemPath)
1380 self.addRelation("systems", sys)
1381 if REQUEST:
1382 REQUEST['message'] = "System added"
1383 return self.callZenScreen(REQUEST)
1384
1385
1386 security.declareProtected(ZEN_CHANGE_DEVICE, 'setTerminalServer')
1388 termserver = self.findDevice(termservername)
1389 if termserver:
1390 self.addRelation('termserver', termserver)
1391
1392
1394 """set related objects to this device"""
1395 if type(relPaths) != type([]) and type(relPaths) != type(()):
1396 relPaths = [relPaths,]
1397 relPaths = filter(lambda x: x.strip(), relPaths)
1398 rel = getattr(self, relName, None)
1399 if not rel:
1400 raise AttributeError, "Relation %s not found" % relName
1401 curRelIds = {}
1402 for value in rel.objectValuesAll():
1403 curRelIds[value.getOrganizerName()] = value
1404 for path in relPaths:
1405 if not curRelIds.has_key(path):
1406 robj = objGetter(path)
1407 self.addRelation(relName, robj)
1408 else:
1409 del curRelIds[path]
1410 for obj in curRelIds.values():
1411 self.removeRelation(relName, obj)
1412 self.setAdminLocalRoles()
1413
1414
1416 'Return the expanded zComment property'
1417 from Products.ZenUtils.ZenTales import talesEval
1418 try:
1419 return talesEval('string:' + self.zLinks, self)
1420 except Exception, ex:
1421 import cgi
1422 return "<i class='errortitle'>%s</i>" % cgi.escape(str(ex))
1423
1424 ####################################################################
1425 # Private getter functions that implement DeviceResultInt
1426 ####################################################################
1427
1428 security.declareProtected(ZEN_VIEW, 'device')
1432
1433
1434 ####################################################################
1435 # Status Management Functions used by status monitors
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
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
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 # Management Functions
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 # if not setlog:
1539 # for c in [c for c in sc.finished if c.timeout < time.time()]:
1540 # from Products.DataCollector.Exceptions import DataCollectorError
1541 # raise DataCollectorError("Device %s timed out" % self.id)
1542
1543
1544 security.declareProtected(ZEN_ADMIN_DEVICE, 'deleteDevice')
1546 """Delete device from the DMD"""
1547 parent = self.getPrimaryParent()
1548 self.getEventManager().manage_deleteHeartbeat(self.getId())
1549 self.getEventManager().manage_deleteAllEvents(self.getId())
1550 parent._delObject(self.getId())
1551 if REQUEST:
1552 REQUEST['message'] = "Device deleted"
1553 if parent.getId()=='devices':
1554 parent = parent.getPrimaryParent()
1555 REQUEST['RESPONSE'].redirect(parent.absolute_url() +
1556 "/deviceOrganizerStatus")
1557
1558 security.declareProtected(ZEN_MANAGE_DEVICE, 'manage_deleteHeartbeat')
1560 """Delete this device's heartbeats."""
1561 self.getEventManager().manage_deleteHeartbeat(self.getId())
1562 if REQUEST:
1563 REQUEST['message'] = "Cleared heartbeat events for %s" % self.id
1564 return self.callZenScreen(REQUEST)
1565
1566
1567 security.declareProtected(ZEN_ADMIN_DEVICE, 'renameDevice')
1569 """Rename device from the DMD"""
1570 if newId:
1571 if not isinstance(newId, unicode):
1572 newId = self.prepId(newId)
1573 parent = self.getPrimaryParent()
1574 parent.manage_renameObject(self.getId(), newId)
1575 self.setLastChange()
1576 if REQUEST:
1577 REQUEST['message'] = "Device %s renamed to %s" % (self.getId(), newId)
1578 REQUEST['RESPONSE'].redirect("%s/%s" % (parent.absolute_url(), newId))
1579
1580
1582 """
1583 Device only propagates afterAdd if it is the added object.
1584 """
1585 super(Device,self).manage_afterAdd(item, container)
1586 self.index_object()
1587
1588
1590 """Not really sure when this is called."""
1591 super(Device,self).manage_afterClone(item)
1592 self.index_object()
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
1605 "Read current RRD values for all of a device's components"
1606 paths = self.getRRDPaths()[:]
1607 #FIXME need better way to scope and need to get DataSources
1608 # from RRDTemplates
1609 #for c in self.os.interfaces(): paths.extend(c.getRRDPaths())
1610 for c in self.os.filesystems(): paths.extend(c.getRRDPaths())
1611 #for c in self.hw.harddisks(): paths.extend(c.getRRDPaths())
1612 objpaq = self.primaryAq()
1613 perfServer = objpaq.getPerformanceServer()
1614 if perfServer:
1615 try:
1616 result = perfServer.currentValues(paths)
1617 if result:
1618 RRDView.updateCache(zip(paths, result))
1619 except Exception:
1620 log.exception("Unable to cache values for %s", self.id);
1621
1622
1624 """ Called by Commandable.doCommand() to ascertain objects on which
1625 a UserCommand should be executed.
1626 """
1627 return [self]
1628
1630 environ = Commandable.getUserCommandEnvironment(self)
1631 context = self.primaryAq()
1632 environ.update({'dev': context, 'device': context,})
1633 return environ
1634
1636 return self.getPrimaryUrlPath() + '/deviceManagement'
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
1654 """ returns data ready for serialization
1655 """
1656 id = '<a class="tablevalues" href="%s">%s</a>' % (
1657 self.getDeviceUrl(), self.getId())
1658 ip = self.getDeviceIp()
1659 path = '<a href="/zport/dmd/Devices%s">%s</a>' % (
1660 self.getDeviceClassPath(),
1661 self.getDeviceClassPath())
1662 prod = self.getProdState()
1663 evsum = self.getHTMLEventSummary()
1664 imgbase = '<img border="0" src="locked-%s-icon.png"/>'
1665 locks = ''
1666 if self.isLockedFromUpdates(): locks += imgbase % 'update'
1667 if self.isLockedFromDeletion(): locks += imgbase % 'delete'
1668 if self.sendEventWhenBlocked(): locks += imgbase % 'sendevent'
1669 return [id, ip, path, prod, evsum, locks, self.getId()]
1670
1672 """Add export of our child objects.
1673 """
1674 map(lambda o: o.exportXml(ofile, ignorerels), (self.hw, self.os))
1675
1677 if propname == 'zCollectorPlugins':
1678 from Products.DataCollector.Plugins import loadPlugins
1679 names = loadPlugins(self.dmd).keys()
1680 names.sort()
1681 return names
1682 return ManagedEntity.zenPropertyOptions(self, propname)
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')
1699 "Deletes the local zProperty, zDeviceTemplates"
1700 for id in self.zDeviceTemplates:
1701 self.removeLocalRRDTemplate(id)
1702 return self.deleteZenProperty('zDeviceTemplates', REQUEST)
1703
1704 security.declareProtected(ZEN_EDIT_LOCAL_TEMPLATES, 'addLocalTemplate')
1706 "Create a local template on a device"
1707 from Products.ZenModel.RRDTemplate import manage_addRRDTemplate
1708 manage_addRRDTemplate(self, id)
1709 if id not in self.zDeviceTemplates:
1710 self.bindTemplates(self.zDeviceTemplates+[id])
1711 if REQUEST:
1712 REQUEST['message'] = 'Added template %s to %s' % (id, self.id)
1713 return self.callZenScreen(REQUEST)
1714
1716 "Returns all available templates for this device"
1717 # All templates defined on this device are available
1718 templates = self.objectValues('RRDTemplate')
1719 # Any templates available to the class that aren't overridden locally
1720 # are also available
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')
1730 """ Returns all Links on this Device's interfaces """
1731 if OSI_layer=='3':
1732 from Products.ZenUtils.NetworkTree import getDeviceNetworkLinks
1733 for link in getDeviceNetworkLinks(self):
1734 yield link
1735 else:
1736 for iface in self.os.interfaces.objectValuesGen():
1737 for link in iface.links.objectValuesGen():
1738 yield link
1739
1740 security.declareProtected(ZEN_VIEW, 'getXMLEdges')
1742 """ Gets XML """
1743 if not start: start=self.id
1744 edges = NetworkTree.get_edges(self, depth,
1745 withIcons=True, filter=filter)
1746 return edgesToXML(edges, 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
1772 """ Gets datatable-ready string of components and summaries """
1773 return self.dmd.ZenEventManager.getDeviceComponentEventSummary(self)
1774
1775
1776 InitializeClass(Device)
1777
| Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0beta1 on Thu Oct 25 16:28:46 2007 | http://epydoc.sourceforge.net |