Skip to content
This repository was archived by the owner on Apr 25, 2019. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 25 additions & 10 deletions cloudstack/compute/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
import urllib
import sys


def valid_methods():
return [r['name'] for r in API_REFS]


class Method(object):

def __init__(self, command, method_name):
self.command = command
self.method_name = method_name
Expand All @@ -25,30 +28,42 @@ def __call__(self, **kwargs):
print '[%s] option is required.' % ', '.join(list(missing))
return

params = dict([(k,v) for (k,v) in kwargs.items()
for opt in options
if opt['option'][2:] == k])
params = dict([(k, v) for (k, v) in kwargs.items()
for opt in options
if opt['option'][2:] == k])

json = client.connect(host=self.command.host,api_key=self.command.api_key,
secret_key=self.command.secret_key,debug=self.command.debug
).get(self.method_name,params)
json = client.connect(
host=self.command.host,
api_key=self.command.api_key,
secret_key=self.command.secret_key,
debug=self.command.debug).get(
self.method_name,
params)
if json:
retval = dict2obj(json[json.keys()[0]])
if retval and hasattr(retval,'list'):
if retval and hasattr(retval, 'list'):
return retval.list
else:
return retval


class Compute(object):
def __init__(self,host=None,api_key=None,secret_key=None,api_refs_json=None,debug=False):

def __init__(
self,
host=None,
api_key=None,
secret_key=None,
api_refs_json=None,
debug=False):
self.host = host
self.api_key = api_key
self.secret_key = secret_key
self.api_refs_json = api_refs_json
self.debug = debug

def __getattr__(self,method_name):
return Method(self,method_name)
def __getattr__(self, method_name):
return Method(self, method_name)

def methods(self):
return valid_methods()
23 changes: 12 additions & 11 deletions cloudstack/compute/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@
from cloudstack.utils import safe_option
from stack import Stack

API_CONF_PATH = os.path.join(os.path.expanduser("~"),".idcfrc")
API_CONF_PATH = os.path.join(os.path.expanduser("~"), ".idcfrc")
logging.basicConfig(format="%(asctime)s %(module)s[%(lineno)d] [%(levelname)s]: %(message)s",
#filename = "log.txt",
level=logging.INFO)

def connect(host=None,api_key=None,secret_key=None,debug=False):

def connect(host=None, api_key=None, secret_key=None, debug=False):
if debug:
httplib2.debuglevel = 1
logging.getLogger().setLevel(logging.DEBUG)
Expand All @@ -32,27 +33,27 @@ def connect(host=None,api_key=None,secret_key=None,debug=False):
if not host:
host = os.environ.get('IDCF_COMPUTE_HOST')
if not host:
host = safe_option(config,"account", "host")
host = safe_option(config, "account", "host")
if not api_key:
api_key = os.environ.get('IDCF_COMPUTE_API_KEY')
if not api_key:
api_key = safe_option(config,"account", "api_key")
api_key = safe_option(config, "account", "api_key")
if not secret_key:
secret_key = os.environ.get('IDCF_COMPUTE_SECRET_KEY')
if not secret_key:
secret_key = safe_option(config,"account","secret_key")
secret_key = safe_option(config, "account", "secret_key")

except ConfigParser.NoSectionError, e:
except ConfigParser.NoSectionError as e:
print >> sys.stderr, e.message
#f = open(API_CONF_PATH,"w")
#config.add_section("account")
# config.add_section("account")
#config.set("account", "host","http://xxx")
#config.set("account", "api_key","xxx")
#config.set("account","secret_key","xxx")
#config.write(f)
# config.set("account","secret_key","xxx")
# config.write(f)
sys.exit(1)

except Exception, e:
except Exception as e:
print >> sys.stderr, e
sys.exit(1)
return Stack(http,host,api_key,secret_key)
return Stack(http, host, api_key, secret_key)
117 changes: 71 additions & 46 deletions cloudstack/compute/shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,18 @@
api_refs_json_path = os.environ.get('IDCF_COMPUTE_API_REFS_JSON')
if not api_refs_json_path:
api_refs_json_path = config.get("account", "api_refs_json")
api_refs = simplejson.load(open(api_refs_json_path,"r"))
api_refs = simplejson.load(open(api_refs_json_path, "r"))
except:
api_refs_json = resource_string('cloudstack.compute', 'apirefs.json')
api_refs = simplejson.loads(api_refs_json)

API_REFS = api_refs


class ShellCommand(object):
"""コマンドのベースクラス
"""

def options(self):
return list()

Expand All @@ -51,24 +53,32 @@ def execute(self, args):
csv_fields = d.pop("csv")
no_headers = d.pop("noheaders")

for k,v in d.items():
for k, v in d.items():
if v is None:
del(d[k])

retval = client.connect().get(command.__name__,d)
retval = client.connect().get(command.__name__, d)

return retval, fields, xml, csv_fields, no_headers

def arg(*args,**kw):

def arg(*args, **kw):
return (args, kw)


class IdcfShell(object):

def __init__(self):
self.arg_parser = argparse.ArgumentParser(
prog = 'cloudstack-api',
prog='cloudstack-api',
#usage='%(prog)s [-h]',
)
self.arg_parser.add_argument('-v','--version', action='version', version="%(prog)s v"+VERSION)
)
self.arg_parser.add_argument(
'-v',
'--version',
action='version',
version="%(prog)s v" +
VERSION)
self.register_commands()

def register_commands(self):
Expand All @@ -89,40 +99,46 @@ def create_commands(self):
commands = []
for index, desc in enumerate(API_REFS):
key = desc["name"]
command = type(key.encode("utf-8"),(ShellCommand,),{"__doc__":desc["help"].encode("utf-8"), "index":index})
command = type(key.encode("utf-8"), (ShellCommand,),
{"__doc__": desc["help"].encode("utf-8"), "index": index})

def options(self):
def opt_required(required):
if required == "true":
return True
else:
return False
retval = [arg(opt["option"],required=opt_required(opt["required"]),
help=opt["help"].encode("utf-8"))
for opt in API_REFS[self.index]["options"]]

retval.append(arg("-t","--table",help="displaying tabular format",
nargs="?", const="*"))
retval.append(arg("-x","--xml",help="displaying xml format",
retval = [arg(opt["option"], required=opt_required(opt["required"]),
help=opt["help"].encode("utf-8"))
for opt in API_REFS[self.index]["options"]]

retval.append(arg("-t",
"--table",
help="displaying tabular format",
nargs="?",
const="*"))
retval.append(arg("-x", "--xml", help="displaying xml format",
nargs="?", const="*"))
retval.append(arg("-c","--csv",help="displaying csv format",
retval.append(arg("-c", "--csv", help="displaying csv format",
nargs="?", const="*"))
retval.append(arg("--noheaders",help="suppress csv header",
retval.append(arg("--noheaders", help="suppress csv header",
action="store_true"))
return retval
setattr(command,"options",options)
setattr(command, "options", options)
commands.append(command)
return commands

def execute(self,raw_args,shell=False):
def execute(self, raw_args, shell=False):
args = self.arg_parser.parse_args(raw_args)
command = args.command_class()
retval,fields,xml,csv_fields,no_headers = command.execute(args)
retval, fields, xml, csv_fields, no_headers = command.execute(args)
if shell:
print_pretty(retval,fields,xml,csv_fields,no_headers)
print_pretty(retval, fields, xml, csv_fields, no_headers)
else:
return retval

def print_pretty(retval,fields,xml,csv_fields,no_headers):

def print_pretty(retval, fields, xml, csv_fields, no_headers):
if not retval:
return
elif xml:
Expand All @@ -131,53 +147,57 @@ def print_pretty(retval,fields,xml,csv_fields,no_headers):
res = retval.get(retval.keys()[0])
count = res.get("count")
if not count:
return print_dict(res,fields)
return print_dict(res, fields)
else:
res.pop("count")
return print_list(res,fields)
return print_list(res, fields)
elif csv_fields:
res = retval.get(retval.keys()[0])
count = res.get("count")
if not count:
return print_dict_csv(res,csv_fields,no_headers)
return print_dict_csv(res, csv_fields, no_headers)
else:
res.pop("count")
return print_list_csv(res,csv_fields,no_headers)
return print_list_csv(res, csv_fields, no_headers)
else:
return print_json(retval)


def print_xml(xml):
root = etree.XML(xml)
print etree.tostring(root,xml_declaration=True,
pretty_print=True,encoding='utf-8')
print etree.tostring(root, xml_declaration=True,
pretty_print=True, encoding='utf-8')


def print_json(json):
print simplejson.dumps(json,sort_keys=True, indent=2)
print simplejson.dumps(json, sort_keys=True, indent=2)


def get_csv_writer():
data = StringIO.StringIO()
writer = csv.writer(data,quoting=csv.QUOTE_NONNUMERIC)
return data,writer
writer = csv.writer(data, quoting=csv.QUOTE_NONNUMERIC)
return data, writer


def print_dict_csv(obj,fields,no_headers):
def print_dict_csv(obj, fields, no_headers):
if not obj:
print "no data found"
else:
headers = get_headers(fields)
if not headers:
headers = obj.keys()
data,writer = get_csv_writer()

data, writer = get_csv_writer()
if not no_headers:
writer.writerow(headers)
writer.writerow([obj.get(k) for k in headers])
print data.getvalue()

def print_list_csv(res,fields,no_headers):

def print_list_csv(res, fields, no_headers):
rows_key = res.keys()[0]
rows = res.get(rows_key)
for i,obj in enumerate(rows):
for i, obj in enumerate(rows):
if i < 1:
if fields:
headers = get_headers(fields)
Expand All @@ -186,39 +206,43 @@ def print_list_csv(res,fields,no_headers):
else:
headers = or_keys(rows)

data,writer = get_csv_writer()
data, writer = get_csv_writer()
if not no_headers:
writer.writerow(headers)
writer.writerow([obj.get(k) for k in headers])
print data.getvalue()


def get_headers(fields):
fields_list = [ f.strip() for f in fields.split(',')]
fields_list = [f.strip() for f in fields.split(',')]
if fields_list[0] == '*' and len(fields_list) == 1:
fields_list = []
fields_list = []
return fields_list


def or_keys(rows):
set_keys = set([])
for obj in rows:
set_keys |= set(obj.keys())
return sorted(list(set_keys))

def print_dict(obj,fields):

def print_dict(obj, fields):
if not obj:
print "no data found"
else:
headers = get_headers(fields)
if not headers:
headers = sorted(obj.keys())
pt = PrettyTable(headers)
pt.add_row( [obj.get(k) for k in headers])
pt.add_row([obj.get(k) for k in headers])
pt.printt(sortby=headers[0])

def print_list(res,fields):

def print_list(res, fields):
rows_key = res.keys()[0]
rows = res.get(rows_key)
for i,obj in enumerate(rows):
for i, obj in enumerate(rows):
if i < 1:
if fields:
headers = get_headers(fields)
Expand All @@ -228,10 +252,11 @@ def print_list(res,fields):
headers = or_keys(rows)

pt = PrettyTable(headers)
[pt.set_field_align("%s"%h,"l") for h in headers]
pt.add_row( [obj.get(k) for k in headers])
[pt.set_field_align("%s" % h, "l") for h in headers]
pt.add_row([obj.get(k) for k in headers])

pt.printt(sortby=headers[0])


def main():
IdcfShell().execute(sys.argv[1:],True)
IdcfShell().execute(sys.argv[1:], True)
Loading