2f70137a1b
Swap the URLError and HTTPError exception handlers. HTTPError is a subclass of URLError, so the HTTPError handler wasn't being reached. Change-Id: Iec86d2b345dbd37858af888bbd54a74884025eda
163 lines
4.9 KiB
Python
Executable File
163 lines
4.9 KiB
Python
Executable File
#!/usr/bin/env python
|
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
|
|
# Copyright 2010 United States Government as represented by the
|
|
# Administrator of the National Aeronautics and Space Administration.
|
|
# All Rights Reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
"""CLI for the Direct API."""
|
|
|
|
import eventlet
|
|
eventlet.monkey_patch()
|
|
|
|
import json
|
|
import os
|
|
import pprint
|
|
import sys
|
|
import textwrap
|
|
import urllib
|
|
import urllib2
|
|
|
|
# If ../nova/__init__.py exists, add ../ to Python search path, so that
|
|
# it will override what happens to be installed in /usr/(local/)lib/python...
|
|
possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
|
|
os.pardir,
|
|
os.pardir))
|
|
if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
|
|
sys.path.insert(0, possible_topdir)
|
|
|
|
import gflags
|
|
|
|
|
|
FLAGS = gflags.FLAGS
|
|
gflags.DEFINE_string('host', '127.0.0.1', 'Direct API host')
|
|
gflags.DEFINE_integer('port', 8001, 'Direct API host')
|
|
gflags.DEFINE_string('user', 'user1', 'Direct API username')
|
|
gflags.DEFINE_string('project', 'proj1', 'Direct API project')
|
|
|
|
|
|
USAGE = """usage: stack [options] <controller> <method> [arg1=value arg2=value]
|
|
|
|
`stack help` should output the list of available controllers
|
|
`stack <controller>` should output the available methods for that controller
|
|
`stack help <controller>` should do the same
|
|
`stack help <controller> <method>` should output info for a method
|
|
"""
|
|
|
|
|
|
def format_help(d):
|
|
"""Format help text, keys are labels and values are descriptions."""
|
|
MAX_INDENT = 30
|
|
indent = max([len(k) for k in d])
|
|
if indent > MAX_INDENT:
|
|
indent = MAX_INDENT - 6
|
|
|
|
out = []
|
|
for k, v in sorted(d.iteritems()):
|
|
if (len(k) + 6) > MAX_INDENT:
|
|
out.extend([' %s' % k])
|
|
initial_indent = ' ' * (indent + 6)
|
|
else:
|
|
initial_indent = ' %s ' % k.ljust(indent)
|
|
subsequent_indent = ' ' * (indent + 6)
|
|
t = textwrap.TextWrapper(initial_indent=initial_indent,
|
|
subsequent_indent=subsequent_indent)
|
|
out.extend(t.wrap(v))
|
|
return out
|
|
|
|
|
|
def help_all():
|
|
rv = do_request('reflect', 'get_controllers')
|
|
out = format_help(rv)
|
|
return (USAGE + str(FLAGS.MainModuleHelp()) +
|
|
'\n\nAvailable controllers:\n' +
|
|
'\n'.join(out) + '\n')
|
|
|
|
|
|
def help_controller(controller):
|
|
rv = do_request('reflect', 'get_methods')
|
|
methods = dict([(k.split('/')[2], v) for k, v in rv.iteritems()
|
|
if k.startswith('/%s' % controller)])
|
|
return ('Available methods for %s:\n' % controller +
|
|
'\n'.join(format_help(methods)))
|
|
|
|
|
|
def help_method(controller, method):
|
|
rv = do_request('reflect',
|
|
'get_method_info',
|
|
{'method': '/%s/%s' % (controller, method)})
|
|
|
|
sig = '%s(%s):' % (method, ', '.join(['='.join(x) for x in rv['args']]))
|
|
out = textwrap.wrap(sig, subsequent_indent=' ' * len('%s(' % method))
|
|
out.append('\n' + rv['doc'])
|
|
return '\n'.join(out)
|
|
|
|
|
|
def do_request(controller, method, params=None):
|
|
if params:
|
|
data = urllib.urlencode(params)
|
|
else:
|
|
data = None
|
|
|
|
url = 'http://%s:%s/%s/%s' % (FLAGS.host, FLAGS.port, controller, method)
|
|
headers = {'X-OpenStack-User': FLAGS.user,
|
|
'X-OpenStack-Project': FLAGS.project}
|
|
|
|
req = urllib2.Request(url, data, headers)
|
|
try:
|
|
resp = urllib2.urlopen(req)
|
|
except urllib2.HTTPError, e:
|
|
print e.read()
|
|
sys.exit(1)
|
|
except urllib2.URLError, e:
|
|
print 'Failed to connect to %s: %s' % (url, e.reason)
|
|
sys.exit(1)
|
|
return json.loads(resp.read())
|
|
|
|
|
|
if __name__ == '__main__':
|
|
args = FLAGS(sys.argv)
|
|
|
|
cmd = args.pop(0)
|
|
if not args:
|
|
print help_all()
|
|
sys.exit()
|
|
|
|
first = args.pop(0)
|
|
if first == 'help':
|
|
action = help_all
|
|
params = []
|
|
if args:
|
|
params.append(args.pop(0))
|
|
action = help_controller
|
|
if args:
|
|
params.append(args.pop(0))
|
|
action = help_method
|
|
print action(*params)
|
|
sys.exit(0)
|
|
|
|
controller = first
|
|
if not args:
|
|
print help_controller(controller)
|
|
sys.exit()
|
|
|
|
method = args.pop(0)
|
|
params = {}
|
|
for x in args:
|
|
key, value = x.split('=', 1)
|
|
params[key] = value
|
|
|
|
pprint.pprint(do_request(controller, method, params))
|