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