~justin-fathomdb/nova/bug744150

« back to all changes in this revision

Viewing changes to bin/stack

  • Committer: Andy Smith
  • Date: 2011-01-18 23:51:13 UTC
  • mfrom: (579 nova)
  • mto: This revision was merged to the branch mainline in revision 581.
  • Revision ID: code@term.ie-20110118235113-ivu21efg3h9z6niq
merge from upstream and fix small issues

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
# vim: tabstop=4 shiftwidth=4 softtabstop=4
 
3
 
 
4
# Copyright 2010 United States Government as represented by the
 
5
# Administrator of the National Aeronautics and Space Administration.
 
6
# All Rights Reserved.
 
7
#
 
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
 
11
#
 
12
#         http://www.apache.org/licenses/LICENSE-2.0
 
13
#
 
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
 
18
#    under the License.
 
19
 
 
20
"""CLI for the Direct API."""
 
21
 
 
22
import eventlet
 
23
eventlet.monkey_patch()
 
24
 
 
25
import os
 
26
import pprint
 
27
import sys
 
28
import textwrap
 
29
import urllib
 
30
import urllib2
 
31
 
 
32
# If ../nova/__init__.py exists, add ../ to Python search path, so that
 
33
# it will override what happens to be installed in /usr/(local/)lib/python...
 
34
possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
 
35
                                   os.pardir,
 
36
                                   os.pardir))
 
37
if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
 
38
    sys.path.insert(0, possible_topdir)
 
39
 
 
40
import gflags
 
41
from nova import utils
 
42
 
 
43
 
 
44
FLAGS = gflags.FLAGS
 
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')
 
49
 
 
50
 
 
51
USAGE = """usage: stack [options] <controller> <method> [arg1=value arg2=value]
 
52
 
 
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
 
57
"""
 
58
 
 
59
 
 
60
def format_help(d):
 
61
    """Format help text, keys are labels and values are descriptions."""
 
62
    indent = max([len(k) for k in d])
 
63
    out = []
 
64
    for k, v in d.iteritems():
 
65
        t = textwrap.TextWrapper(initial_indent='   %s   ' % k.ljust(indent),
 
66
                                 subsequent_indent=' ' * (indent + 6))
 
67
        out.extend(t.wrap(v))
 
68
    return out
 
69
 
 
70
 
 
71
def help_all():
 
72
    rv = do_request('reflect', 'get_controllers')
 
73
    out = format_help(rv)
 
74
    return (USAGE + str(FLAGS.MainModuleHelp()) +
 
75
            '\n\nAvailable controllers:\n' +
 
76
            '\n'.join(out) + '\n')
 
77
 
 
78
 
 
79
def help_controller(controller):
 
80
    rv = do_request('reflect', 'get_methods')
 
81
    methods = dict([(k.split('/')[2], v) for k, v in rv.iteritems()
 
82
               if k.startswith('/%s' % controller)])
 
83
    return ('Available methods for %s:\n' % controller +
 
84
            '\n'.join(format_help(methods)))
 
85
 
 
86
 
 
87
def help_method(controller, method):
 
88
    rv = do_request('reflect',
 
89
                    'get_method_info',
 
90
                    {'method': '/%s/%s' % (controller, method)})
 
91
 
 
92
    sig = '%s(%s):' % (method, ', '.join(['='.join(x) for x in rv['args']]))
 
93
    out = textwrap.wrap(sig, subsequent_indent=' ' * len('%s(' % method))
 
94
    out.append('\n' + rv['doc'])
 
95
    return '\n'.join(out)
 
96
 
 
97
 
 
98
def do_request(controller, method, params=None):
 
99
    if params:
 
100
        data = urllib.urlencode(params)
 
101
    else:
 
102
        data = None
 
103
 
 
104
    url = 'http://%s:%s/%s/%s' % (FLAGS.host, FLAGS.port, controller, method)
 
105
    headers = {'X-OpenStack-User': FLAGS.user,
 
106
               'X-OpenStack-Project': FLAGS.project}
 
107
 
 
108
    req = urllib2.Request(url, data, headers)
 
109
    resp = urllib2.urlopen(req)
 
110
    return utils.loads(resp.read())
 
111
 
 
112
 
 
113
if __name__ == '__main__':
 
114
    args = FLAGS(sys.argv)
 
115
 
 
116
    cmd = args.pop(0)
 
117
    if not args:
 
118
        print help_all()
 
119
        sys.exit()
 
120
 
 
121
    first = args.pop(0)
 
122
    if first == 'help':
 
123
        action = help_all
 
124
        params = []
 
125
        if args:
 
126
            params.append(args.pop(0))
 
127
            action = help_controller
 
128
        if args:
 
129
            params.append(args.pop(0))
 
130
            action = help_method
 
131
        print action(*params)
 
132
        sys.exit(0)
 
133
 
 
134
    controller = first
 
135
    if not args:
 
136
        print help_controller(controller)
 
137
        sys.exit()
 
138
 
 
139
    method = args.pop(0)
 
140
    params = {}
 
141
    for x in args:
 
142
        key, value = x.split('=', 1)
 
143
        params[key] = value
 
144
 
 
145
    pprint.pprint(do_request(controller, method, params))