2
# vim: tabstop=4 shiftwidth=4 softtabstop=4
4
# Copyright 2010 United States Government as represented by the
5
# Administrator of the National Aeronautics and Space Administration.
8
# Licensed under the Apache License, Version 2.0 (the "License"); you may
9
# not use this file except in compliance with the License. You may obtain
10
# a copy of the License at
12
# http://www.apache.org/licenses/LICENSE-2.0
14
# Unless required by applicable law or agreed to in writing, software
15
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
17
# License for the specific language governing permissions and limitations
20
"""CLI for the Direct API."""
23
eventlet.monkey_patch()
33
# If ../nova/__init__.py exists, add ../ to Python search path, so that
34
# it will override what happens to be installed in /usr/(local/)lib/python...
35
possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
38
if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
39
sys.path.insert(0, possible_topdir)
45
gflags.DEFINE_string('host', '127.0.0.1', 'Direct API host')
46
gflags.DEFINE_integer('port', 8001, 'Direct API host')
47
gflags.DEFINE_string('user', 'user1', 'Direct API username')
48
gflags.DEFINE_string('project', 'proj1', 'Direct API project')
51
USAGE = """usage: stack [options] <controller> <method> [arg1=value arg2=value]
53
`stack help` should output the list of available controllers
54
`stack <controller>` should output the available methods for that controller
55
`stack help <controller>` should do the same
56
`stack help <controller> <method>` should output info for a method
61
"""Format help text, keys are labels and values are descriptions."""
63
indent = max([len(k) for k in d])
64
if indent > MAX_INDENT:
65
indent = MAX_INDENT - 6
68
for k, v in sorted(d.iteritems()):
69
if (len(k) + 6) > MAX_INDENT:
70
out.extend([' %s' % k])
71
initial_indent = ' ' * (indent + 6)
73
initial_indent = ' %s ' % k.ljust(indent)
74
subsequent_indent = ' ' * (indent + 6)
75
t = textwrap.TextWrapper(initial_indent=initial_indent,
76
subsequent_indent=subsequent_indent)
82
rv = do_request('reflect', 'get_controllers')
84
return (USAGE + str(FLAGS.MainModuleHelp()) +
85
'\n\nAvailable controllers:\n' +
86
'\n'.join(out) + '\n')
89
def help_controller(controller):
90
rv = do_request('reflect', 'get_methods')
91
methods = dict([(k.split('/')[2], v) for k, v in rv.iteritems()
92
if k.startswith('/%s' % controller)])
93
return ('Available methods for %s:\n' % controller +
94
'\n'.join(format_help(methods)))
97
def help_method(controller, method):
98
rv = do_request('reflect',
100
{'method': '/%s/%s' % (controller, method)})
102
sig = '%s(%s):' % (method, ', '.join(['='.join(x) for x in rv['args']]))
103
out = textwrap.wrap(sig, subsequent_indent=' ' * len('%s(' % method))
104
out.append('\n' + rv['doc'])
105
return '\n'.join(out)
108
def do_request(controller, method, params=None):
110
data = urllib.urlencode(params)
114
url = 'http://%s:%s/%s/%s' % (FLAGS.host, FLAGS.port, controller, method)
115
headers = {'X-OpenStack-User': FLAGS.user,
116
'X-OpenStack-Project': FLAGS.project}
118
req = urllib2.Request(url, data, headers)
120
resp = urllib2.urlopen(req)
121
except urllib2.HTTPError, e:
124
return json.loads(resp.read())
127
if __name__ == '__main__':
128
args = FLAGS(sys.argv)
140
params.append(args.pop(0))
141
action = help_controller
143
params.append(args.pop(0))
145
print action(*params)
150
print help_controller(controller)
156
key, value = x.split('=', 1)
159
pprint.pprint(do_request(controller, method, params))