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

# Source Code for Module Products.ZenRelations.ExportDevices

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