1
2
3
4
5
6
7
8
9
10
11
12
13
14 import re
15 from Acquisition import aq_base
16 from Products.Five.browser import BrowserView
17 from Products.Five.browser.pagetemplatefile import ZopeTwoPageTemplateFile
18 from Products.ZenModel.IpNetwork import AutoDiscoveryJob
19 from Products.ZenWidgets.messaging import IMessageSender
20 from Products.ZenUtils import Ext
21 from Products.ZenUtils.jsonutils import json
22
23 _is_network = lambda x: bool(re.compile(r'^(\d+\.){3}\d+\/\d+$').search(x))
24 _is_range = lambda x: bool(re.compile(r'^(\d+\.){3}\d+\-\d+$').search(x))
27 """
28 Standard macros for the quickstart.
29 """
30 template = ZopeTwoPageTemplateFile('templates/quickstart_macros.pt')
31
34
37 """
38 Displays the steps the user will soon be completing. The anticipation!
39 """
40 __call__ = ZopeTwoPageTemplateFile('templates/outline.pt')
41
44 """
45 Creates the initial user and sets the admin password.
46 """
47 __call__ = ZopeTwoPageTemplateFile('templates/createuser.pt')
48
51 """
52 Specify devices to be added.
53 """
54 @json
56 """
57 Format the value of Devices.Discovered.zSnmpCommunities for a textarea
58 """
59 devclass = self.context.dmd.Devices.Discovered.primaryAq()
60 return '\n'.join(devclass.zSnmpCommunities)
61
63 """
64 Walks all device classes building a list of description/protocol pairs.
65 """
66 ALLOWED_PROTOCOLS = ('SSH', 'SNMP', 'WMI')
67 devclass = self.context.dmd.Devices
68 orgs = devclass.getSubOrganizers()
69 types = []
70 for org in orgs:
71
72 if not hasattr(aq_base(org), 'devtypes') or not org.devtypes:
73 continue
74 for t in org.devtypes:
75 try:
76 desc, ptcl = t
77 except ValueError:
78 continue
79
80
81 if not ptcl or not desc:
82 continue
83
84
85 if ptcl not in ALLOWED_PROTOCOLS: continue
86 types.append((org.getOrganizerName(), desc, ptcl))
87 return types
88
89 @json
91 """
92 Build an object for populating an Ext ComboBox representing "device
93 types," which should exactly correspond to DeviceClasses in the system.
94
95 This method iterates over a predetermined list of types we might want
96 to see and checks each DeviceClass for existence (i.e., is the
97 appropriate ZenPack installed?).
98 """
99
100 types = {'win':[], 'ssh':[], 'snmp':[]}
101 for t in self._assemble_types_list():
102 if t[2]=='WMI': types['win'].append(t)
103 elif t[2]=='SNMP': types['snmp'].append(t)
104 elif t[2]=='SSH': types['ssh'].append(t)
105
106 def dev_class_exists(path):
107 """
108 Return a boolean indicating whether the specified DeviceClass
109 exists.
110 """
111 try:
112 self.context.unrestrictedTraverse(
113 '/zport/dmd/Devices' + path)
114 except AttributeError:
115 return False
116 else:
117 return True
118
119 def format_type(credtype, classpath, description, protocol):
120 """
121 Turn information representing a device class into a dictionary of
122 the format our ComboBox expects.
123 """
124 value = '%s_%s' % (classpath, credtype)
125 return dict(value=value,
126 shortdesc="%s (%s)" % (description, protocol),
127 description=description, protocol=protocol)
128
129
130 response = []
131 for credtype, devtypes in types.iteritems():
132 for devtype in devtypes:
133
134 if dev_class_exists(devtype[0]):
135
136 response.append(format_type(credtype, *devtype))
137
138
139 response.sort(key=lambda x:x['description'])
140
141
142
143 return dict(types=response)
144
145
146 @Ext.form_action
148 response = Ext.FormResponse()
149 submitted = self.request.form.get('network', [])
150 if isinstance(submitted, basestring):
151 submitted = [submitted]
152 zProperties = {
153 'zCommandUsername': self.request.form.get('sshusername'),
154 'zCommandPassword': self.request.form.get('sshpass'),
155 'zWinUser': self.request.form.get('winusername'),
156 'zWinPassword': self.request.form.get('winpass'),
157 'zSnmpCommunities': self.request.form.get('snmpcommunities').splitlines()
158 }
159
160 nets = []
161 ranges = []
162 for row in submitted:
163 if _is_network(row): nets.append(row)
164 elif _is_range(row): ranges.append(row)
165 if not nets and not ranges:
166 response.error('network',
167 'You must enter at least one network or IP range.')
168 if nets:
169 for net in nets:
170
171
172 _n = self.context.dmd.Networks.createNet(net)
173 try:
174 self.context.JobManager.addJob(
175 AutoDiscoveryJob,
176 nets=nets,
177 zProperties=zProperties)
178 except:
179 response.error('network', 'There was an error scheduling this '
180 'job. Please check your installation and try '
181 'again.')
182 else:
183 IMessageSender(self.context).sendToUser(
184 'Autodiscovery Task Created',
185 'Discovery of the following networks is in progress: %s' % (
186 ', '.join(ranges))
187 )
188 if ranges:
189
190
191 try:
192 self.context.JobManager.addJob(
193 AutoDiscoveryJob,
194 ranges=ranges,
195 zProperties=zProperties)
196 except:
197 response.error('network', 'There was an error scheduling this '
198 'job. Please check your installation and try '
199 'again.')
200 else:
201 IMessageSender(self.context).sendToUser(
202 'Autodiscovery Task Created',
203 'Discovery of the following IP ranges is in progress: %s' % (
204 ', '.join(ranges))
205 )
206
207
208 response.redirect('/zport/dmd')
209 return response
210
211
212 @Ext.form_action
214
215 response = Ext.FormResponse()
216 devs = filter(lambda x:x.startswith('device_'),
217 self.request.form.keys())
218
219 devnames = filter(lambda x:bool(self.request.form.get(x)), devs)
220 if not devnames:
221 response.error('device_0',
222 'You must enter at least one hostname/IP.')
223 return response
224
225 for k in devs:
226
227 if not self.request.form.get(k): continue
228 idx = k.split('_')[1]
229 devclass, type_ = self.request.form.get(
230 'deviceclass_%s' % idx).split('_')
231
232 if type_=='ssh':
233 zProps = {
234 'zCommandUsername': self.request.form.get('sshuser_%s' % idx),
235 'zCommandPassword': self.request.form.get(
236 'sshpass_%s' % idx),
237 }
238 elif type_=='win':
239 zProps = {
240 'zWinUser': self.request.form.get('winuser_%s' % idx),
241 'zWinPassword': self.request.form.get('winpass_%s' % idx),
242 }
243 elif type_=='snmp':
244 zProps = {
245 'zSnmpCommunities': self.request.form.get(
246 'snmpcomm_%s' % idx
247 ).splitlines()
248 }
249 perfConf = self.context.Monitors.getPerformanceMonitor('localhost')
250 perfConf.addDeviceCreationJob(deviceName=self.request.form.get(k),
251 devicePath=devclass, zProperties=zProps, discoverProto='auto')
252 devnames = [self.request.form.get(dev) for dev in devs]
253 IMessageSender(self.context).sendToUser(
254 'Devices Added',
255 'Modeling of the following devices has been scheduled: %s' % (
256 ', '.join(filter(None, devnames))
257 )
258 )
259 response.redirect('/zport/dmd')
260 return response
261