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