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