diff --git a/cloud-cli/cloudapis/amazon.py b/cloud-cli/cloudapis/amazon.py
deleted file mode 100644
index c6911d6ed2d..00000000000
--- a/cloud-cli/cloudapis/amazon.py
+++ /dev/null
@@ -1,63 +0,0 @@
-'''Implements the Amazon API'''
-
-
-import boto.ec2
-import os
-from cloudtool.utils import describe,OptionConflictError,OptionValueError
-raise ImportError
-
-class AmazonAPI:
-
- @describe("access_key", "Amazon access key")
- @describe("secret_key", "Amazon secret key")
- @describe("region", "Amazon region")
- @describe("endpoint", "Amazon endpoint")
- def __init__(self,
- access_key=os.environ.get("AWS_ACCESS_KEY_ID",None),
- secret_key=os.environ.get("AWS_SECRET_ACCESS_KEY",None),
- region=None,
- endpoint=None):
- if not access_key: raise OptionValueError,"you need to specify an access key"
- if not secret_key: raise OptionValueError,"you need to specify a secret key"
- if region and endpoint:
- raise OptionConflictError,("mutually exclusive with --endpoint",'--region')
- self.__dict__.update(locals())
-
- def _get_regions(self):
- return boto.ec2.regions(aws_access_key_id=self.access_key,aws_secret_access_key=self.secret_key)
-
- def _get_region(self,name):
- try: return [ x for x in self._get_regions() if x.name == name ][0]
- except IndexError: raise KeyError,name
-
- def _connect(self):
- if self.region:
- region = self._get_region(self.region)
- self.connection = region.connect(
- aws_access_key_id=self.access_key,
- aws_secret_access_key=self.secret_key
- )
- else:
- self.connection = boto.ec2.connection.EC2Connection(
- host=self.endpoint,
- aws_access_key_id=self.access_key,
- aws_secret_access_key=self.secret_key
- )
- def list_regions(self):
- """Lists all regions"""
- regions = self._get_regions()
- for r in regions: print r
-
- def get_all_images(self):
- """Lists all images"""
- self._connect()
- images = self.connection.get_all_images()
- for i in images: print i
-
- def get_region(self):
- """Gets the region you're connecting to"""
- self._connect()
- print self.connection.region
-
-
-implementor = AmazonAPI
\ No newline at end of file
diff --git a/cloud-cli/cloudapis/cloud.py b/cloud-cli/cloudapis/cloud.py
index 07276b4446e..be703dd16e9 100644
--- a/cloud-cli/cloudapis/cloud.py
+++ b/cloud-cli/cloudapis/cloud.py
@@ -58,26 +58,32 @@ def load_dynamic_methods():
name = getText(cmd.getElementsByTagName('name')[0].childNodes).strip()
assert name
- description = cmd.getElementsByTagName('name')[0].getAttribute("description")
- if description: description = '"""%s"""' % description
+ description = getText(cmd.getElementsByTagName('description')[0].childNodes).strip()
+ if description:
+ description = '"""%s"""' % description
else: description = ''
arguments = []
options = []
descriptions = []
- for param in cmd.getElementsByTagName('arg'):
- argname = getText(param.childNodes).strip()
+ for param in cmd.getElementsByTagName("request")[0].getElementsByTagName("arg"):
+ argname = getText(param.getElementsByTagName('name')[0].childNodes).strip()
assert argname
- required = param.getAttribute("required").strip()
+ required = getText(param.getElementsByTagName('required')[0].childNodes).strip()
if required == 'true': required = True
elif required == 'false': required = False
else: raise AssertionError, "Not reached"
if required: arguments.append(argname)
options.append(argname)
- description = param.getAttribute("description").strip()
- if description: descriptions.append( (argname,description) )
+ #import ipdb; ipdb.set_trace()
+ requestDescription = param.getElementsByTagName('description')
+ if requestDescription:
+ descriptionParam = getText(requestDescription[0].childNodes)
+ else:
+ descriptionParam = ''
+ if descriptionParam: descriptions.append( (argname,descriptionParam) )
funcparams = ["self"] + [ "%s=None"%o for o in options ]
funcparams = ", ".join(funcparams)
@@ -95,7 +101,7 @@ def load_dynamic_methods():
output = self._make_request("%s",parms)
return output
"""%(name,funcparams,description,arguments,name)
-
+
namespace = {}
exec code.strip() in namespace
@@ -106,7 +112,8 @@ def load_dynamic_methods():
yield (name,func)
-for name,meth in load_dynamic_methods(): setattr(CloudAPI,name,meth)
+for name,meth in load_dynamic_methods():
+ setattr(CloudAPI, name, meth)
implementor = CloudAPI
diff --git a/cloud-cli/cloudtool/__init__.py b/cloud-cli/cloudtool/__init__.py
index a1062ff529c..d1b41c8cc2c 100644
--- a/cloud-cli/cloudtool/__init__.py
+++ b/cloud-cli/cloudtool/__init__.py
@@ -11,25 +11,27 @@ import cloudtool.utils as utils
def main(argv=None):
+ #import ipdb; ipdb.set_trace()
if argv == None:
argv = sys.argv
- prelim_args = [ x for x in argv[1:] if not x.startswith('-') ]
+ prelim_args = [ x for x in argv[0:] if not x.startswith('-') ]
parser = utils.get_parser()
-
+
api = __import__("cloudapis")
apis = getattr(api, "implementor")
- if len(prelim_args) == 0:
- parser.error("you need to specify an API as the first argument\n\nSupported APIs:\n" + "\n".join(utils.get_api_list(apis)))
- elif len(prelim_args) == 1:
+ if len(prelim_args) == 1:
commandlist = utils.get_command_list(apis)
- parser.error("you need to specify a command name as the second argument\n\nCommands supported by the %s API:\n"%prelim_args[0] + "\n".join(commandlist))
+ parser.error("you need to specify a command name as the first argument\n\nCommands supported by the %s API:\n"%prelim_args[0] + "\n".join(commandlist))
command = utils.lookup_command_in_api(apis,prelim_args[1])
if not command: parser.error("command %r not supported by the %s API"%(prelim_args[1],prelim_args[0]))
+
+ argv = argv[1:]
+ if len(argv) == 1:
+ argv.append("--help")
parser = utils.get_parser(apis.__init__,command)
- argv = argv[1:]
opts,args,api_optionsdict,cmd_optionsdict = parser.parse_args(argv)
@@ -38,7 +40,7 @@ def main(argv=None):
except utils.OptParseError,e:
parser.error(str(e))
- command = utils.lookup_command_in_api(api,args[1])
+ command = utils.lookup_command_in_api(api,args[0])
# we now discard the first two arguments as those necessarily are the api and command names
args = args[2:]
diff --git a/cloud-cli/cloudtool/utils.py b/cloud-cli/cloudtool/utils.py
index 6c7456feb42..5762be64735 100644
--- a/cloud-cli/cloudtool/utils.py
+++ b/cloud-cli/cloudtool/utils.py
@@ -112,51 +112,18 @@ def get_parser(api_callable=None,cmd_callable=None): # this should probably be t
group = parser.add_option_group("General options")
group.add_option('-v', '--verbose', dest="verbose", help="Print extra output")
- # now we need to derive the short options. we initialize the known fixed longopts and shortopts
- longopts = [ '--verbose' ]
-
- # we add the known long options, sorted and grouped to guarantee a stable short opt set regardless of order
- if api_callable and api_options:
- longopts += sorted([ x[0][0] for x in api_options ])
- if cmd_callable and cmd_options:
- longopts += sorted([ x[0][0] for x in cmd_options ])
-
- # we use this function to derive a suitable short option and remember the already-used short options
- def derive_shortopt(longopt,usedopts):
- """longopt begins with a dash"""
- shortopt = None
- for x in xrange(2,10000):
- try: shortopt = "-" + longopt[x]
- except IndexError:
- shortopt = None
- break
- if shortopt in usedopts: continue
- usedopts.append(shortopt)
- break
- return shortopt
-
- # now we loop through the long options and assign a suitable short option, saving the short option for later use
- long_to_short = {}
- alreadyusedshorts = []
- for longopt in longopts:
- long_to_short[longopt] = derive_shortopt(longopt,alreadyusedshorts)
-
parser.api_dests = []
if api_callable and api_options:
group = parser.add_option_group("Options for the %s API"%api_name)
for a in api_options:
- shortopt = long_to_short[a[0][0]]
- if shortopt: group.add_option(shortopt,a[0][0],**a[1])
- else: group.add_option(a[0][0],**a[1])
+ group.add_option(a[0][0],**a[1])
parser.api_dests.append(a[1]["dest"])
parser.cmd_dests = []
if cmd_callable and cmd_options:
group = parser.add_option_group("Options for the %s command"%cmd_name)
for a in cmd_options:
- shortopt = long_to_short[a[0][0]]
- if shortopt: group.add_option(shortopt,a[0][0],**a[1])
- else: group.add_option(a[0][0],**a[1])
+ group.add_option(a[0][0],**a[1])
parser.cmd_dests.append(a[1]["dest"])
return parser
@@ -178,7 +145,7 @@ def get_command_list(api):
for cmd_name in dir(api):
cmd = getattr(api,cmd_name)
if callable(cmd) and not cmd_name.startswith("_"):
- if cmd.__doc__: docstring = cmd.__doc__
- else: docstring = ''
- cmds.append( " %s %s"%(cmd_name.replace('_','-'),docstring) )
+ if cmd.__doc__:docstring = cmd.__doc__
+ else:docstring = ''
+ cmds.append( " %s" % (cmd_name.replace('_','-')) )
return cmds
diff --git a/utils/src/com/cloud/utils/commandlinetool/BuildCommandLineInputFile.java b/utils/src/com/cloud/utils/commandlinetool/BuildCommandLineInputFile.java
deleted file mode 100644
index f2a77615b9f..00000000000
--- a/utils/src/com/cloud/utils/commandlinetool/BuildCommandLineInputFile.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/**
- * Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
- *
- * This software is licensed under the GNU General Public License v3 or later.
- *
- * It is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-
-package com.cloud.utils.commandlinetool;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Properties;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Text;
-
-import com.cloud.utils.Pair;
-
-public class BuildCommandLineInputFile {
- private static Properties api_commands = new Properties();
- private static String dirName="";
-
- public static void main (String[] args) {
- Properties preProcessedCommands = new Properties();
- Class clas = null;
- Enumeration e = null;
- String[] fileNames = null;
-
- //load properties
- List argsList = Arrays.asList(args);
- Iterator iter = argsList.iterator();
- while (iter.hasNext()) {
- String arg = iter.next();
- // populate the file names
- if (arg.equals("-f")) {
- fileNames = iter.next().split(",");
- }
- if (arg.equals("-d")) {
- dirName = iter.next();
- }
- }
-
- if ((fileNames == null) || (fileNames.length == 0)){
- System.out.println("Please specify input file(s) separated by coma using -f option");
- System.exit(2);
- }
-
- for (String fileName : fileNames) {
- try {
- FileInputStream in = new FileInputStream(fileName);
- preProcessedCommands.load(in);
- }catch (FileNotFoundException ex) {
- System.out.println("Can't find file " + fileName);
- System.exit(2);
- } catch (IOException ex1) {
- System.out.println("Error reading from file " + ex1);
- System.exit(2);
- }
- }
-
-
- for (Object key : preProcessedCommands.keySet()) {
- String preProcessedCommand = preProcessedCommands.getProperty((String)key);
- String[] commandParts = preProcessedCommand.split(";");
- api_commands.put(key, commandParts[0]);
- }
-
-
- e = api_commands.propertyNames();
-
- try {
- DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
- DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
- Document doc = docBuilder.newDocument();
- Element root = doc.createElement("commands");
- doc.appendChild(root);
-
- while (e.hasMoreElements()) {
- String key = (String) e.nextElement();
- try {
- clas = Class.forName(api_commands.getProperty(key));
- Element child1 = doc.createElement("command");
- root.appendChild(child1);
- Element child2 = doc.createElement("name");
- child1.appendChild(child2);
- Text text = doc.createTextNode(key);
- child2.appendChild(text);
-
- Field m[] = clas.getDeclaredFields();
- for (int i = 0; i < m.length; i++) {
- if (m[i].getName().endsWith("s_properties")) {
- m[i].setAccessible(true);
- List> properties = (List>) m[i].get(null);
- for (Pair property : properties){
- if (!property.first().toString().equals("ACCOUNT_OBJ") && !property.first().toString().equals("USER_ID")){
- Element child3 = doc.createElement("arg");
- child1.appendChild(child3);
- Class clas2 = property.first().getClass();
- Method m2 = clas2.getMethod("getName");
- text = doc.createTextNode(m2.invoke(property.first()).toString());
- child3.appendChild(text);
- child3.setAttribute("required", property.second().toString());
- }
- }
- }
- }
- } catch (ClassNotFoundException ex2) {
- System.out.println("Can't find class " + api_commands.getProperty(key));
- System.exit(2);
- }
- }
- TransformerFactory transfac = TransformerFactory.newInstance();
- Transformer trans = transfac.newTransformer();
- trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
- trans.setOutputProperty(OutputKeys.INDENT, "yes");
-
- StringWriter sw = new StringWriter();
- StreamResult result = new StreamResult(sw);
- DOMSource source = new DOMSource(doc);
- trans.transform(source, result);
- String xmlString = sw.toString();
-
- //write xml to file
- File f=new File(dirName + "/commands.xml");
- Writer output = new BufferedWriter(new FileWriter(f));
- output.write(xmlString);
- output.close();
- } catch (Exception ex) {
- System.out.println(ex);
- System.exit(2);
- }
- }
-
-}
\ No newline at end of file
diff --git a/wscript_build b/wscript_build
index 6cb90d4afcd..3dbf48123fb 100644
--- a/wscript_build
+++ b/wscript_build
@@ -421,7 +421,7 @@ def generate_xml_api_description(task):
cp += jars
cp = pathsep.join(cp)
arguments = ["-f",",".join(properties),"-d",builddir]
- ret = Utils.exec_command(["java","-cp",cp,"com.cloud.utils.commandlinetool.BuildCommandLineInputFile"]+arguments,log=True)
+ ret = Utils.exec_command(["java","-cp",cp,"com.cloud.api.doc.ApiXmlDocWriter"]+arguments,log=True)
return ret
props = " client/tomcatconf/commands.properties"
jarnames = ['utils','server','core', 'api']