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

Source Code for Module Products.ZenWidgets.browser.quickstart.views

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