1
2
3
4
5
6
7
8
9
10
11
12
13
14 __doc__="""ZDeviceLoader.py
15
16 load devices from a GUI screen in the ZMI
17
18 """
19
20 import socket
21 from logging import StreamHandler, Formatter, getLogger
22 log = getLogger("zen.DeviceLoader")
23
24 from ipaddr import IPAddress
25
26 import transaction
27 from ZODB.transact import transact
28 from zope.interface import implements
29 from AccessControl import ClassSecurityInfo
30 from AccessControl import Permissions as permissions
31
32 from OFS.SimpleItem import SimpleItem
33
34 from Products.ZenUtils.Utils import isXmlRpc, setupLoggingHeader
35 from Products.ZenUtils.Utils import binPath, clearWebLoggingStream
36 from Products.ZenUtils.IpUtil import getHostByName, ipwrap
37
38 from Products.ZenUtils.Exceptions import ZentinelException
39 from Products.ZenModel.Exceptions import DeviceExistsError, NoSnmp
40 from Products.ZenModel.Device import manage_createDevice
41 from Products.ZenWidgets import messaging
42 from Products.Jobber.interfaces import IJobStatus
43 from Products.Jobber.jobs import ShellCommandJob
44 from Products.Jobber.status import SUCCESS, FAILURE
45 from ZenModelItem import ZenModelItem
46 from zExceptions import BadRequest
47 from Products.ZenModel.interfaces import IDeviceLoader
48 from Products.ZenEvents.Event import Event
60
62 implements(IDeviceLoader)
63
64 context = None
65 request = None
66 deviceobj = None
67
70
71 - def run_zendisc(self, deviceName, devicePath, performanceMonitor):
72 """
73 Various ways of doing this should be implemented in subclasses.
74 """
75 raise NotImplementedError
76
92
93 - def load_device(self, deviceName, devicePath='/Discovered',
94 discoverProto='snmp', performanceMonitor='localhost',
95 manageIp="", zProperties=None, deviceProperties=None):
96 """
97 Load a single device into the database.
98 """
99
100 try:
101 if zProperties is None:
102 zProperties = {}
103 if deviceProperties is None:
104 deviceProperties = {}
105
106
107 deviceName = deviceName.replace(' ', '')
108 manageIp = manageIp.replace(' ', '')
109
110
111 try:
112 ipv6addr = IPAddress(deviceName)
113 manageIp = deviceName
114 deviceName = ipwrap(deviceName)
115 deviceProperties.setdefault('title', manageIp)
116 except ValueError:
117 pass
118
119
120
121 if discoverProto=='none':
122 if not manageIp:
123 try:
124 manageIp = getHostByName(deviceName)
125 except socket.error:
126 pass
127
128
129
130 for key in 'zSnmpCommunity', 'zSnmpPort', 'zSnmpVer':
131 if key in zProperties:
132 deviceProperties[key] = zProperties.pop(key)
133
134
135 self.deviceobj = manage_createDevice(self.context, deviceName,
136 devicePath,
137 performanceMonitor=performanceMonitor,
138 manageIp=manageIp,
139 zProperties=zProperties,
140 **deviceProperties)
141
142
143
144 self.deviceobj._temp_device = True
145
146
147 if discoverProto=='none':
148 return self.deviceobj
149
150
151 self.run_zendisc(deviceName, devicePath, performanceMonitor)
152
153 finally:
154
155 self.cleanup()
156
157 return self.deviceobj
158
161 implements(IDeviceLoader)
162
163 - def run_zendisc(self, deviceName, devicePath, performanceMonitor):
164 """
165 In this subclass, just commit to database,
166 so everybody can find the new device
167 """
168 pass
169
171 """
172 Delegate cleanup to the Job itself.
173 """
174 pass
175
178 - def __init__(self, jobid, deviceName, devicePath="/Discovered", tag="",
179 serialNumber="", rackSlot=0, productionState=1000,
180 comments="", hwManufacturer="", hwProductName="",
181 osManufacturer="", osProductName="", locationPath="",
182 groupPaths=[], systemPaths=[], performanceMonitor="localhost",
183 discoverProto="snmp", priority=3, manageIp="",
184 zProperties=None, title=None, zendiscCmd=[]):
185
186
187 self.deviceName = deviceName
188 self.devicePath = devicePath
189 self.performanceMonitor = performanceMonitor
190 self.discoverProto = discoverProto
191 self.manageIp = manageIp.replace(' ', '')
192
193
194 self.zProperties = zProperties
195 self.deviceProps = dict(tag=tag,
196 serialNumber=serialNumber,
197 rackSlot=rackSlot,
198 productionState=productionState,
199 comments=comments,
200 hwManufacturer=hwManufacturer,
201 hwProductName = hwProductName,
202 osManufacturer = osManufacturer,
203 osProductName = osProductName,
204 locationPath = locationPath,
205 groupPaths = groupPaths,
206 systemPaths = systemPaths,
207 priority = priority,
208 title= title)
209
210 zendiscCmd.extend(['--job', jobid])
211 super(DeviceCreationJob, self).__init__(jobid, zendiscCmd)
212
213
215
216 self._v_loader = JobDeviceLoader(self)
217
218 @transact
219 def createDevice(loader, zProperties):
220
221
222 loader.getStatus().setZProperties(**zProperties)
223
224 loader._v_loader.load_device(loader.deviceName, loader.devicePath,
225 loader.discoverProto,
226 loader.performanceMonitor, loader.manageIp,
227 loader.zProperties, loader.deviceProps)
228
229
230 try:
231 createDevice(self, self.zProperties)
232 except Exception, e:
233 log.exception("Encountered error. Rolling back initial device add.")
234 transaction.abort()
235 job_log = self.getStatus().getLog()
236 job_log.write(str(e.args[0]))
237 job_log.finish()
238 self.finished(FAILURE)
239 transaction.commit()
240 else:
241 if self.discoverProto != 'none':
242 super(DeviceCreationJob, self).run(r)
243 else:
244 job_log = self.getStatus().getLog()
245 job_log.write("device added without modeling")
246 job_log.finish()
247 self.finished(SUCCESS)
248
260
261 -class WeblogDeviceLoader(BaseDeviceLoader):
262 - def __init__(self, context, request):
265
266 - def run_zendisc(self, deviceName, devicePath, performanceMonitor):
267
268 transaction.commit()
269 collector = self.deviceobj.getPerformanceServer()
270 collector._executeZenDiscCommand(deviceName, devicePath,
271 performanceMonitor,
272 REQUEST=self.request)
273
276 """Load devices into the DMD database"""
277
278 portal_type = meta_type = 'DeviceLoader'
279
280 manage_options = ((
281 {'label':'ManualDeviceLoader', 'action':'manualDeviceLoader'},
282 ) + SimpleItem.manage_options)
283
284
285 security = ClassSecurityInfo()
286
287 factory_type_information = (
288 {
289 'immediate_view' : 'addDevice',
290 'actions' :
291 (
292 { 'id' : 'status'
293 , 'name' : 'Status'
294 , 'action' : 'addDevice'
295 , 'permissions' : (
296 permissions.view, )
297 },
298 )
299 },
300 )
301
304
305
306 - def loadDevice(self, deviceName, devicePath="/Discovered",
307 tag="", serialNumber="",
308 zSnmpCommunity="", zSnmpPort=161, zSnmpVer=None,
309 rackSlot=0, productionState=1000, comments="",
310 hwManufacturer="", hwProductName="",
311 osManufacturer="", osProductName="",
312 locationPath="", groupPaths=[], systemPaths=[],
313 performanceMonitor="localhost",
314 discoverProto="snmp",priority=3,REQUEST=None):
315 """
316 Load a device into the database connecting its major relations
317 and collecting its configuration.
318 """
319 device = None
320 if not deviceName: return self.callZenScreen(REQUEST)
321 xmlrpc = isXmlRpc(REQUEST)
322 if REQUEST and not xmlrpc:
323 handler = setupLoggingHeader(self, REQUEST)
324
325 loader = WeblogDeviceLoader(self, REQUEST)
326
327 try:
328 device = loader.load_device(deviceName, devicePath, discoverProto,
329 performanceMonitor,
330 zProperties=dict(
331 zSnmpCommunity=zSnmpCommunity,
332 zSnmpPort=zSnmpPort,
333 zSnmpVer=zSnmpVer
334 ),
335 deviceProperties=dict(
336 tag=tag,
337 serialNumber=serialNumber,
338 rackSlot=rackSlot,
339 productionState=productionState,
340 comments=comments,
341 hwManufacturer=hwManufacturer,
342 hwProductName=hwProductName,
343 osManufacturer=osManufacturer,
344 osProductName=osProductName,
345 locationPath=locationPath,
346 groupPaths=groupPaths,
347 systemPaths=systemPaths,
348 priority=priority
349 ))
350 except (SystemExit, KeyboardInterrupt):
351 raise
352 except ZentinelException, e:
353 log.info(e)
354 if xmlrpc: return 1
355 except DeviceExistsError, e:
356 log.info(e)
357 if xmlrpc: return 2
358 except NoSnmp, e:
359 log.info(e)
360 if xmlrpc: return 3
361 except Exception, e:
362 log.exception(e)
363 log.exception('load of device %s failed' % deviceName)
364 transaction.abort()
365 if device is None:
366 log.error("Unable to add the device %s" % deviceName)
367 else:
368 log.info("Device %s loaded!" % deviceName)
369
370 if REQUEST and not xmlrpc:
371 self.loaderFooter(device, REQUEST.RESPONSE)
372 clearWebLoggingStream(handler)
373 if xmlrpc: return 0
374
375 - def addManufacturer(self, newHWManufacturerName=None,
376 newSWManufacturerName=None, REQUEST=None):
398
399
400 security.declareProtected('Change Device', 'setHWProduct')
401 - def setHWProduct(self, newHWProductName, hwManufacturer, REQUEST=None):
416
417
418 security.declareProtected('Change Device', 'setOSProduct')
419 - def setOSProduct(self, newOSProductName, osManufacturer, REQUEST=None):
434
435
436 security.declareProtected('Change Device', 'addLocation')
454
455
456 security.declareProtected('Change Device', 'addSystem')
457 - def addSystem(self, newSystemPath, REQUEST=None):
476
477
478 security.declareProtected('Change Device', 'addDeviceGroup')
498
499
500 security.declareProtected('Change Device', 'setPerformanceMonitor')
517
518
520 """setup logging package to send to browser"""
521 root = getLogger()
522 self._v_handler = StreamHandler(response)
523 fmt = Formatter("""<tr class="tablevalues">
524 <td>%(asctime)s</td><td>%(levelname)s</td>
525 <td>%(name)s</td><td>%(message)s</td></tr>
526 """, "%Y-%m-%d %H:%M:%S")
527 self._v_handler.setFormatter(fmt)
528 root.addHandler(self._v_handler)
529 root.setLevel(10)
530
531
533 alog = getLogger()
534 if getattr(self, "_v_handler", False):
535 alog.removeHandler(self._v_handler)
536
537
546