#!/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] [arg1=value arg2=value] `stack help` should output the list of available controllers `stack ` should output the available methods for that controller `stack help ` should do the same `stack help ` 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))