1
2
3
4
5
6
7
8
9
10
11
12 import sys
13 import os
14 import os.path
15 import code
16 import atexit
17 import logging
18 import transaction
19 from subprocess import Popen, PIPE
20 from optparse import OptionParser
21
23 os.environ.setdefault("CELERY_LOADER", "Products.ZenUtils.celeryintegration.ZenossLoader")
24
25 setup_loader()
26
27
28
29
30
31 parser = OptionParser(usage='usage: %prog [options] -- [ipthon_options] [ipython_args]')
32 parser.add_option('--host',
33 dest="host", default=None,
34 help="Hostname of ZEO server")
35 parser.add_option('--port',
36 dest="port", type="int", default=None,
37 help="Port of ZEO server")
38 parser.add_option('--script',
39 dest="script", default=None,
40 help="Name of file to execute.")
41 parser.add_option('--commit',
42 dest="commit", default=False, action="store_true",
43 help="Run commit() at end of script?")
44 parser.add_option('-n', '--no-ipython',
45 dest="use_ipython", default=True, action="store_false",
46 help="Do not embed IPython shell if IPython is found")
47
48 opts, args = parser.parse_args()
49
50 readline = rlcompleter = None
51 Completer = object
52 IPShellEmbed = None
53
54 if opts.use_ipython:
55 try:
56 import readline
57
58 try:
59 from IPython.Shell import IPShellEmbed
60 except ImportError:
61 IPShellEmbed = None
62 except AttributeError:
63
64 IPShellEmbed = None
65 from rlcompleter import Completer
66 except ImportError:
67 pass
68
69
70 import Zope2
71 CONF_FILE = os.path.join(os.environ['ZENHOME'], 'etc', 'zope.conf')
72
73
74 _argv = sys.argv
75 sys.argv = [sys.argv[0], ] + [x for x in sys.argv[1:] if x.startswith("-")]
76 Zope2.configure(CONF_FILE)
77 sys.argv = _argv
78
79
80 from Products.CMFCore.utils import getToolByName
81 from AccessControl.SecurityManagement import newSecurityManager
82 from AccessControl.SecurityManagement import noSecurityManager
83 from Products.ZenUtils.Utils import zenPath, set_context
84 from Products.ZenModel.IpNetwork import IpNetworkPrinterFactory
85 from Products.ZenMessaging import audit
86
87 _CUSTOMSTUFF = []
88
89
91
92 from App.config import getConfiguration
93 serverconfig = getConfiguration().databases[1].config.storage.config
94 xhost, xport = serverconfig.server[0].address
95 if host: xhost = host
96 if port: xport = port
97 serverconfig.server[0].address = (xhost, xport)
98
99
101 """
102 Everything available in the console is defined here.
103 """
104
105 import socket
106 from transaction import commit
107 from pprint import pprint
108 from Products.ZenUtils.Utils import setLogLevel
109 from Products.Zuul import getFacade, listFacades
110
111
112 app = Zope2.app()
113 app = set_context(app)
114
115 def login(username='admin'):
116 utool = getToolByName(app, 'acl_users')
117 user = utool.getUserById(username)
118 if user is None:
119 user = app.zport.acl_users.getUserById(username)
120 user = user.__of__(utool)
121 newSecurityManager(None, user)
122 from AccessControl.Implementation import setImplementation
123
124
125
126
127 login('admin')
128
129
130 zport = app.zport
131 dmd = zport.dmd
132 sync = zport._p_jar.sync
133 find = dmd.Devices.findDevice
134 devices = dmd.Devices
135 me = find(socket.getfqdn())
136 auditComment = audit.auditComment
137 shell_stdout = []
138 shell_stderr = []
139
140 def reindex():
141 sync()
142 dmd.Devices.reIndex()
143 dmd.Events.reIndex()
144 dmd.Manufacturers.reIndex()
145 dmd.Networks.reIndex()
146 commit()
147
148 def logout():
149 noSecurityManager()
150
151 def zhelp():
152 cmds = sorted(filter(lambda x: not x.startswith("_"), _CUSTOMSTUFF))
153 for cmd in cmds:
154 print cmd
155
156 def grepdir(obj, regex=""):
157 if regex:
158 import re
159 pattern = re.compile(regex)
160 for key in dir(obj):
161 if pattern.search(key):
162 print key
163
164 def lookupGuid(guid):
165 """
166 Given a guid this returns the object that it identifies
167 """
168 from Products.ZenUtils.guid.interfaces import IGUIDManager
169 manager = IGUIDManager(dmd)
170 return manager.getObject(guid)
171
172 def version():
173 for info in zport.About.getAllVersions():
174 print "%10s: %s" % (info['header'], info['data'])
175 print "%10s: %s" % ("DMD", dmd.version)
176
177 def printNets(net=dmd.Networks, format="text", out=sys.stdout):
178 """
179 Print out the IpNetwork and IpAddress hierarchy under net. To print
180 out everything call printNets(dmd.Networks). format can be text,
181 python, or xml.
182 """
183 factory = IpNetworkPrinterFactory()
184 printer = factory.createIpNetworkPrinter(format, out)
185 printer.printIpNetwork(net)
186
187
188 def cleandir(obj):
189 portaldir = set(dir(dmd))
190 objdir = set(dir(obj))
191 appdir = set(dir(app))
192 result = sorted(objdir - portaldir - appdir)
193 pprint(result)
194
195 def history(start=None, end=None, lines=30,
196 number=False):
197 """
198 Display the history starting from entry 'start' to
199 entry 'end'. Only available on platforms where the
200 readline module can be imported.
201
202 History starts from 0 and goes to a large number.
203 The history file is $ZENHOME/.pyhistory by default.
204
205 @parameter start: Line number to start printing
206 @type start: integer
207 @parameter end: Line number to finish printing
208 @type end: integer
209 @parameter lines: number of lines to show if no end
210 @type lines: integer
211 @parameter number: show the line numbers?
212 @type number: boolean
213 """
214 if readline is not None:
215 maxHistLength = readline.get_current_history_length()
216 if start is None:
217 start = maxHistLength
218 if end is None:
219 end = maxHistLength - lines
220 if start < end:
221 end, start = start, end
222 for i in range(end, start):
223 if number:
224 print i, readline.get_history_item(i)
225 else:
226 print readline.get_history_item(i)
227
228 def sh(cmd, interactive=True):
229 """
230 Execute a shell command. If interactive is False, then
231 direct the contents of stdout into shell_stdout and the
232 output of stderr into shell_stderr.
233
234 @parameter cmd: shell command to execute
235 @type cmd: string
236 @parameter interactive: show outut to the screen or not
237 @type interactive: boolean
238 """
239 if interactive:
240 proc = Popen(cmd, shell=True)
241 else:
242 proc = Popen(cmd, stdout=PIPE, stderr=PIPE, shell=True)
243 output, errors = proc.communicate()
244 proc.wait()
245 if not interactive:
246 output = output.split('\n')[:-1]
247 errors = errors.split('\n')[:-1]
248 _CUSTOMSTUFF['shell_stdout'] = output
249 _CUSTOMSTUFF['shell_stderr'] = errors
250 return output, errors
251
252 def edit(file=None, start=None, end=None, lines=30):
253 """
254 Use the value of the EDITOR environment variable to
255 edit a file. Defaults to the original Unix IDE -- vi.
256
257 @parameter file: name of file to edit -- defaults to a temp file
258 @type file: string
259 @parameter start: Line number to start printing
260 @type start: integer
261 @parameter end: Line number to finish printing
262 @type end: integer
263 @parameter lines: number of lines to show if no end
264 @type lines: integer
265 """
266 editor = os.environ.get('EDITOR', 'vi')
267 isNewFile = True
268 isTmpName = False
269 if file == None:
270 isTmpName = True
271 file = os.tempnam()
272 fp = open(file, 'w')
273 elif os.path.exists(file):
274 isNewFile = False
275 else:
276 fp = open(file, 'w')
277
278 if isNewFile and readline is not None:
279 maxHistLength = readline.get_current_history_length()
280 if start is None:
281 start = maxHistLength
282 if end is None:
283 end = maxHistLength - lines
284 if start < end:
285 end, start = start, end
286 for i in range(end, start):
287 fp.write(readline.get_history_item(i) + '\n')
288 fp.close()
289
290 sh('%s %s' % (editor, file))
291 execfile(file, globals(), _CUSTOMSTUFF)
292 if isTmpName:
293 os.unlink(file)
294
295 _CUSTOMSTUFF = locals()
296 return _CUSTOMSTUFF
297
298
300 """
301 Provides the abiility to specify *just* the zendmd-specific
302 stuff when you first enter and hit tab-tab, and also the
303 ability to remove junk that we don't need to see.
304 """
305 ignored_names = [
306 "COPY", "DELETE", "HEAD", "HistoricalRevisions",
307 "LOCK", "MKCOL", "MOVE", "OPTIONS",
308 "Open", "PROPFIND", "PROPPATCH",
309 "PUT", "REQUEST", "SQLConnectionIDs",
310 "SiteRootAdd", "TRACE", "UNLOCK",
311 "ac_inherited_permissions",
312 "access_debug_info",
313 "bobobase_modification_time",
314 "manage_historyCompare",
315 "manage_historyCopy",
316 "manage_addDTMLDocument",
317 "manage_addDTMLMethod",
318 "manage_clone",
319 "manage_copyObjects",
320 "manage_copyright",
321 "manage_cutObjects",
322 "manage_historicalComparison",
323 "validClipData",
324 "manage_CopyContainerAllItems",
325 "manage_CopyContainerFirstItem",
326 "manage_DAVget",
327 "manage_FTPlist",
328 "manage_UndoForm",
329 "manage_access",
330 ]
331 ignored_prefixes = [
332 '_', 'wl_', 'cb_', 'acl', 'http__', 'dav_',
333 'manage_before', 'manage_after',
334 'manage_acquired',
335 ]
336
337 current_prompt = ''
348
349
360
382
383
384
385
386
387 -class HistoryConsole(code.InteractiveConsole):
388 """
389 Subclass the default InteractiveConsole to get readline history
390 """
391 - def __init__(self, locals=None, filename="<console>",
392 histfile=zenPath('.pyhistory')):
393 code.InteractiveConsole.__init__(self, locals, filename)
394 self.completer = None
395 if readline is not None:
396 self.completer = ZenCompleter(locals)
397 readline.set_completer(self.completer.complete)
398 readline.parse_and_bind("tab: complete")
399 self.init_history(histfile)
400
401
402 - def init_history(self, histfile):
403 if hasattr(readline, "read_history_file"):
404 try:
405 readline.read_history_file(histfile)
406 except IOError:
407 pass
408 atexit.register(self.save_history, histfile)
409
410 - def save_history(self, histfile):
411 readline.write_history_file(histfile)
412
417
418 - def runsource(self, source, filename):
419 if source and source[0] == '!':
420 self.locals['sh'](source[1:])
421 return False
422 elif source and source[0] == '|':
423 self.locals['sh'](source[1:], interactive=False)
424 return False
425 return code.InteractiveConsole.runsource(self, source, filename)
426
427
428 if __name__=="__main__":
429
430
431 if opts.host or opts.port:
432 set_db_config(opts.host, opts.port)
433
434 vars = _customStuff()
435
436 for arg in sys.argv[1:]:
437 if not arg.startswith("-") and os.path.exists(arg):
438 opts.script = arg
439 break
440 if opts.script:
441 if not os.path.exists(opts.script):
442 print "Unable to open script file '%s' -- exiting" % opts.script
443 sys.exit(1)
444 execfile(opts.script, globals(), vars)
445 if opts.commit:
446 from transaction import commit
447 commit()
448 else:
449 try:
450 transaction.abort()
451 except:
452 pass
453 sys.exit(0)
454
455 audit.audit('Shell.Script.Run')
456 _banner = ("Welcome to the Zenoss dmd command shell!\n"
457 "'dmd' is bound to the DataRoot. 'zhelp()' to get a list of "
458 "commands.")
459 try:
460 if IPShellEmbed:
461 sys.argv[1:] = args
462 ipshell = IPShellEmbed(banner=_banner)
463 ipshell(local_ns=vars)
464 else:
465 if readline is not None:
466 _banner = '\n'.join([_banner,
467 "Use TAB-TAB to see a list of zendmd related commands.",
468 "Tab completion also works for objects -- hit tab after"
469 " an object name and '.'", " (eg dmd. + tab-key)."])
470
471
472
473 myconsole = HistoryConsole(locals=vars)
474 myconsole.interact(_banner)
475 finally:
476
477 try:
478 transaction.abort()
479 except:
480 pass
481