mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Fixed command line tool
This commit is contained in:
parent
ad3c18a46c
commit
fe2fc63692
@ -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
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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:]
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
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<String> argsList = Arrays.asList(args);
|
||||
Iterator<String> 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<Pair<Enum, Boolean>> properties = (List<Pair<Enum, Boolean>>) 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -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']
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user