Package Products :: Package ZenRelations :: Module ExportDevices |
[hide private]
[frames] | no frames]

# Source Code for Module Products.ZenRelations.ExportDevices

      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  __doc__= """ExportDevices
     15  Export devices from /zport/dmd/Devices inside the Zope database
     16  """
     17
     18  import sys
     19  from xml.dom.minidom import parseString
     20  import StringIO
     21  import re
     22  import datetime
     23
     24  import Globals
     25
     26  from Products.ZenUtils.ZCmdBase import ZCmdBase
     27
     28  # Blank line regular expression
     29  _newlines = re.compile('\n[\t \r]*\n', re.M)
     30
     31 -class ExportDevices(ZCmdBase):
     32      """
     33      Wrapper class around exportXml() to create XML exports of devices.
     34      """
     35
     36 -    def __init__(self):
     37          """
     38          Initializer that creates an output file, or if nothing is specified
     39          with the command-line option --outfile, sends to stdout.
     40          """
     41
     42          ZCmdBase.__init__(self)
     43          if not self.options.outfile:
     44              self.outfile = sys.stdout
     45
     46          else:
     47              self.outfile = open(self.options.outfile, 'w')
     48
     49
     50 -    def buildOptions(self):
     51          """
     52          Command-line options setup
     53          """
     54
     55          ZCmdBase.buildOptions(self)
     56          self.parser.add_option('-o', '--outfile',
     57                      dest="outfile",
     58                      help= "Output file for exporting XML objects. Default is stdout" )
     59
     60          self.parser.add_option('--ignore', action="append",
     61                      dest="ignorerels", default=[],
     62                      help="Relations that should be ignored.  Every relation to" + \
     63                 " ignore must be specified with a separate --ignorerels option." )
     64
     65
     66
     67 -    def strip_out_zenoss_internals(self, doc):
     68          """
     69          Remove Zenoss internal-use objects that we don't need for an import.
     70          doc is our XML document tree.
     71
     72          @param doc: XML tree
     73          @type doc: XML DOM document
     74          @return: XML output
     75          @rtype: string
     76          """
     77
     78          _retain_class = (
     79              "Products.ZenModel.DeviceClass",
     80              "Products.ZenModel.Device",
     81              )
     82
     83          _retain_props = (
     84              "description",
     85              "productionState",
     86              "priority",
     87              "monitors",
     88              )
     89
     90          def denewline(s):
     91              """
     92              Remove blank lines and standardize on Unix-style newlines.
     93
     94              @param s: XML output
     95              @type s: string
     96              @return: XML output
     97              @rtype: string
     98              """
     99              while re.search(_newlines, s):
    100                  s = re.sub(_newlines, '\n', s)
    101              return s
    102
    103          def clearObjects(node):
    104              """
    105              Remove devices from the export list
    106
    107              @param node: XML tree
    108              @type node: XML DOM object
    109              """
    110
    111              def keepDevice(elem):
    112                  """
    113                  Look for objects that we should be exporting...
    114
    115                  @param elem: XML element
    116                  @type elem: XML DOM object
    117                  @return: should the element be kept in the resulting output?
    118                  @rtype: boolean
    119                  """
    120                  try: return not elem.getAttribute('module') in _retain_class
    121                  except: return True
    122
    123              try: elems = node.getElementsByTagName('object')
    124              except AttributeError: pass
    125              else:
    126                  elems = filter(keepDevice, elems)
    127                  [elem.parentNode.removeChild(elem) for elem in elems]
    128
    129
    130          def clearProps(node):
    131              """
    132              Remove any properties that shouldn't be exported
    133
    134              @param node: XML tree
    135              @type node: XML DOM object
    136              """
    137              try:
    138                  props = node.getElementsByTagName('property')
    139              except AttributeError:
    140                  pass
    141              else:
    142                  for prop in props:
    143                      if prop.getAttribute('module') not in _retain_props:
    144                          prop.parentNode.removeChild(prop)
    145
    146          # From our XML document root, do any last-minute cleanup before exporting
    147          root = doc.getElementsByTagName('objects')[0]
    148          clearObjects(root)
    149          clearProps(root)
    150
    151          # Standardize the output of the standard XML pretty printer
    152          return denewline(doc.toprettyxml().replace('\t', ' '*4))
    153
    154
    155 -    def getVersion(self):
    156          """
    157          Gather our current version information
    158
    159          @return: Zenoss version information
    160          @rtype: string
    161          """
    162          from Products.ZenModel.ZenossInfo import ZenossInfo
    163          zinfo = ZenossInfo('')
    164          return str(zinfo.getZenossVersion())
    165
    166
    167 -    def getServerName(self):
    168          """
    169          Gather our Zenoss server name
    170
    171          @return: Zenoss server name
    172          @rtype: string
    173          """
    174          import socket
    175          return socket.gethostname()
    176
    177
    178 -    def export(self):
    179          """
    180          Create XML header and then call exportXml() for all objects starting at root.
    181          """
    182
    183          root = self.dmd.Devices
    184          if not hasattr(root, "exportXml"):
    185              print  "ERROR: Root object for %s is not exportable (exportXml not found)" % root
    186              sys.exit(1)
    187
    188          export_date = datetime.datetime.now()
    189          version = self.getVersion()
    190          server = self.getServerName()
    191
    192          # TODO: When the DTD gets created, add the reference here
    193          buffer = StringIO.StringIO()
    194          buffer.write( """<?xml version="1.0" encoding="ISO-8859-1" ?>
    195
    196  <!--
    197      Zenoss Device export completed on %s
    198
    199      Use ImportDevices to import this file.
    200
    201      For more information about Zenoss, go to http://www.zenoss.com
    202   -->
    203
    204  <objects version="%s" export_date="%s" zenoss_server="%s" >\n""" % \
    205           ( export_date, version, export_date, server ))
    206
    207
    208          # Pass off all the hard work to the objects
    209          root.exportXml( buffer, self.options.ignorerels, True )
    210
    211          # Write the ending tag
    212          buffer.write( "</objects>\n" )
    213
    214          # Create an XML document tree that we clean up and then export
    215          doc = parseString(buffer.getvalue())
    216          finalxml = self.strip_out_zenoss_internals(doc)
    217
    218          # Actually write out the file
    219          self.outfile.write(finalxml)
    220          self.outfile.close()
    221
    222          # Clean up our StringIO object
    223          buffer.close()
    224          doc.unlink()
    225
    226
    227  if __name__ == '__main__':
    228      ex = ExportDevices()
    229      ex.export()
    230