1
2
3
4
5
6
7
8
9
10
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
29 _newlines = re.compile('\n[\t \r]*\n', re.M)
30
32 """
33 Wrapper class around exportXml() to create XML exports of devices.
34 """
35
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
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
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
147 root = doc.getElementsByTagName('objects')[0]
148 clearObjects(root)
149 clearProps(root)
150
151
152 return denewline(doc.toprettyxml().replace('\t', ' '*4))
153
154
165
166
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
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
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
209 root.exportXml( buffer, self.options.ignorerels, True )
210
211
212 buffer.write( "</objects>\n" )
213
214
215 doc = parseString(buffer.getvalue())
216 finalxml = self.strip_out_zenoss_internals(doc)
217
218
219 self.outfile.write(finalxml)
220 self.outfile.close()
221
222
223 buffer.close()
224 doc.unlink()
225
226
227 if __name__ == '__main__':
228 ex = ExportDevices()
229 ex.export()
230