Package Products :: Package ZenModel :: Module zendmd
[hide private]
[frames] | no frames]

Source Code for Module Products.ZenModel.zendmd

  1  #!/usr/bin/env python 
  2  ############################################################################## 
  3  #  
  4  # Copyright (C) Zenoss, Inc. 2007, all rights reserved. 
  5  #  
  6  # This content is made available according to terms specified in 
  7  # License.zenoss under the directory where your Zenoss product is installed. 
  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   
22 -def setup_loader():
23 os.environ.setdefault("CELERY_LOADER", "Products.ZenUtils.celeryintegration.ZenossLoader")
24 25 setup_loader() 26 27 # Parse the command line for host and port; have to do it before Zope 28 # configuration, because it hijacks option parsing. 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 # Looks like we have IPython but the wrong version of readline, likely on OSX 10.6 64 IPShellEmbed = None 65 from rlcompleter import Completer 66 except ImportError: 67 pass 68 69 # Zope magic ensues! 70 import Zope2 71 CONF_FILE = os.path.join(os.environ['ZENHOME'], 'etc', 'zope.conf') 72 73 # hide any positional arguments during Zope2 configure 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 # restore normality 78 79 # Now we have the right paths, so we can do the rest of the imports 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
90 -def set_db_config(host=None, port=None):
91 # Modify the database configuration manually 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
100 -def _customStuff():
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 # Connect to the database, set everything up 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 #Chip's pitched battle against segfault. 124 #import pdb;pdb.set_trace() 125 #setImplementation('PYTHON') 126 127 login('admin') 128 129 # Useful references 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
299 -class ZenCompleter(Completer):
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 = ''
338 - def complete(self, text, state):
339 # Don't show all objects if we're typing in code 340 if self.current_prompt == sys.ps2: 341 if state == 0: 342 if text == '': 343 return ' ' 344 else: 345 return None 346 347 return Completer.complete(self, text, state)
348 349
350 - def global_matches(self, text):
351 """ 352 Compute matches when text is a simple name. 353 """ 354 matches = [] 355 for name in self.namespace: 356 if name.startswith(text): 357 matches.append(name) 358 359 return matches
360
361 - def attr_matches(self, text):
362 """ 363 Compute matches when text contains a dot. 364 """ 365 matches = [] 366 for name in Completer.attr_matches(self, text): 367 if name.endswith("__roles__"): 368 continue 369 component = name.split('.')[-1] 370 if component in self.ignored_names: 371 continue 372 ignore = False 373 for prefix in self.ignored_prefixes: 374 if component.startswith(prefix): 375 ignore = True 376 break 377 378 if not ignore: 379 matches.append(name) 380 381 return matches
382 #return filter(lambda x: not x.endswith("__roles__"), 383 #Completer.attr_matches(self, text)) 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
413 - def raw_input(self, prompt=""):
414 if self.completer: 415 self.completer.current_prompt = prompt 416 return code.InteractiveConsole.raw_input(self, prompt)
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 # Do we want to connect to a database other than the one specified in 430 # zope.conf? 431 if opts.host or opts.port: 432 set_db_config(opts.host, opts.port) 433 434 vars = _customStuff() 435 # set the first positional argument as the --script arg 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 # Start up the console 473 myconsole = HistoryConsole(locals=vars) 474 myconsole.interact(_banner) 475 finally: 476 # try to abort any open transactions for our two phase commit listeners 477 try: 478 transaction.abort() 479 except: 480 pass 481