Package ZenWidgets :: Package browser :: Package quickstart :: Module views
[hide private]
[frames] | no frames]

Source Code for Module ZenWidgets.browser.quickstart.views

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