| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  | #!/usr/bin/env python | 
					
						
							| 
									
										
										
										
											2010-11-01 23:49:21 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | #   The contents of this file are subject to the Mozilla Public License | 
					
						
							|  |  |  | #   Version 1.1 (the "License"); you may not use this file except in | 
					
						
							|  |  |  | #   compliance with the License. You may obtain a copy of the License at | 
					
						
							|  |  |  | #   http://www.mozilla.org/MPL/ | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | #   Software distributed under the License is distributed on an "AS IS" | 
					
						
							|  |  |  | #   basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the | 
					
						
							|  |  |  | #   License for the specific language governing rights and limitations | 
					
						
							|  |  |  | #   under the License. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | #   The Original Code is RabbitMQ Management Plugin. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | #   The Initial Developer of the Original Code is VMware, Inc. | 
					
						
							| 
									
										
										
										
											2012-02-02 21:24:33 +08:00
										 |  |  | #   Copyright (c) 2010-2012 VMware, Inc.  All rights reserved. | 
					
						
							| 
									
										
										
										
											2010-11-01 23:49:21 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-09 22:35:38 +08:00
										 |  |  | from ConfigParser import ConfigParser, NoSectionError | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  | from optparse import OptionParser | 
					
						
							|  |  |  | import sys | 
					
						
							|  |  |  | import httplib | 
					
						
							|  |  |  | import urllib | 
					
						
							|  |  |  | import base64 | 
					
						
							|  |  |  | import json | 
					
						
							| 
									
										
										
										
											2010-10-19 18:52:38 +08:00
										 |  |  | import os | 
					
						
							| 
									
										
										
										
											2010-11-20 01:50:07 +08:00
										 |  |  | import socket | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | LISTABLE = ['connections', 'channels', 'exchanges', 'queues', 'bindings', | 
					
						
							| 
									
										
										
										
											2010-11-09 19:02:22 +08:00
										 |  |  |             'users', 'vhosts', 'permissions', 'nodes'] | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-03 21:20:13 +08:00
										 |  |  | SHOWABLE = ['overview'] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-19 01:21:10 +08:00
										 |  |  | PROMOTE_COLUMNS = ['vhost', 'name', 'type', | 
					
						
							|  |  |  |                    'source', 'destination', 'destination_type', 'routing_key'] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-19 18:17:11 +08:00
										 |  |  | URIS = { | 
					
						
							|  |  |  |     'exchange':   '/exchanges/{vhost}/{name}', | 
					
						
							|  |  |  |     'queue':      '/queues/{vhost}/{name}', | 
					
						
							|  |  |  |     'binding':    '/bindings/{vhost}/e/{source}/{destination_char}/{destination}', | 
					
						
							|  |  |  |     'binding_del':'/bindings/{vhost}/e/{source}/{destination_char}/{destination}/{properties_key}', | 
					
						
							|  |  |  |     'vhost':      '/vhosts/{name}', | 
					
						
							|  |  |  |     'user':       '/users/{name}', | 
					
						
							|  |  |  |     'permission': '/permissions/{vhost}/{user}' | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-19 17:39:25 +08:00
										 |  |  | DECLARABLE = { | 
					
						
							| 
									
										
										
										
											2010-10-19 18:17:11 +08:00
										 |  |  |     'exchange':   {'mandatory': ['name', 'type'], | 
					
						
							| 
									
										
										
										
											2010-11-17 18:51:23 +08:00
										 |  |  |                    'optional':  {'auto_delete': 'false', 'durable': 'true', | 
					
						
							|  |  |  |                                  'internal': 'false'}}, | 
					
						
							| 
									
										
										
										
											2010-10-19 18:17:11 +08:00
										 |  |  |     'queue':      {'mandatory': ['name'], | 
					
						
							| 
									
										
										
										
											2012-01-12 21:06:42 +08:00
										 |  |  |                    'optional':  {'auto_delete': 'false', 'durable': 'true', | 
					
						
							|  |  |  |                                  'node': None}}, | 
					
						
							| 
									
										
										
										
											2010-10-19 18:17:11 +08:00
										 |  |  |     'binding':    {'mandatory': ['source', 'destination_type', 'destination', | 
					
						
							|  |  |  |                                  'routing_key'], | 
					
						
							|  |  |  |                    'optional':  {}}, | 
					
						
							|  |  |  |     'vhost':      {'mandatory': ['name'], | 
					
						
							|  |  |  |                    'optional':  {}}, | 
					
						
							| 
									
										
										
										
											2011-06-09 22:12:02 +08:00
										 |  |  |     'user':       {'mandatory': ['name', 'password', 'tags'], | 
					
						
							| 
									
										
										
										
											2010-10-19 18:17:11 +08:00
										 |  |  |                    'optional':  {}}, | 
					
						
							| 
									
										
										
										
											2010-11-27 01:42:13 +08:00
										 |  |  |     'permission': {'mandatory': ['vhost', 'user', 'configure', 'write', 'read'], | 
					
						
							| 
									
										
										
										
											2010-10-19 18:17:11 +08:00
										 |  |  |                    'optional':  {}} | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | DELETABLE = { | 
					
						
							|  |  |  |     'exchange':   {'mandatory': ['name']}, | 
					
						
							|  |  |  |     'queue':      {'mandatory': ['name']}, | 
					
						
							|  |  |  |     'binding':    {'mandatory': ['source', 'destination_type', 'destination', | 
					
						
							|  |  |  |                                  'properties_key']}, | 
					
						
							|  |  |  |     'vhost':      {'mandatory': ['name']}, | 
					
						
							|  |  |  |     'user':       {'mandatory': ['name']}, | 
					
						
							|  |  |  |     'permission': {'mandatory': ['vhost', 'user']} | 
					
						
							| 
									
										
										
										
											2010-10-19 17:39:25 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-10-19 01:51:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-19 18:29:39 +08:00
										 |  |  | CLOSABLE = { | 
					
						
							|  |  |  |     'connection': {'mandatory': ['name'], | 
					
						
							|  |  |  |                    'optional':  {}, | 
					
						
							|  |  |  |                    'uri':       '/connections/{name}'} | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PURGABLE = { | 
					
						
							|  |  |  |     'queue': {'mandatory': ['name'], | 
					
						
							|  |  |  |               'optional':  {}, | 
					
						
							|  |  |  |               'uri':       '/queues/{vhost}/{name}/contents'} | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-10 21:39:10 +08:00
										 |  |  | EXTRA_VERBS = { | 
					
						
							| 
									
										
										
										
											2011-03-10 23:09:04 +08:00
										 |  |  |     'publish': {'mandatory': ['routing_key'], | 
					
						
							|  |  |  |                 'optional':  {'payload': None, | 
					
						
							|  |  |  |                               'exchange': 'amq.default', | 
					
						
							| 
									
										
										
										
											2011-03-10 21:39:10 +08:00
										 |  |  |                               'payload_encoding': 'string'}, | 
					
						
							|  |  |  |                 'uri':       '/exchanges/{vhost}/{exchange}/publish'}, | 
					
						
							|  |  |  |     'get':     {'mandatory': ['queue'], | 
					
						
							| 
									
										
										
										
											2011-03-10 22:58:02 +08:00
										 |  |  |                 'optional':  {'count': '1', 'requeue': 'true', | 
					
						
							| 
									
										
										
										
											2012-01-04 22:45:01 +08:00
										 |  |  |                               'payload_file': None, 'encoding': 'auto'}, | 
					
						
							| 
									
										
										
										
											2011-03-10 21:39:10 +08:00
										 |  |  |                 'uri':       '/queues/{vhost}/{queue}/get'} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-19 18:17:11 +08:00
										 |  |  | for k in DECLARABLE: | 
					
						
							|  |  |  |     DECLARABLE[k]['uri'] = URIS[k] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | for k in DELETABLE: | 
					
						
							|  |  |  |     DELETABLE[k]['uri'] = URIS[k] | 
					
						
							|  |  |  |     DELETABLE[k]['optional'] = {} | 
					
						
							|  |  |  | DELETABLE['binding']['uri'] = URIS['binding_del'] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  | def make_usage(): | 
					
						
							| 
									
										
										
										
											2010-10-19 01:51:42 +08:00
										 |  |  |     usage = """usage: %prog [options] cmd | 
					
						
							|  |  |  | where cmd is one of: | 
					
						
							| 
									
										
										
										
											2010-10-19 18:17:11 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  | """ | 
					
						
							|  |  |  |     for l in LISTABLE: | 
					
						
							| 
									
										
										
										
											2010-12-22 00:10:38 +08:00
										 |  |  |         usage += "  list {0} [<column>...]\n".format(l) | 
					
						
							| 
									
										
										
										
											2011-01-03 21:20:13 +08:00
										 |  |  |     for s in SHOWABLE: | 
					
						
							|  |  |  |         usage += "  show {0} [<column>...]\n".format(s) | 
					
						
							| 
									
										
										
										
											2011-03-10 21:39:10 +08:00
										 |  |  |     usage += fmt_usage_stanza(DECLARABLE,  'declare') | 
					
						
							|  |  |  |     usage += fmt_usage_stanza(DELETABLE,   'delete') | 
					
						
							|  |  |  |     usage += fmt_usage_stanza(CLOSABLE,    'close') | 
					
						
							|  |  |  |     usage += fmt_usage_stanza(PURGABLE,    'purge') | 
					
						
							|  |  |  |     usage += fmt_usage_stanza(EXTRA_VERBS, '') | 
					
						
							| 
									
										
										
										
											2010-10-19 18:17:11 +08:00
										 |  |  |     usage += """ | 
					
						
							| 
									
										
										
										
											2011-02-26 01:00:13 +08:00
										 |  |  |   export <file> | 
					
						
							| 
									
										
										
										
											2011-03-10 23:12:24 +08:00
										 |  |  |   import <file> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   * If payload is not specified on publish, standard input is used | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   * If payload_file is not specified on get, the payload will be shown on | 
					
						
							|  |  |  |     standard output along with the message metadata | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-09 22:35:38 +08:00
										 |  |  |   * If payload_file is specified on get, count must not be set | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   CONFIGURATION FILE | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   It is possible to specify a configuration file from the command line. | 
					
						
							|  |  |  |   Hosts can be configured easily in a configuration file and called | 
					
						
							|  |  |  |   from the command line. | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   ### Configuration file example | 
					
						
							|  |  |  |   # rabbitmqadmin.conf.example START | 
					
						
							|  |  |  |   [host_normal] | 
					
						
							|  |  |  |   hostname = localhost | 
					
						
							|  |  |  |   port = 55672 | 
					
						
							|  |  |  |   username = guest | 
					
						
							|  |  |  |   password = guest | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   [host_ssl] | 
					
						
							|  |  |  |   hostname = otherhost | 
					
						
							|  |  |  |   port = 55672 | 
					
						
							|  |  |  |   username = guest | 
					
						
							|  |  |  |   password = guest | 
					
						
							|  |  |  |   ssl = True | 
					
						
							|  |  |  |   ssl_key_file = /path/to/key.pem | 
					
						
							|  |  |  |   ssl_cert_file = /path/to/cert.pem | 
					
						
							|  |  |  |   # rabbitmqadmin.conf.example END | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   ### to benefit from the configuration file: | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   rabbitmqadmin -c rabbitmqadmin.conf.example -N host_normal ... | 
					
						
							|  |  |  |   """ | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  |     return usage | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-19 18:29:39 +08:00
										 |  |  | def fmt_usage_stanza(root, verb): | 
					
						
							| 
									
										
										
										
											2010-10-19 18:40:10 +08:00
										 |  |  |     def fmt_args(args): | 
					
						
							| 
									
										
										
										
											2011-01-06 19:37:59 +08:00
										 |  |  |         res = " ".join(["{0}=...".format(a) for a in args['mandatory']]) | 
					
						
							| 
									
										
										
										
											2010-10-19 18:40:10 +08:00
										 |  |  |         opts = " ".join("{0}=...".format(o) for o in args['optional'].keys()) | 
					
						
							|  |  |  |         if opts != "": | 
					
						
							|  |  |  |             res += " [{0}]".format(opts) | 
					
						
							|  |  |  |         return res | 
					
						
							| 
									
										
										
										
											2010-10-19 18:29:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     text = "\n" | 
					
						
							| 
									
										
										
										
											2011-03-10 21:39:10 +08:00
										 |  |  |     if verb != "": | 
					
						
							|  |  |  |         verb = " " + verb | 
					
						
							| 
									
										
										
										
											2010-10-19 18:29:39 +08:00
										 |  |  |     for k in root.keys(): | 
					
						
							| 
									
										
										
										
											2011-03-10 21:39:10 +08:00
										 |  |  |         text += " {0} {1} {2}\n".format(verb, k, fmt_args(root[k])) | 
					
						
							| 
									
										
										
										
											2010-10-19 18:29:39 +08:00
										 |  |  |     return text | 
					
						
							| 
									
										
										
										
											2010-10-19 01:51:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-09 22:35:38 +08:00
										 |  |  | DefaultOptions = {"hostname" : "localhost", | 
					
						
							|  |  |  |                   "port" : "55672", | 
					
						
							|  |  |  |                   "vhost" : None, | 
					
						
							|  |  |  |                   "username" : "guest", | 
					
						
							|  |  |  |                   "password" : "guest", | 
					
						
							|  |  |  |                   "ssl" : False, | 
					
						
							|  |  |  |                   "ssl_key_file" : None, | 
					
						
							|  |  |  |                   "ssl_cert_file" : None, | 
					
						
							|  |  |  |                   "verbose" : True, | 
					
						
							|  |  |  |                   "format" : "table", | 
					
						
							|  |  |  |                   "depth" : 1, | 
					
						
							|  |  |  |                   "bash_completion" : False } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  | parser = OptionParser(usage=make_usage()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def make_parser(): | 
					
						
							| 
									
										
										
										
											2012-02-09 22:35:38 +08:00
										 |  |  |     parser.add_option("-c", "--config", dest="config", | 
					
						
							|  |  |  |                       help="configuration file", | 
					
						
							|  |  |  |                       metavar="CONFIG") | 
					
						
							|  |  |  |     parser.add_option("-N", "--node", dest="node", | 
					
						
							|  |  |  |                       help="node described in the configuration file", | 
					
						
							|  |  |  |                       metavar="NODE") | 
					
						
							|  |  |  |     parser.add_option("-H", "--host", dest="hostname", | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  |                       help="connect to host HOST [default: %default]", | 
					
						
							|  |  |  |                       metavar="HOST") | 
					
						
							| 
									
										
										
										
											2012-02-09 22:35:38 +08:00
										 |  |  |     parser.add_option("-P", "--port", dest="port", | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  |                       help="connect to port PORT [default: %default]", | 
					
						
							|  |  |  |                       metavar="PORT") | 
					
						
							|  |  |  |     parser.add_option("-V", "--vhost", dest="vhost", | 
					
						
							| 
									
										
										
										
											2010-10-19 01:51:42 +08:00
										 |  |  |                       help="connect to vhost VHOST [default: all vhosts for list, '/' for declare]", | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  |                       metavar="VHOST") | 
					
						
							| 
									
										
										
										
											2012-02-09 22:35:38 +08:00
										 |  |  |     parser.add_option("-u", "--username", dest="username", | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  |                       help="connect using username USERNAME [default: %default]", | 
					
						
							|  |  |  |                       metavar="USERNAME") | 
					
						
							| 
									
										
										
										
											2012-02-09 22:35:38 +08:00
										 |  |  |     parser.add_option("-p", "--password", dest="password", | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  |                       help="connect using password PASSWORD [default: %default]", | 
					
						
							|  |  |  |                       metavar="PASSWORD") | 
					
						
							|  |  |  |     parser.add_option("-q", "--quiet", action="store_false", dest="verbose", | 
					
						
							| 
									
										
										
										
											2012-02-09 22:35:38 +08:00
										 |  |  |                       help="suppress status messages") | 
					
						
							| 
									
										
										
										
											2011-03-14 21:29:56 +08:00
										 |  |  |     parser.add_option("-s", "--ssl", action="store_true", dest="ssl", | 
					
						
							| 
									
										
										
										
											2012-02-09 22:35:38 +08:00
										 |  |  |                       help="connect with ssl") | 
					
						
							|  |  |  |     parser.add_option("--ssl-key-file", dest="ssl_key_file", | 
					
						
							| 
									
										
										
										
											2011-03-14 21:29:56 +08:00
										 |  |  |                       help="PEM format key file for SSL [default: none]") | 
					
						
							| 
									
										
										
										
											2012-02-09 22:35:38 +08:00
										 |  |  |     parser.add_option("--ssl-cert-file", dest="ssl_cert_file", | 
					
						
							| 
									
										
										
										
											2011-03-14 21:29:56 +08:00
										 |  |  |                       help="PEM format certificate file for SSL [default: none]") | 
					
						
							| 
									
										
										
										
											2012-02-09 22:35:38 +08:00
										 |  |  |     parser.add_option("-f", "--format", dest="format", | 
					
						
							| 
									
										
										
										
											2010-11-17 18:17:39 +08:00
										 |  |  |                       help="format for listing commands - one of [" + ", ".join(FORMATS.keys())  + "]  [default: %default]") | 
					
						
							| 
									
										
										
										
											2012-02-09 22:35:38 +08:00
										 |  |  |     parser.add_option("-d", "--depth", dest="depth", | 
					
						
							| 
									
										
										
										
											2010-10-19 01:21:10 +08:00
										 |  |  |                       help="maximum depth to recurse for listing tables [default: %default]") | 
					
						
							| 
									
										
										
										
											2010-11-17 18:17:39 +08:00
										 |  |  |     parser.add_option("--bash-completion", action="store_true", | 
					
						
							| 
									
										
										
										
											2012-02-09 22:35:38 +08:00
										 |  |  |                       dest="bash_completion", | 
					
						
							| 
									
										
										
										
											2010-11-17 18:17:39 +08:00
										 |  |  |                       help="Print bash completion script") | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-09 22:35:38 +08:00
										 |  |  | def make_configuration(): | 
					
						
							|  |  |  |     make_parser() | 
					
						
							|  |  |  |     (options, args) = parser.parse_args() | 
					
						
							|  |  |  |     if options.config and options.node: | 
					
						
							|  |  |  |         config = ConfigParser() | 
					
						
							|  |  |  |         config.read(options.config) | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             new_conf = dict(config.items(options.node)) | 
					
						
							|  |  |  |         except NoSectionError as error: | 
					
						
							|  |  |  |             assert_usage(False, error) | 
					
						
							|  |  |  |         new_opts = DefaultOptions.copy() | 
					
						
							|  |  |  |         for (key, val) in new_conf.items(): | 
					
						
							|  |  |  |             new_opts[key] = val | 
					
						
							|  |  |  |         for (key, val) in new_opts.items(): | 
					
						
							|  |  |  |             if getattr(options, key) is None: | 
					
						
							|  |  |  |                 setattr(options, key, val) | 
					
						
							|  |  |  |     return (options, args) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-19 18:52:38 +08:00
										 |  |  | def assert_usage(expr, error): | 
					
						
							|  |  |  |     if not expr: | 
					
						
							| 
									
										
										
										
											2011-03-15 18:29:34 +08:00
										 |  |  |         output("\nERROR: {0}\n".format(error)) | 
					
						
							|  |  |  |         output("{0} --help for help\n".format(os.path.basename(sys.argv[0]))) | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  |         sys.exit(1) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-19 01:21:10 +08:00
										 |  |  | def column_sort_key(col): | 
					
						
							|  |  |  |     if col in PROMOTE_COLUMNS: | 
					
						
							|  |  |  |         return (1, PROMOTE_COLUMNS.index(col)) | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         return (2, col) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  | def main(): | 
					
						
							| 
									
										
										
										
											2012-02-09 22:35:38 +08:00
										 |  |  |     (options, args) = make_configuration() | 
					
						
							| 
									
										
										
										
											2010-11-17 18:17:39 +08:00
										 |  |  |     if options.bash_completion: | 
					
						
							|  |  |  |         print_bash_completion() | 
					
						
							|  |  |  |         exit(0) | 
					
						
							| 
									
										
										
										
											2010-10-19 18:52:38 +08:00
										 |  |  |     assert_usage(len(args) > 0, 'Action not specified') | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  |     mgmt = Management(options, args[1:]) | 
					
						
							|  |  |  |     mode = "invoke_" + args[0] | 
					
						
							| 
									
										
										
										
											2010-10-19 18:52:38 +08:00
										 |  |  |     assert_usage(hasattr(mgmt, mode), | 
					
						
							|  |  |  |                  'Action {0} not understood'.format(args[0])) | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  |     method = getattr(mgmt, "invoke_%s" % args[0]) | 
					
						
							|  |  |  |     method() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-15 18:39:21 +08:00
										 |  |  | def output(s): | 
					
						
							|  |  |  |     print maybe_utf8(s, sys.stdout) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def die(s): | 
					
						
							|  |  |  |     sys.stderr.write(maybe_utf8("*** {0}".format(s), sys.stderr)) | 
					
						
							| 
									
										
										
										
											2010-11-20 01:50:07 +08:00
										 |  |  |     exit(1) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-15 18:39:21 +08:00
										 |  |  | def maybe_utf8(s, stream): | 
					
						
							|  |  |  |     if stream.isatty(): | 
					
						
							|  |  |  |         # It will have an encoding, which Python will respect | 
					
						
							|  |  |  |         return s | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         # It won't have an encoding, and Python will pick ASCII by default | 
					
						
							|  |  |  |         return s.encode('utf-8') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  | class Management: | 
					
						
							|  |  |  |     def __init__(self, options, args): | 
					
						
							|  |  |  |         self.options = options | 
					
						
							|  |  |  |         self.args = args | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def get(self, path): | 
					
						
							|  |  |  |         return self.http("GET", path, "") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def put(self, path, body): | 
					
						
							|  |  |  |         return self.http("PUT", path, body) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def post(self, path, body): | 
					
						
							|  |  |  |         return self.http("POST", path, body) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-19 18:17:11 +08:00
										 |  |  |     def delete(self, path): | 
					
						
							|  |  |  |         return self.http("DELETE", path, "") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  |     def http(self, method, path, body): | 
					
						
							| 
									
										
										
										
											2011-03-14 21:29:56 +08:00
										 |  |  |         if self.options.ssl: | 
					
						
							|  |  |  |             conn = httplib.HTTPSConnection(self.options.hostname, | 
					
						
							|  |  |  |                                            self.options.port, | 
					
						
							|  |  |  |                                            self.options.ssl_key_file, | 
					
						
							|  |  |  |                                            self.options.ssl_cert_file) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             conn = httplib.HTTPConnection(self.options.hostname, | 
					
						
							|  |  |  |                                           self.options.port) | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  |         headers = {"Authorization": | 
					
						
							|  |  |  |                        "Basic " + base64.b64encode(self.options.username + ":" + | 
					
						
							|  |  |  |                                                    self.options.password)} | 
					
						
							|  |  |  |         if body != "": | 
					
						
							|  |  |  |             headers["Content-Type"] = "application/json" | 
					
						
							| 
									
										
										
										
											2010-11-20 01:50:07 +08:00
										 |  |  |         try: | 
					
						
							|  |  |  |             conn.request(method, "/api%s" % path, body, headers) | 
					
						
							|  |  |  |         except socket.error as e: | 
					
						
							|  |  |  |             die("Could not connect: {0}".format(e)) | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  |         resp = conn.getresponse() | 
					
						
							| 
									
										
										
										
											2010-11-20 01:50:07 +08:00
										 |  |  |         if resp.status == 400: | 
					
						
							|  |  |  |             die(json.loads(resp.read())['reason']) | 
					
						
							|  |  |  |         if resp.status == 401: | 
					
						
							|  |  |  |             die("Access refused: {0}".format(path)) | 
					
						
							|  |  |  |         if resp.status == 404: | 
					
						
							|  |  |  |             die("Not found: {0}".format(path)) | 
					
						
							|  |  |  |         if resp.status < 200 or resp.status > 400: | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  |             raise Exception("Received %d %s for path %s\n%s" | 
					
						
							|  |  |  |                             % (resp.status, resp.reason, path, resp.read())) | 
					
						
							|  |  |  |         return resp.read() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def verbose(self, string): | 
					
						
							|  |  |  |         if self.options.verbose: | 
					
						
							| 
									
										
										
										
											2011-03-15 18:29:34 +08:00
										 |  |  |             output(string) | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def get_arg(self): | 
					
						
							| 
									
										
										
										
											2010-10-19 18:52:38 +08:00
										 |  |  |         assert_usage(len(self.args) == 1, 'Exactly one argument required') | 
					
						
							|  |  |  |         return self.args[0] | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-26 01:00:13 +08:00
										 |  |  |     def invoke_publish(self): | 
					
						
							| 
									
										
										
										
											2011-03-10 23:00:45 +08:00
										 |  |  |         (uri, upload) = self.parse_args(self.args, EXTRA_VERBS['publish']) | 
					
						
							|  |  |  |         upload['properties'] = {} # TODO do we care here? | 
					
						
							| 
									
										
										
										
											2012-01-16 19:43:34 +08:00
										 |  |  |         if not 'payload' in upload: | 
					
						
							| 
									
										
										
										
											2011-03-10 23:09:04 +08:00
										 |  |  |             data = sys.stdin.read() | 
					
						
							|  |  |  |             upload['payload'] = base64.b64encode(data) | 
					
						
							|  |  |  |             upload['payload_encoding'] = 'base64' | 
					
						
							| 
									
										
										
										
											2011-03-10 23:00:45 +08:00
										 |  |  |         resp = json.loads(self.post(uri, json.dumps(upload))) | 
					
						
							| 
									
										
										
										
											2011-02-26 01:00:13 +08:00
										 |  |  |         if resp['routed']: | 
					
						
							|  |  |  |             self.verbose("Message published") | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.verbose("Message published but NOT routed") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def invoke_get(self): | 
					
						
							| 
									
										
										
										
											2011-03-10 23:00:45 +08:00
										 |  |  |         (uri, upload) = self.parse_args(self.args, EXTRA_VERBS['get']) | 
					
						
							| 
									
										
										
										
											2012-01-16 19:43:34 +08:00
										 |  |  |         payload_file = 'payload_file' in upload and upload['payload_file'] or None | 
					
						
							| 
									
										
										
										
											2011-03-10 23:00:45 +08:00
										 |  |  |         assert_usage(not payload_file or upload['count'] == '1', | 
					
						
							| 
									
										
										
										
											2011-03-10 22:58:02 +08:00
										 |  |  |                      'Cannot get multiple messages using payload_file') | 
					
						
							| 
									
										
										
										
											2011-03-10 23:00:45 +08:00
										 |  |  |         result = self.post(uri, json.dumps(upload)) | 
					
						
							| 
									
										
										
										
											2011-03-10 22:58:02 +08:00
										 |  |  |         if payload_file: | 
					
						
							|  |  |  |             write_payload_file(payload_file, result) | 
					
						
							|  |  |  |             columns = ['routing_key', 'exchange', 'message_count', | 
					
						
							|  |  |  |                        'payload_bytes', 'redelivered'] | 
					
						
							|  |  |  |             format_list(result, columns, self.options) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             format_list(result, [], self.options) | 
					
						
							| 
									
										
										
										
											2011-02-26 01:00:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  |     def invoke_export(self): | 
					
						
							|  |  |  |         path = self.get_arg() | 
					
						
							| 
									
										
										
										
											2011-10-13 23:32:55 +08:00
										 |  |  |         definitions = self.get("/definitions") | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  |         with open(path, 'w') as f: | 
					
						
							| 
									
										
										
										
											2011-10-13 23:32:55 +08:00
										 |  |  |             f.write(definitions) | 
					
						
							|  |  |  |         self.verbose("Exported definitions for %s to \"%s\"" | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  |                      % (self.options.hostname, path)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def invoke_import(self): | 
					
						
							|  |  |  |         path = self.get_arg() | 
					
						
							|  |  |  |         with open(path, 'r') as f: | 
					
						
							| 
									
										
										
										
											2011-10-13 23:32:55 +08:00
										 |  |  |             definitions = f.read() | 
					
						
							|  |  |  |         self.post("/definitions", definitions) | 
					
						
							|  |  |  |         self.verbose("Imported definitions for %s from \"%s\"" | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  |                      % (self.options.hostname, path)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def invoke_list(self): | 
					
						
							| 
									
										
										
										
											2011-05-09 23:08:24 +08:00
										 |  |  |         cols = self.args[1:] | 
					
						
							|  |  |  |         uri = self.list_show_uri(LISTABLE, 'list', cols) | 
					
						
							|  |  |  |         format_list(self.get(uri), cols, self.options) | 
					
						
							| 
									
										
										
										
											2011-01-03 21:20:13 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def invoke_show(self): | 
					
						
							| 
									
										
										
										
											2011-05-09 23:08:24 +08:00
										 |  |  |         cols = self.args[1:] | 
					
						
							|  |  |  |         uri = self.list_show_uri(SHOWABLE, 'show', cols) | 
					
						
							|  |  |  |         format_list('[{0}]'.format(self.get(uri)), cols, self.options) | 
					
						
							| 
									
										
										
										
											2011-01-03 21:20:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-09 23:08:24 +08:00
										 |  |  |     def list_show_uri(self, obj_types, verb, cols): | 
					
						
							| 
									
										
										
										
											2010-12-22 00:10:38 +08:00
										 |  |  |         obj_type = self.args[0] | 
					
						
							| 
									
										
										
										
											2011-01-03 21:20:13 +08:00
										 |  |  |         assert_usage(obj_type in obj_types, | 
					
						
							|  |  |  |                      "Don't know how to {0} {1}".format(verb, obj_type)) | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  |         uri = "/%s" % obj_type | 
					
						
							|  |  |  |         if self.options.vhost: | 
					
						
							|  |  |  |             uri += "/%s" % urllib.quote_plus(self.options.vhost) | 
					
						
							| 
									
										
										
										
											2011-05-09 23:08:24 +08:00
										 |  |  |         if cols != []: | 
					
						
							|  |  |  |             uri += "?columns=" + ",".join(cols) | 
					
						
							| 
									
										
										
										
											2011-01-03 21:20:13 +08:00
										 |  |  |         return uri | 
					
						
							| 
									
										
										
										
											2010-10-19 01:21:10 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-19 01:51:42 +08:00
										 |  |  |     def invoke_declare(self): | 
					
						
							| 
									
										
										
										
											2011-03-10 23:00:45 +08:00
										 |  |  |         (obj_type, uri, upload) = self.declare_delete_parse(DECLARABLE) | 
					
						
							| 
									
										
										
										
											2010-10-19 18:17:11 +08:00
										 |  |  |         if obj_type == 'binding': | 
					
						
							| 
									
										
										
										
											2011-03-10 23:00:45 +08:00
										 |  |  |             self.post(uri, json.dumps(upload)) | 
					
						
							| 
									
										
										
										
											2010-10-19 18:17:11 +08:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2011-03-10 23:00:45 +08:00
										 |  |  |             self.put(uri, json.dumps(upload)) | 
					
						
							| 
									
										
										
										
											2010-10-19 18:17:11 +08:00
										 |  |  |         self.verbose("{0} declared".format(obj_type)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def invoke_delete(self): | 
					
						
							| 
									
										
										
										
											2011-03-10 23:00:45 +08:00
										 |  |  |         (obj_type, uri, upload) = self.declare_delete_parse(DELETABLE) | 
					
						
							| 
									
										
										
										
											2010-10-19 18:17:11 +08:00
										 |  |  |         self.delete(uri) | 
					
						
							|  |  |  |         self.verbose("{0} deleted".format(obj_type)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-19 18:29:39 +08:00
										 |  |  |     def invoke_close(self): | 
					
						
							| 
									
										
										
										
											2011-03-10 23:00:45 +08:00
										 |  |  |         (obj_type, uri, upload) = self.declare_delete_parse(CLOSABLE) | 
					
						
							| 
									
										
										
										
											2010-10-19 18:29:39 +08:00
										 |  |  |         self.delete(uri) | 
					
						
							|  |  |  |         self.verbose("{0} closed".format(obj_type)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def invoke_purge(self): | 
					
						
							| 
									
										
										
										
											2011-03-10 23:00:45 +08:00
										 |  |  |         (obj_type, uri, upload) = self.declare_delete_parse(PURGABLE) | 
					
						
							| 
									
										
										
										
											2010-10-19 18:29:39 +08:00
										 |  |  |         self.delete(uri) | 
					
						
							|  |  |  |         self.verbose("{0} purged".format(obj_type)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-19 18:17:11 +08:00
										 |  |  |     def declare_delete_parse(self, root): | 
					
						
							| 
									
										
										
										
											2010-10-19 18:52:38 +08:00
										 |  |  |         assert_usage(len(self.args) > 0, 'Type not specified') | 
					
						
							| 
									
										
										
										
											2010-10-19 01:51:42 +08:00
										 |  |  |         obj_type = self.args[0] | 
					
						
							| 
									
										
										
										
											2010-10-19 18:52:38 +08:00
										 |  |  |         assert_usage(obj_type in root, | 
					
						
							|  |  |  |                      'Type {0} not recognised'.format(obj_type)) | 
					
						
							| 
									
										
										
										
											2011-02-26 01:00:13 +08:00
										 |  |  |         obj = root[obj_type] | 
					
						
							| 
									
										
										
										
											2011-03-10 23:00:45 +08:00
										 |  |  |         (uri, upload) = self.parse_args(self.args[1:], obj) | 
					
						
							|  |  |  |         return (obj_type, uri, upload) | 
					
						
							| 
									
										
										
										
											2011-02-26 01:00:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-10 21:39:10 +08:00
										 |  |  |     def parse_args(self, args, obj): | 
					
						
							|  |  |  |         mandatory =  obj['mandatory'] | 
					
						
							|  |  |  |         optional = obj['optional'] | 
					
						
							|  |  |  |         uri_template = obj['uri'] | 
					
						
							| 
									
										
										
										
											2011-03-10 23:00:45 +08:00
										 |  |  |         upload = {} | 
					
						
							| 
									
										
										
										
											2010-10-19 01:51:42 +08:00
										 |  |  |         for k in optional.keys(): | 
					
						
							| 
									
										
										
										
											2012-01-12 21:06:42 +08:00
										 |  |  |             if optional[k]: | 
					
						
							|  |  |  |                 upload[k] = optional[k] | 
					
						
							| 
									
										
										
										
											2010-11-20 01:37:26 +08:00
										 |  |  |         for arg in args: | 
					
						
							|  |  |  |             assert_usage("=" in arg, | 
					
						
							|  |  |  |                          'Argument "{0}" not in format name=value'.format(arg)) | 
					
						
							| 
									
										
										
										
											2011-03-10 21:22:46 +08:00
										 |  |  |             (name, value) = arg.split("=", 1) | 
					
						
							| 
									
										
										
										
											2010-11-20 01:37:26 +08:00
										 |  |  |             assert_usage(name in mandatory or name in optional.keys(), | 
					
						
							|  |  |  |                          'Argument "{0}" not recognised'.format(name)) | 
					
						
							| 
									
										
										
										
											2011-03-10 23:00:45 +08:00
										 |  |  |             upload[name] = value | 
					
						
							| 
									
										
										
										
											2010-11-20 01:37:26 +08:00
										 |  |  |         for m in mandatory: | 
					
						
							| 
									
										
										
										
											2011-03-10 23:00:45 +08:00
										 |  |  |             assert_usage(m in upload.keys(), | 
					
						
							| 
									
										
										
										
											2010-11-20 01:37:26 +08:00
										 |  |  |                          'mandatory argument "{0}" required'.format(m)) | 
					
						
							| 
									
										
										
										
											2011-03-10 23:00:45 +08:00
										 |  |  |         upload['arguments'] = {} | 
					
						
							|  |  |  |         upload['vhost'] = self.options.vhost or '/' | 
					
						
							| 
									
										
										
										
											2010-10-19 17:39:25 +08:00
										 |  |  |         uri_args = {} | 
					
						
							| 
									
										
										
										
											2011-03-10 23:00:45 +08:00
										 |  |  |         for k in upload: | 
					
						
							|  |  |  |             v = upload[k] | 
					
						
							| 
									
										
										
										
											2011-03-10 22:58:02 +08:00
										 |  |  |             if v: | 
					
						
							|  |  |  |                 uri_args[k] = urllib.quote_plus(v) | 
					
						
							|  |  |  |                 if k == 'destination_type': | 
					
						
							|  |  |  |                     uri_args['destination_char'] = v[0] | 
					
						
							| 
									
										
										
										
											2011-02-26 01:00:13 +08:00
										 |  |  |         uri = uri_template.format(**uri_args) | 
					
						
							| 
									
										
										
										
											2011-03-10 23:00:45 +08:00
										 |  |  |         return (uri, upload) | 
					
						
							| 
									
										
										
										
											2010-10-19 01:51:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-22 00:10:38 +08:00
										 |  |  | def format_list(json_list, columns, options): | 
					
						
							| 
									
										
										
										
											2010-10-19 01:21:10 +08:00
										 |  |  |     format = options.format | 
					
						
							|  |  |  |     formatter = None | 
					
						
							|  |  |  |     if format == "raw_json": | 
					
						
							| 
									
										
										
										
											2011-03-15 18:29:34 +08:00
										 |  |  |         output(json_list) | 
					
						
							| 
									
										
										
										
											2010-10-19 01:21:10 +08:00
										 |  |  |         return | 
					
						
							|  |  |  |     elif format == "pretty_json": | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  |         enc = json.JSONEncoder(False, False, True, True, True, 2) | 
					
						
							| 
									
										
										
										
											2011-03-15 18:29:34 +08:00
										 |  |  |         output(enc.encode(json.loads(json_list))) | 
					
						
							| 
									
										
										
										
											2010-10-19 01:21:10 +08:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2010-11-17 18:17:39 +08:00
										 |  |  |     else: | 
					
						
							|  |  |  |         formatter = FORMATS[format] | 
					
						
							| 
									
										
										
										
											2010-10-19 18:52:38 +08:00
										 |  |  |     assert_usage(formatter != None, | 
					
						
							|  |  |  |                  "Format {0} not recognised".format(format)) | 
					
						
							| 
									
										
										
										
											2010-12-22 00:10:38 +08:00
										 |  |  |     formatter_instance = formatter(columns, options) | 
					
						
							| 
									
										
										
										
											2010-10-19 01:21:10 +08:00
										 |  |  |     formatter_instance.display(json_list) | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-19 01:21:10 +08:00
										 |  |  | class Lister: | 
					
						
							|  |  |  |     def verbose(self, string): | 
					
						
							|  |  |  |         if self.options.verbose: | 
					
						
							| 
									
										
										
										
											2011-03-15 18:29:34 +08:00
										 |  |  |             output(string) | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-19 01:21:10 +08:00
										 |  |  |     def display(self, json_list): | 
					
						
							| 
									
										
										
										
											2010-12-22 00:10:38 +08:00
										 |  |  |         depth = sys.maxint | 
					
						
							|  |  |  |         if len(self.columns) == 0: | 
					
						
							|  |  |  |             depth = int(self.options.depth) | 
					
						
							|  |  |  |         (columns, table) = self.list_to_table(json.loads(json_list), depth) | 
					
						
							| 
									
										
										
										
											2010-10-19 01:21:10 +08:00
										 |  |  |         if len(table) > 0: | 
					
						
							|  |  |  |             self.display_list(columns, table) | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  |         else: | 
					
						
							|  |  |  |             self.verbose("No items") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-19 01:21:10 +08:00
										 |  |  |     def list_to_table(self, items, max_depth): | 
					
						
							|  |  |  |         columns = {} | 
					
						
							|  |  |  |         column_ix = {} | 
					
						
							|  |  |  |         row = None | 
					
						
							|  |  |  |         table = [] | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-19 01:21:10 +08:00
										 |  |  |         def add(prefix, depth, item, fun): | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  |             for key in item: | 
					
						
							| 
									
										
										
										
											2011-05-09 23:08:55 +08:00
										 |  |  |                 column = prefix == '' and key or (prefix + '.' + key) | 
					
						
							| 
									
										
										
										
											2012-01-04 23:15:54 +08:00
										 |  |  |                 subitem = item[key] | 
					
						
							|  |  |  |                 if type(subitem) == dict: | 
					
						
							| 
									
										
										
										
											2010-10-19 01:21:10 +08:00
										 |  |  |                     if depth < max_depth: | 
					
						
							| 
									
										
										
										
											2012-01-04 23:15:54 +08:00
										 |  |  |                         add(column, depth + 1, subitem, fun) | 
					
						
							|  |  |  |                 elif type(subitem) == list: | 
					
						
							|  |  |  |                     # The first branch has slave nodes in queues in | 
					
						
							|  |  |  |                     # mind (which come out looking decent); the second | 
					
						
							|  |  |  |                     # one has applications in nodes (which look less | 
					
						
							|  |  |  |                     # so, but what would look good?). | 
					
						
							|  |  |  |                     if [x for x in subitem if type(x) != unicode] == []: | 
					
						
							|  |  |  |                         serialised = " ".join(subitem) | 
					
						
							|  |  |  |                     else: | 
					
						
							|  |  |  |                         serialised = json.dumps(subitem) | 
					
						
							|  |  |  |                     fun(column, serialised) | 
					
						
							| 
									
										
										
										
											2010-10-19 01:21:10 +08:00
										 |  |  |                 else: | 
					
						
							| 
									
										
										
										
											2012-01-04 23:15:54 +08:00
										 |  |  |                     fun(column, subitem) | 
					
						
							| 
									
										
										
										
											2010-10-19 01:21:10 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         def add_to_columns(col, val): | 
					
						
							|  |  |  |             columns[col] = True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def add_to_row(col, val): | 
					
						
							| 
									
										
										
										
											2010-12-22 00:10:38 +08:00
										 |  |  |             if col in column_ix: | 
					
						
							| 
									
										
										
										
											2011-03-15 01:12:09 +08:00
										 |  |  |                 row[column_ix[col]] = unicode(val) | 
					
						
							| 
									
										
										
										
											2010-12-22 00:10:38 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if len(self.columns) == 0: | 
					
						
							|  |  |  |             for item in items: | 
					
						
							|  |  |  |                 add('', 1, item, add_to_columns) | 
					
						
							|  |  |  |             columns = columns.keys() | 
					
						
							|  |  |  |             columns.sort(key=column_sort_key) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             columns = self.columns | 
					
						
							| 
									
										
										
										
											2010-10-19 01:21:10 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         for i in xrange(0, len(columns)): | 
					
						
							|  |  |  |             column_ix[columns[i]] = i | 
					
						
							|  |  |  |         for item in items: | 
					
						
							|  |  |  |             row = len(columns) * [''] | 
					
						
							|  |  |  |             add('', 1, item, add_to_row) | 
					
						
							|  |  |  |             table.append(row) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return (columns, table) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TSVList(Lister): | 
					
						
							| 
									
										
										
										
											2010-12-22 00:10:38 +08:00
										 |  |  |     def __init__(self, columns, options): | 
					
						
							|  |  |  |         self.columns = columns | 
					
						
							| 
									
										
										
										
											2010-10-19 01:21:10 +08:00
										 |  |  |         self.options = options | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def display_list(self, columns, table): | 
					
						
							|  |  |  |         head = "" | 
					
						
							|  |  |  |         for col in columns: | 
					
						
							|  |  |  |             head += col + "\t" | 
					
						
							|  |  |  |         self.verbose(head) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for row in table: | 
					
						
							| 
									
										
										
										
											2010-10-19 19:17:02 +08:00
										 |  |  |             line = "" | 
					
						
							| 
									
										
										
										
											2010-10-19 01:21:10 +08:00
										 |  |  |             for cell in row: | 
					
						
							| 
									
										
										
										
											2010-10-19 19:17:02 +08:00
										 |  |  |                 line += cell + "\t" | 
					
						
							| 
									
										
										
										
											2011-03-15 18:29:34 +08:00
										 |  |  |             output(line) | 
					
						
							| 
									
										
										
										
											2010-10-19 01:21:10 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | class LongList(Lister): | 
					
						
							| 
									
										
										
										
											2010-12-22 00:10:38 +08:00
										 |  |  |     def __init__(self, columns, options): | 
					
						
							|  |  |  |         self.columns = columns | 
					
						
							| 
									
										
										
										
											2010-10-19 01:21:10 +08:00
										 |  |  |         self.options = options | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def display_list(self, columns, table): | 
					
						
							|  |  |  |         sep = "\n" + "-" * 80 + "\n" | 
					
						
							|  |  |  |         max_width = 0 | 
					
						
							|  |  |  |         for col in columns: | 
					
						
							|  |  |  |             max_width = max(max_width, len(col)) | 
					
						
							| 
									
										
										
										
											2011-03-15 01:12:09 +08:00
										 |  |  |         fmt = "{0:>" + unicode(max_width) + "}: {1}" | 
					
						
							| 
									
										
										
										
											2011-03-15 18:29:34 +08:00
										 |  |  |         output(sep) | 
					
						
							| 
									
										
										
										
											2010-10-19 01:21:10 +08:00
										 |  |  |         for i in xrange(0, len(table)): | 
					
						
							|  |  |  |             for j in xrange(0, len(columns)): | 
					
						
							| 
									
										
										
										
											2011-03-15 18:29:34 +08:00
										 |  |  |                 output(fmt.format(columns[j], table[i][j])) | 
					
						
							|  |  |  |             output(sep) | 
					
						
							| 
									
										
										
										
											2010-10-19 01:21:10 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | class TableList(Lister): | 
					
						
							| 
									
										
										
										
											2010-12-22 00:10:38 +08:00
										 |  |  |     def __init__(self, columns, options): | 
					
						
							|  |  |  |         self.columns = columns | 
					
						
							| 
									
										
										
										
											2010-10-19 01:21:10 +08:00
										 |  |  |         self.options = options | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def display_list(self, columns, table): | 
					
						
							|  |  |  |         total = [columns] | 
					
						
							|  |  |  |         total.extend(table) | 
					
						
							|  |  |  |         self.ascii_table(total) | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def ascii_table(self, rows): | 
					
						
							|  |  |  |         table = "" | 
					
						
							|  |  |  |         col_widths = [0] * len(rows[0]) | 
					
						
							|  |  |  |         for i in xrange(0, len(rows[0])): | 
					
						
							|  |  |  |             for j in xrange(0, len(rows)): | 
					
						
							|  |  |  |                 col_widths[i] = max(col_widths[i], len(rows[j][i])) | 
					
						
							|  |  |  |         self.ascii_bar(col_widths) | 
					
						
							|  |  |  |         self.ascii_row(col_widths, rows[0], "^") | 
					
						
							|  |  |  |         self.ascii_bar(col_widths) | 
					
						
							|  |  |  |         for row in rows[1:]: | 
					
						
							|  |  |  |             self.ascii_row(col_widths, row, "<") | 
					
						
							|  |  |  |         self.ascii_bar(col_widths) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def ascii_row(self, col_widths, row, align): | 
					
						
							|  |  |  |         txt = "|" | 
					
						
							|  |  |  |         for i in xrange(0, len(col_widths)): | 
					
						
							| 
									
										
										
										
											2011-03-15 01:12:09 +08:00
										 |  |  |             fmt = " {0:" + align + unicode(col_widths[i]) + "} " | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  |             txt += fmt.format(row[i]) + "|" | 
					
						
							| 
									
										
										
										
											2011-03-15 18:29:34 +08:00
										 |  |  |         output(txt) | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def ascii_bar(self, col_widths): | 
					
						
							|  |  |  |         txt = "+" | 
					
						
							|  |  |  |         for w in col_widths: | 
					
						
							|  |  |  |             txt += ("-" * (w + 2)) + "+" | 
					
						
							| 
									
										
										
										
											2011-03-15 18:29:34 +08:00
										 |  |  |         output(txt) | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-09 18:55:04 +08:00
										 |  |  | class KeyValueList(Lister): | 
					
						
							| 
									
										
										
										
											2010-12-22 00:10:38 +08:00
										 |  |  |     def __init__(self, columns, options): | 
					
						
							|  |  |  |         self.columns = columns | 
					
						
							| 
									
										
										
										
											2010-11-09 18:55:04 +08:00
										 |  |  |         self.options = options | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def display_list(self, columns, table): | 
					
						
							|  |  |  |         for i in xrange(0, len(table)): | 
					
						
							|  |  |  |             row = [] | 
					
						
							|  |  |  |             for j in xrange(0, len(columns)): | 
					
						
							|  |  |  |                 row.append("{0}=\"{1}\"".format(columns[j], table[i][j])) | 
					
						
							| 
									
										
										
										
											2011-03-15 18:29:34 +08:00
										 |  |  |             output(" ".join(row)) | 
					
						
							| 
									
										
										
										
											2010-11-09 18:55:04 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-17 18:17:39 +08:00
										 |  |  | # TODO handle spaces etc in completable names | 
					
						
							|  |  |  | class BashList(Lister): | 
					
						
							| 
									
										
										
										
											2010-12-22 00:10:38 +08:00
										 |  |  |     def __init__(self, columns, options): | 
					
						
							|  |  |  |         self.columns = columns | 
					
						
							| 
									
										
										
										
											2010-11-17 18:17:39 +08:00
										 |  |  |         self.options = options | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def display_list(self, columns, table): | 
					
						
							|  |  |  |         ix = None | 
					
						
							|  |  |  |         for i in xrange(0, len(columns)): | 
					
						
							|  |  |  |             if columns[i] == 'name': | 
					
						
							|  |  |  |                 ix = i | 
					
						
							|  |  |  |         if ix is not None: | 
					
						
							|  |  |  |             res = [] | 
					
						
							|  |  |  |             for row in table: | 
					
						
							|  |  |  |                 res.append(row[ix]) | 
					
						
							| 
									
										
										
										
											2011-03-15 18:29:34 +08:00
										 |  |  |             output(" ".join(res)) | 
					
						
							| 
									
										
										
										
											2010-11-17 18:17:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | FORMATS = { | 
					
						
							|  |  |  |     'raw_json'    : None, # Special cased | 
					
						
							|  |  |  |     'pretty_json' : None, # Ditto | 
					
						
							|  |  |  |     'tsv'         : TSVList, | 
					
						
							|  |  |  |     'long'        : LongList, | 
					
						
							|  |  |  |     'table'       : TableList, | 
					
						
							|  |  |  |     'kvp'         : KeyValueList, | 
					
						
							|  |  |  |     'bash'        : BashList | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-10 22:58:02 +08:00
										 |  |  | def write_payload_file(payload_file, json_list): | 
					
						
							|  |  |  |     result = json.loads(json_list)[0] | 
					
						
							|  |  |  |     payload = result['payload'] | 
					
						
							|  |  |  |     payload_encoding = result['payload_encoding'] | 
					
						
							|  |  |  |     with open(payload_file, 'w') as f: | 
					
						
							|  |  |  |         if payload_encoding == 'base64': | 
					
						
							|  |  |  |             data = base64.b64decode(payload) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             data = payload | 
					
						
							|  |  |  |         f.write(data) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-17 18:17:39 +08:00
										 |  |  | def print_bash_completion(): | 
					
						
							|  |  |  |     script = """# This is a bash completion script for rabbitmqadmin. | 
					
						
							|  |  |  | # Redirect it to a file, then source it or copy it to /etc/bash_completion.d | 
					
						
							|  |  |  | # to get tab completion. rabbitmqadmin must be on your PATH for this to work. | 
					
						
							|  |  |  | _rabbitmqadmin() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     local cur prev opts base | 
					
						
							|  |  |  |     COMPREPLY=() | 
					
						
							|  |  |  |     cur="${COMP_WORDS[COMP_CWORD]}" | 
					
						
							|  |  |  |     prev="${COMP_WORDS[COMP_CWORD-1]}" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-26 01:00:13 +08:00
										 |  |  |     opts="list show declare delete close purge import export get publish" | 
					
						
							| 
									
										
										
										
											2010-11-17 18:17:39 +08:00
										 |  |  |     fargs="--help --host --port --vhost --username --password --format --depth" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case "${prev}" in | 
					
						
							|  |  |  | 	list) | 
					
						
							|  |  |  | 	    COMPREPLY=( $(compgen -W '""" + " ".join(LISTABLE) + """' -- ${cur}) ) | 
					
						
							|  |  |  |             return 0 | 
					
						
							|  |  |  |             ;; | 
					
						
							| 
									
										
										
										
											2011-01-03 21:20:13 +08:00
										 |  |  | 	show) | 
					
						
							|  |  |  | 	    COMPREPLY=( $(compgen -W '""" + " ".join(SHOWABLE) + """' -- ${cur}) ) | 
					
						
							|  |  |  |             return 0 | 
					
						
							|  |  |  |             ;; | 
					
						
							| 
									
										
										
										
											2010-11-17 18:17:39 +08:00
										 |  |  | 	declare) | 
					
						
							|  |  |  | 	    COMPREPLY=( $(compgen -W '""" + " ".join(DECLARABLE.keys()) + """' -- ${cur}) ) | 
					
						
							|  |  |  |             return 0 | 
					
						
							|  |  |  |             ;; | 
					
						
							|  |  |  | 	delete) | 
					
						
							|  |  |  | 	    COMPREPLY=( $(compgen -W '""" + " ".join(DELETABLE.keys()) + """' -- ${cur}) ) | 
					
						
							|  |  |  |             return 0 | 
					
						
							|  |  |  |             ;; | 
					
						
							|  |  |  | 	close) | 
					
						
							|  |  |  | 	    COMPREPLY=( $(compgen -W '""" + " ".join(CLOSABLE.keys()) + """' -- ${cur}) ) | 
					
						
							|  |  |  |             return 0 | 
					
						
							|  |  |  |             ;; | 
					
						
							|  |  |  | 	purge) | 
					
						
							|  |  |  | 	    COMPREPLY=( $(compgen -W '""" + " ".join(PURGABLE.keys()) + """' -- ${cur}) ) | 
					
						
							|  |  |  |             return 0 | 
					
						
							|  |  |  |             ;; | 
					
						
							|  |  |  | 	export) | 
					
						
							|  |  |  | 	    COMPREPLY=( $(compgen -f ${cur}) ) | 
					
						
							|  |  |  |             return 0 | 
					
						
							|  |  |  |             ;; | 
					
						
							|  |  |  | 	import) | 
					
						
							|  |  |  | 	    COMPREPLY=( $(compgen -f ${cur}) ) | 
					
						
							|  |  |  |             return 0 | 
					
						
							|  |  |  |             ;; | 
					
						
							| 
									
										
										
										
											2011-05-10 18:22:06 +08:00
										 |  |  | 	-@(H|-host)) | 
					
						
							| 
									
										
										
										
											2010-11-17 18:17:39 +08:00
										 |  |  | 	    COMPREPLY=( $(compgen -A hostname ${cur}) ) | 
					
						
							|  |  |  |             return 0 | 
					
						
							|  |  |  |             ;; | 
					
						
							| 
									
										
										
										
											2011-05-10 18:22:06 +08:00
										 |  |  | 	-@(V|-vhost)) | 
					
						
							| 
									
										
										
										
											2010-11-17 18:17:39 +08:00
										 |  |  |             opts="$(rabbitmqadmin -q -f bash list vhosts)" | 
					
						
							|  |  |  | 	    COMPREPLY=( $(compgen -W "${opts}"  -- ${cur}) ) | 
					
						
							|  |  |  |             return 0 | 
					
						
							|  |  |  |             ;; | 
					
						
							| 
									
										
										
										
											2011-05-10 18:22:06 +08:00
										 |  |  | 	-@(u|-username)) | 
					
						
							| 
									
										
										
										
											2010-11-17 18:17:39 +08:00
										 |  |  |             opts="$(rabbitmqadmin -q -f bash list users)" | 
					
						
							|  |  |  | 	    COMPREPLY=( $(compgen -W "${opts}"  -- ${cur}) ) | 
					
						
							|  |  |  |             return 0 | 
					
						
							|  |  |  |             ;; | 
					
						
							| 
									
										
										
										
											2011-05-10 18:22:06 +08:00
										 |  |  | 	-@(f|-format)) | 
					
						
							| 
									
										
										
										
											2010-11-17 18:17:39 +08:00
										 |  |  | 	    COMPREPLY=( $(compgen -W \"""" + " ".join(FORMATS.keys()) + """\"  -- ${cur}) ) | 
					
						
							|  |  |  |             return 0 | 
					
						
							|  |  |  |             ;; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | """ | 
					
						
							|  |  |  |     for l in LISTABLE: | 
					
						
							|  |  |  |         key = l[0:len(l) - 1] | 
					
						
							|  |  |  |         script += "        " + key + """) | 
					
						
							|  |  |  |             opts="$(rabbitmqadmin -q -f bash list """ + l + """)" | 
					
						
							|  |  |  | 	    COMPREPLY=( $(compgen -W "${opts}"  -- ${cur}) ) | 
					
						
							|  |  |  |             return 0 | 
					
						
							|  |  |  |             ;; | 
					
						
							|  |  |  | """ | 
					
						
							|  |  |  |     script += """        *) | 
					
						
							|  |  |  |         ;; | 
					
						
							|  |  |  |     esac | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    COMPREPLY=($(compgen -W "${opts} ${fargs}" -- ${cur})) | 
					
						
							|  |  |  |    return 0 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | complete -F _rabbitmqadmin rabbitmqadmin | 
					
						
							|  |  |  | """ | 
					
						
							| 
									
										
										
										
											2011-03-15 18:29:34 +08:00
										 |  |  |     output(script) | 
					
						
							| 
									
										
										
										
											2010-11-09 18:55:04 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-13 00:56:45 +08:00
										 |  |  | if __name__ == "__main__": | 
					
						
							|  |  |  |     main() |