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 desc, ptcl = t
76
77 if not ptcl or not desc: continue
78
79 if ptcl not in ALLOWED_PROTOCOLS: continue
80 types.append((org.getOrganizerName(), desc, ptcl))
81 return types
82
83 @json
85 """
86 Build an object for populating an Ext ComboBox representing "device
87 types," which should exactly correspond to DeviceClasses in the system.
88
89 This method iterates over a predetermined list of types we might want
90 to see and checks each DeviceClass for existence (i.e., is the
91 appropriate ZenPack installed?).
92 """
93
94 types = {'win':[], 'ssh':[], 'snmp':[]}
95 for t in self._assemble_types_list():
96 if t[2]=='WMI': types['win'].append(t)
97 elif t[2]=='SNMP': types['snmp'].append(t)
98 elif t[2]=='SSH': types['ssh'].append(t)
99
100 def dev_class_exists(path):
101 """
102 Return a boolean indicating whether the specified DeviceClass
103 exists.
104 """
105 try:
106 self.context.unrestrictedTraverse(
107 '/zport/dmd/Devices' + path)
108 except AttributeError:
109 return False
110 else:
111 return True
112
113 def format_type(credtype, classpath, description, protocol):
114 """
115 Turn information representing a device class into a dictionary of
116 the format our ComboBox expects.
117 """
118 value = '%s_%s' % (classpath, credtype)
119 return dict(value=value,
120 shortdesc="%s (%s)" % (description, protocol),
121 description=description, protocol=protocol)
122
123
124 response = []
125 for credtype, devtypes in types.iteritems():
126 for devtype in devtypes:
127
128 if dev_class_exists(devtype[0]):
129
130 response.append(format_type(credtype, *devtype))
131
132
133 response.sort(key=lambda x:x['description'])
134
135
136
137 return dict(types=response)
138
139
140 @Ext.form_action
142 response = Ext.FormResponse()
143 submitted = self.request.form.get('network', [])
144 if isinstance(submitted, basestring):
145 submitted = [submitted]
146 zProperties = {
147 'zCommandUsername': self.request.form.get('sshusername'),
148 'zCommandPassword': self.request.form.get('sshpass'),
149 'zWinUser': self.request.form.get('winusername'),
150 'zWinPassword': self.request.form.get('winpass'),
151 'zSnmpCommunities': self.request.form.get('snmpcommunities').splitlines()
152 }
153
154 nets = []
155 ranges = []
156 for row in submitted:
157 if _is_network(row): nets.append(row)
158 elif _is_range(row): ranges.append(row)
159 if not nets and not ranges:
160 response.error('network',
161 'You must enter at least one network or IP range.')
162 if nets:
163 for net in nets:
164
165
166 _n = self.context.dmd.Networks.createNet(net)
167 try:
168 self.context.JobManager.addJob(
169 AutoDiscoveryJob,
170 nets=nets,
171 zProperties=zProperties)
172 except:
173 response.error('network', 'There was an error scheduling this '
174 'job. Please check your installation and try '
175 'again.')
176 else:
177 IMessageSender(self.context).sendToUser(
178 'Autodiscovery Task Created',
179 'Discovery of the following networks is in progress: %s' % (
180 ', '.join(ranges))
181 )
182 if ranges:
183
184
185 try:
186 self.context.JobManager.addJob(
187 AutoDiscoveryJob,
188 ranges=ranges,
189 zProperties=zProperties)
190 except:
191 response.error('network', 'There was an error scheduling this '
192 'job. Please check your installation and try '
193 'again.')
194 else:
195 IMessageSender(self.context).sendToUser(
196 'Autodiscovery Task Created',
197 'Discovery of the following IP ranges is in progress: %s' % (
198 ', '.join(ranges))
199 )
200
201
202 response.redirect('/zport/dmd')
203 return response
204
205
206 @Ext.form_action
208
209 response = Ext.FormResponse()
210 devs = filter(lambda x:x.startswith('device_'),
211 self.request.form.keys())
212
213 devnames = filter(lambda x:bool(self.request.form.get(x)), devs)
214 if not devnames:
215 response.error('device_0',
216 'You must enter at least one hostname/IP.')
217 return response
218
219 for k in devs:
220
221 if not self.request.form.get(k): continue
222 idx = k.split('_')[1]
223 devclass, type_ = self.request.form.get(
224 'deviceclass_%s' % idx).split('_')
225
226 if type_=='ssh':
227 zProps = {
228 'zCommandUsername': self.request.form.get('sshuser_%s' % idx),
229 'zCommandPassword': self.request.form.get(
230 'sshpass_%s' % idx),
231 }
232 elif type_=='win':
233 zProps = {
234 'zWinUser': self.request.form.get('winuser_%s' % idx),
235 'zWinPassword': self.request.form.get('winpass_%s' % idx),
236 }
237 elif type_=='snmp':
238 zProps = {
239 'zSnmpCommunities': self.request.form.get(
240 'snmpcomm_%s' % idx
241 ).splitlines()
242 }
243 perfConf = self.context.Monitors.getPerformanceMonitor('localhost')
244 perfConf.addDeviceCreationJob(deviceName=self.request.form.get(k),
245 devicePath=devclass, zProperties=zProps, discoverProto='auto')
246 devnames = [self.request.form.get(dev) for dev in devs]
247 IMessageSender(self.context).sendToUser(
248 'Devices Added',
249 'Modeling of the following devices has been scheduled: %s' % (
250 ', '.join(filter(None, devnames))
251 )
252 )
253 response.redirect('/zport/dmd')
254 return response
255