You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ro...@apache.org on 2018/04/10 22:41:51 UTC
[cloudstack-cloudmonkey] 01/02: cloudmonkey: purge legacy files
This is an automated email from the ASF dual-hosted git repository.
rohit pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cloudstack-cloudmonkey.git
commit 7b55fb417ac6788b009c1caf040f2a9dbb6e0031
Author: Rohit Yadav <ro...@apache.org>
AuthorDate: Wed Apr 11 04:02:40 2018 +0530
cloudmonkey: purge legacy files
Signed-off-by: Rohit Yadav <ro...@apache.org>
---
.gitignore | 28 --
Dockerfile | 36 --
Makefile | 41 --
cloudmonkey/__init__.py | 23 --
cloudmonkey/cachemaker.py | 182 ---------
cloudmonkey/cloudmonkey.py | 937 --------------------------------------------
cloudmonkey/config.py | 209 ----------
cloudmonkey/precache.py | 19 -
cloudmonkey/printer.py | 124 ------
cloudmonkey/requester.py | 335 ----------------
config.docker | 25 --
docs/.gitignore | 1 -
docs/Makefile | 177 ---------
docs/source/cloudmonkey.rst | 62 ---
docs/source/conf.py | 262 -------------
docs/source/index.rst | 37 --
docs/source/modules.rst | 7 -
setup.cfg | 7 -
setup.py | 86 ----
19 files changed, 2598 deletions(-)
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 63c8cd1..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,28 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you 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.
-
-dist/
-*~
-*.log
-*.pyc
-*.egginfo/
-*.egg-info/
-.DS_Store
-*.swp
-build/
-.*
-!.gitignore
diff --git a/Dockerfile b/Dockerfile
deleted file mode 100644
index 696974d..0000000
--- a/Dockerfile
+++ /dev/null
@@ -1,36 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you 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.
-#
-#
-FROM python:2
-
-MAINTAINER "Apache CloudStack" <de...@cloudstack.apache.org>
-LABEL Description="Apache CloudStack CloudMonkey; Python based CloudStack command line interface"
-LABEL Vendor="Apache.org"
-LABEL License=ApacheV2
-LABEL Version=5.3.3
-
-COPY . /cloudstack-cloudmonkey
-RUN pip install requests
-RUN (cd /cloudstack-cloudmonkey; python setup.py build)
-RUN (cd /cloudstack-cloudmonkey; python setup.py install)
-
-RUN mkdir -p /cloudmonkey
-WORKDIR /cloudmonkey
-COPY config.docker /cloudmonkey/config
-
-ENTRYPOINT ["cloudmonkey", "-c", "/cloudmonkey/config"]
\ No newline at end of file
diff --git a/Makefile b/Makefile
deleted file mode 100644
index 182cbce..0000000
--- a/Makefile
+++ /dev/null
@@ -1,41 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you 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.
-
-all: clean buildwithcache
-
-runtests:
- nosetests -v --verbosity=3
-
-buildwithcache: buildcache build
-
-build:
- python setup.py build
- python setup.py sdist
-
-check:
- pep8 cloudmonkey/*.py
-
-buildcache:
- python cloudmonkey/cachemaker.py
- mv -f precache.py cloudmonkey/
-
-install: clean
- python setup.py sdist
- pip install --upgrade dist/cloudmonkey-*.tar.gz
-
-clean:
- rm -frv build dist *egg-info
diff --git a/cloudmonkey/__init__.py b/cloudmonkey/__init__.py
deleted file mode 100644
index cf689e7..0000000
--- a/cloudmonkey/__init__.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you 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.
-
-try:
- from config import __version__, __description__
- from config import __maintainer__, __maintaineremail__
- from config import __project__, __projecturl__, __projectemail__
-except ImportError, e:
- print e
diff --git a/cloudmonkey/cachemaker.py b/cloudmonkey/cachemaker.py
deleted file mode 100644
index 2f2fa87..0000000
--- a/cloudmonkey/cachemaker.py
+++ /dev/null
@@ -1,182 +0,0 @@
-# -*- coding: utf-8 -*-
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you 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.
-
-try:
- import json
- import os
- import types
-
- from config import config_fields
-except ImportError, e:
- import sys
- print "ImportError", e
- sys.exit(1)
-
-
-def getvalue(dictionary, key):
- if key in dictionary:
- return dictionary[key]
- else:
- return None
-
-
-def splitcsvstring(string):
- if string is not None:
- return filter(lambda x: x.strip() != '', string.split(','))
- else:
- return []
-
-
-def splitverbsubject(string):
- idx = 0
- for char in string:
- if char.islower():
- idx += 1
- else:
- break
- return string[:idx].lower(), string[idx:].lower()
-
-
-def savecache(apicache, json_file):
- """
- Saves apicache dictionary as json_file, returns dictionary as indented str
- """
- if apicache is None or apicache is {}:
- return ""
- apicachestr = json.dumps(apicache, indent=2)
- with open(json_file, 'w') as cache_file:
- cache_file.write(apicachestr)
- return apicachestr
-
-
-def loadcache(json_file):
- """
- Loads json file as dictionary, feeds it to monkeycache and spits result
- """
- f = open(json_file, 'r')
- data = f.read()
- f.close()
- try:
- apicache = json.loads(data)
- except ValueError, e:
- print "Error processing json:", json_file, e
- return {}
- return apicache
-
-
-def monkeycache(apis):
- """
- Feed this a dictionary of api bananas, it spits out processed cache
- """
- if isinstance(type(apis), types.NoneType) or apis is None:
- return {}
-
- responsekey = filter(lambda x: 'response' in x, apis.keys())
-
- if len(responsekey) == 0:
- print "[monkeycache] Invalid dictionary, has no response"
- return None
- if len(responsekey) != 1:
- print "[monkeycache] Multiple responsekeys, chosing first one"
-
- responsekey = responsekey[0]
- verbs = set()
- cache = {}
- cache['count'] = getvalue(apis[responsekey], 'count')
- cache['asyncapis'] = []
-
- apilist = getvalue(apis[responsekey], 'api')
- if apilist is None:
- print "[monkeycache] Server response issue, no apis found"
-
- for api in apilist:
- name = getvalue(api, 'name')
- verb, subject = splitverbsubject(name)
-
- apidict = {}
- apidict['name'] = name
- apidict['description'] = getvalue(api, 'description')
- apidict['isasync'] = getvalue(api, 'isasync')
- if apidict['isasync']:
- cache['asyncapis'].append(name)
- apidict['related'] = splitcsvstring(getvalue(api, 'related'))
-
- required = []
- apiparams = []
- for param in getvalue(api, 'params'):
- apiparam = {}
- apiparam['name'] = getvalue(param, 'name')
- apiparam['description'] = getvalue(param, 'description')
- apiparam['required'] = (getvalue(param, 'required') is True)
- apiparam['length'] = int(getvalue(param, 'length'))
- apiparam['type'] = getvalue(param, 'type')
- apiparam['related'] = splitcsvstring(getvalue(param, 'related'))
- if apiparam['required']:
- required.append(apiparam['name'])
- apiparams.append(apiparam)
-
- apidict['requiredparams'] = required
- apidict['params'] = apiparams
- apidict['response'] = getvalue(api, 'response')
- if verb not in cache:
- cache[verb] = {}
- cache[verb][subject] = apidict
- verbs.add(verb)
-
- cache['verbs'] = list(verbs)
- return cache
-
-
-def main(json_file):
- """
- cachemaker.py creates a precache datastore of all available apis of
- CloudStack and dumps the precache dictionary in an
- importable python module. This way we cheat on the runtime overhead of
- completing commands and help docs. This reduces the overall search and
- cache_miss (computation) complexity from O(n) to O(1) for any valid cmd.
- """
- f = open("precache.py", "w")
- f.write("""# -*- coding: utf-8 -*-
-# Auto-generated code by cachemaker.py
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you 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.""")
- f.write("\napicache = %s" % loadcache(json_file))
- f.close()
-
-if __name__ == "__main__":
- cache_file = config_fields['core']['cache_file']
- print "[cachemaker] Pre-caching using user's cloudmonkey cache", cache_file
- if os.path.exists(cache_file):
- main(cache_file)
- else:
- print "[cachemaker] Unable to cache apis, file not found", cache_file
- print "[cachemaker] Run cloudmonkey sync to generate cache"
diff --git a/cloudmonkey/cloudmonkey.py b/cloudmonkey/cloudmonkey.py
deleted file mode 100644
index b106362..0000000
--- a/cloudmonkey/cloudmonkey.py
+++ /dev/null
@@ -1,937 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you 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.
-
-try:
- import argcomplete
- import argparse
- import atexit
- import cmd
- import csv
- import copy
- import json
- import logging
- import os
- import shlex
- import sys
- import time
- import types
-
- from cachemaker import loadcache, savecache, monkeycache, splitverbsubject
- from config import __version__, __description__, __projecturl__
- from config import display_types
- from config import read_config, write_config, config_file, default_profile
- from dicttoxml import dicttoxml
- from optparse import OptionParser
- from prettytable import PrettyTable
- from printer import monkeyprint
- from requester import monkeyrequest
- from requester import login
- from requester import logout
- from urlparse import urlparse
- from xml.dom.minidom import parseString
-except ImportError, e:
- print("Import error in %s : %s" % (__name__, e))
- import sys
- sys.exit()
-
-try:
- from precache import apicache
-except ImportError:
- apicache = {'count': 0, 'verbs': [], 'asyncapis': []}
-
-normal_readline = True
-# Fix terminal env before importing readline
-# Without it, char ESC[?1034h gets printed in output
-# There is not TERM variable in some environment such as Docker.
-if 'TERM' not in os.environ or os.environ['TERM'].startswith('xterm'):
- os.environ['TERM'] = 'vt100'
-try:
- import readline
-except ImportError, e:
- print("Module readline not found, autocompletions will fail", e)
-else:
- import rlcompleter
- readline_doc = getattr(readline, '__doc__', '')
- if readline_doc is not None and 'libedit' in readline_doc:
- readline.parse_and_bind("bind ^I rl_complete")
- readline.parse_and_bind("bind ^R em-inc-search-prev")
- normal_readline = False
- else:
- readline.parse_and_bind("tab: complete")
-
-log_fmt = '%(asctime)s - %(filename)s:%(lineno)s - [%(levelname)s] %(message)s'
-logger = logging.getLogger(__name__)
-
-
-class CloudMonkeyShell(cmd.Cmd, object):
- intro = ("☁ Apache CloudStack 🐵 cloudmonkey " + __version__ +
- ". Type help or ? to list commands.\n")
- ruler = "="
- config_options = []
- profile_names = []
- verbs = []
- interpreterMode = False
- error_on_last_command = False
- param_cache = {}
- prompt = "🐵 > "
- protocol = "http"
- host = "localhost"
- port = "8080"
- path = "/client/api"
- hook_count = 0
-
- def __init__(self, pname, cfile):
- self.default_apis = self.completenames('')
- self.program_name = pname
- self.config_file = cfile
- self.config_options = read_config(self.get_attr, self.set_attr,
- self.config_file)
- self.loadcache()
- self.init_credential_store()
- logging.basicConfig(filename=self.log_file,
- level=logging.DEBUG, format=log_fmt)
- logger.debug("Loaded config fields:\n%s" % map(lambda x: "%s=%s" %
- (x, getattr(self, x)),
- self.config_options))
- cmd.Cmd.__init__(self)
-
- try:
- if os.path.exists(self.history_file):
- readline.read_history_file(self.history_file)
- except IOError, e:
- logger.debug(u"Error: Unable to read history. " + unicode(e))
- atexit.register(readline.write_history_file, self.history_file)
-
- def init_credential_store(self):
- self.credentials = {'apikey': self.apikey, 'secretkey': self.secretkey,
- 'domain': self.domain, 'username': self.username,
- 'password': self.password,
- 'signatureversion': self.signatureversion}
- parsed_url = urlparse(self.url)
- self.protocol = "http" if not parsed_url.scheme else parsed_url.scheme
- self.host = parsed_url.netloc
- self.port = "8080" if not parsed_url.port else parsed_url.port
- self.path = parsed_url.path
- self.set_prompt()
-
- def get_prompt(self):
- return self.prompt.split(") ")[-1]
-
- def set_prompt(self):
- self.prompt = "(%s) %s" % (self.profile, self.get_prompt())
-
- def get_attr(self, field):
- return getattr(self, field)
-
- def set_attr(self, field, value):
- return setattr(self, field, value)
-
- def emptyline(self):
- pass
-
- def cmdloop(self, intro=None):
- self.interpreterMode = True
- print(self.intro)
- print "Using management server profile:", self.profile, "\n"
- while True:
- try:
- super(CloudMonkeyShell, self).cmdloop(intro="")
- except KeyboardInterrupt:
- print("^C")
-
- def precmd(self, line):
- self.hook_count -= 1
- if self.hook_count <= 0:
- self.hook_count = 0
- readline.set_startup_hook()
- return line
-
- def loadcache(self):
- if os.path.exists(self.cache_file):
- self.apicache = loadcache(self.cache_file)
- else:
- self.apicache = apicache
- if 'verbs' in self.apicache:
- self.verbs = self.apicache['verbs']
-
- for verb in self.verbs:
- handler_name = "do_" + str(verb)
- handler_doc = str("%ss resources" % verb.capitalize())
-
- if hasattr(self, handler_name) and getattr(self, handler_name).__doc__ == handler_doc:
- continue
-
- def add_grammar(verb):
- default_handler = None
- if self.default_apis.__contains__(verb):
- default_handler = getattr(self, handler_name)
-
- def grammar_closure(self, args):
- if not args:
- if default_handler:
- default_handler(args)
- return
- args = args.decode("utf-8")
- if self.pipe_runner(u"{0} {1}".format(verb, args)):
- return
- if ' --help' in args or ' -h' in args:
- self.do_help("%s %s" % (verb, args))
- return
- try:
- args_partition = args.partition(" ")
- cmd = self.apicache[verb][args_partition[0]]['name']
- args = args_partition[2]
- except KeyError, e:
- if default_handler:
- default_handler(args)
- else:
- self.monkeyprint("Error: invalid %s api arg " % verb,
- str(e))
- return
- self.default(u"{0} {1}".format(cmd, args))
- return grammar_closure
-
- grammar_handler = add_grammar(verb)
- grammar_handler.__doc__ = handler_doc
- grammar_handler.__name__ = handler_name
- setattr(self.__class__, grammar_handler.__name__, grammar_handler)
-
- def monkeyprint(self, *args):
- output = u""
- try:
- for arg in args:
- if isinstance(type(arg), types.NoneType) or not arg:
- continue
- if not (isinstance(arg, str) or isinstance(arg, unicode)):
- arg = unicode(arg)
- output += arg
- except Exception, e:
- print(str(e))
-
- output = output.encode("utf-8")
- if self.color == 'true':
- monkeyprint(output)
- else:
- if output.startswith("Error"):
- sys.stderr.write(output + "\n")
- sys.stderr.flush()
- else:
- print output
-
- def print_result(self, result, result_filter=[]):
- if not result or len(result) == 0:
- return
-
- filtered_result = copy.deepcopy(result)
- if result_filter and isinstance(result_filter, list) \
- and len(result_filter) > 0:
- tfilter = {} # temp var to hold a dict of the filters
- tresult = filtered_result # dupe the result to filter
- if result_filter:
- for res in result_filter:
- tfilter[res] = 1
- for okey, oval in result.iteritems():
- if isinstance(oval, dict):
- for tkey in oval:
- if tkey not in tfilter:
- try:
- del(tresult[okey][oval][tkey])
- except:
- pass
- elif isinstance(oval, list):
- for x in range(len(oval)):
- if isinstance(oval[x], dict):
- for tkey in oval[x]:
- if tkey not in tfilter:
- try:
- del(tresult[okey][x][tkey])
- except:
- pass
- else:
- try:
- del(tresult[okey][x])
- except:
- pass
- filtered_result = tresult
-
- def print_result_json(result):
- self.monkeyprint(json.dumps(result,
- sort_keys=True,
- indent=2,
- ensure_ascii=False,
- separators=(',', ': ')))
-
- def print_result_xml(result):
- custom_root = "CloudStack-%s" % self.profile.replace(" ", "_")
- xml = dicttoxml(result, attr_type=False, custom_root=custom_root)
- self.monkeyprint(parseString(xml).toprettyxml())
-
- def print_result_csv(result):
- if "count" in result:
- result.pop("count")
-
- if len(result.keys()) == 1:
- item = result[result.keys()[0]]
- if isinstance(item, list):
- result = item
- elif isinstance(item, dict):
- result = [item]
-
- if isinstance(result, list) and len(result) > 0:
- if isinstance(result[0], dict):
- keys = result[0].keys()
- writer = csv.DictWriter(sys.stdout, keys)
- print ','.join(keys)
- for item in result:
- row = {}
- for k in keys:
- if k not in item:
- row[k] = None
- else:
- if type(item[k]) is unicode:
- row[k] = item[k].encode('utf8')
- else:
- row[k] = item[k]
- writer.writerow(row)
- elif isinstance(result, dict):
- keys = result.keys()
- writer = csv.DictWriter(sys.stdout, keys)
- print ','.join(keys)
- writer.writerow(result)
-
- def print_result_tabular(result):
- def print_table(printer, toprow):
- if printer:
- self.monkeyprint(printer.get_string())
- return PrettyTable(toprow)
- printer = None
- toprow = []
- if not result:
- return
- toprow = set(reduce(lambda x, y: x + y, map(lambda x: x.keys(),
- filter(lambda x: isinstance(x, dict), result))))
- printer = print_table(printer, toprow)
- for node in result:
- if not node:
- continue
- for key in toprow:
- if key not in node:
- node[key] = ''
- row = map(lambda x: node[x], toprow)
- if printer and row:
- printer.add_row(row)
- print_table(printer, toprow)
-
- def print_result_as_dict(result):
- for key in sorted(result.keys(), key=lambda x:
- x not in ['id', 'count', 'name'] and x):
- if isinstance(result[key], list):
- self.monkeyprint(key + ":")
- print_result_as_list(result[key])
- elif isinstance(result[key], dict):
- self.monkeyprint(key + ":")
- print_result_as_dict(result[key])
- else:
- value = unicode(result[key])
- self.monkeyprint(key, " = ", value)
-
- def print_result_as_list(result):
- for idx, node in enumerate(result):
- if isinstance(node, dict):
- if self.display == 'table':
- print_result_tabular(result)
- break
- print_result_as_dict(node)
- elif isinstance(node, list):
- print_result_as_list(node)
- else:
- self.monkeyprint(filtered_result)
- if result and node and (idx+1) < len(result):
- self.monkeyprint(self.ruler * 80)
-
- if self.display == "json":
- print_result_json(filtered_result)
- return
-
- if self.display == "xml":
- print_result_xml(filtered_result)
- return
-
- if self.display == "csv":
- print_result_csv(filtered_result)
- return
-
- if isinstance(filtered_result, dict):
- print_result_as_dict(filtered_result)
- elif isinstance(filtered_result, list):
- print_result_as_list(filtered_result)
- else:
- self.monkeyprint(filtered_result)
-
- def make_request(self, command, args={}, isasync=False):
- self.error_on_last_command = False
- response, error = monkeyrequest(command, args, isasync,
- self.asyncblock, logger,
- self.url, self.credentials,
- self.timeout, self.expires,
- self.verifysslcert == 'true',
- self.signatureversion)
- if error:
- self.monkeyprint(u"Error {0}".format(error))
- self.error_on_last_command = True
- return response
-
- def update_param_cache(self, api, result={}):
- if not api:
- return
- logger.debug("Updating param cache for %s API" % api)
- responsekey = filter(lambda x: 'response' in x, result.keys())[0]
- result = result[responsekey]
- options = []
- uuids = []
- for key in result.keys():
- if isinstance(result[key], list):
- for element in result[key]:
- if 'id' in element.keys():
- uuid = unicode(element['id'])
- name = ""
- keyspace = ["name", "displayname",
- "username", "description"]
- for name_key in keyspace:
- if name_key in element.keys():
- name = element[name_key]
- break
- options.append((uuid, name,))
- uuids.append(uuid)
- self.param_cache[api] = {}
- self.param_cache[api]["ts"] = int(time.time())
- self.param_cache[api]["options"] = sorted(options)
- return sorted(uuids)
-
- def default(self, args):
- try:
- args = args.strip()
- args.decode("utf-8")
- except UnicodeError, ignore:
- args = args.encode("utf-8")
-
- if self.pipe_runner(args):
- return
-
- apiname = args.partition(' ')[0]
- verb, subject = splitverbsubject(apiname)
-
- lexp = shlex.shlex(args)
- lexp.whitespace = " "
- lexp.whitespace_split = True
- lexp.posix = True
- args = []
- while True:
- try:
- next_val = lexp.next()
- if not next_val:
- break
- next_val = next_val.decode("utf-8")
- args.append(next_val.replace(u'\x00', u''))
- except ValueError, err:
- self.monkeyprint("Command parsing error: ", err)
- return
-
- args_dict = dict(map(lambda x: [x.partition("=")[0],
- x.partition("=")[2]],
- args[1:])[x] for x in range(len(args) - 1))
-
- field_filter = []
- if 'filter' in args_dict:
- field_filter = filter(lambda x: x.strip() != '',
- args_dict.pop('filter').split(','))
- field_filter = list(set(field_filter))
-
- missing = []
- if verb in self.apicache and subject in self.apicache[verb]:
- missing = filter(lambda x: x not in [key.split('[')[0].lower()
- for key in args_dict],
- self.apicache[verb][subject]['requiredparams'])
-
- if len(missing) > 0:
- self.monkeyprint("Missing arguments: ", ' '.join(missing))
- return
-
- isasync = False
- if 'asyncapis' in self.apicache:
- if apiname.decode("utf-8") in self.apicache["asyncapis"]:
- isasync = True
-
- result = self.make_request(apiname, args_dict, isasync)
-
- if not result or not isinstance(result, dict):
- if isinstance(result, unicode):
- result = result.decode("utf-8")
- logger.debug("Invalid command result: %s" % result)
- return
-
- try:
- responsekeys = filter(lambda x: 'response' in x, result.keys())
- for responsekey in responsekeys:
- self.print_result(result[responsekey], field_filter)
- if apiname.startswith("list") and "id" not in args_dict:
- self.update_param_cache(apiname, result)
- except Exception as e:
- self.monkeyprint("Error on parsing and printing ", e)
-
- def completedefault(self, text, line, begidx, endidx):
- partitions = line[:endidx].partition(" ")
- verb = partitions[0].strip()
- rline = partitions[2].lstrip().partition(" ")
- subject = rline[0]
- separator = rline[1]
- params = rline[2].lstrip()
-
- if verb not in self.verbs:
- return []
-
- autocompletions = []
- search_string = ""
-
- if separator != " ": # Complete verb subjects
- autocompletions = map(lambda x: x + " ",
- self.apicache[verb].keys())
- search_string = subject
- else: # Complete subject params
- autocompletions = map(lambda x: x + "=",
- map(lambda x: x['name'],
- self.apicache[verb][subject]['params']))
- search_string = text
- if self.paramcompletion == 'true':
- param = line[:endidx].split(" ")[-1]
- idx = param.find("=")
- value = param[idx + 1:]
- param = param[:idx]
- if param == "filter":
- response_params = self.apicache[verb][subject]["response"]
- used = filter(lambda x: x.strip() != "",
- value.split(",")[:-1])
- unused = map(lambda x: x['name'] + ",", filter(lambda x:
- "name" in x and x["name"] not in used,
- response_params))
- last_value = value.split(",")[-1]
- if last_value:
- unused = filter(lambda x: x.startswith(last_value),
- unused)
- suffix = ",".join(used)
- if suffix:
- suffix += ","
- global normal_readline
- if normal_readline:
- return filter(lambda x: x.startswith(last_value),
- map(lambda x: x, unused))
- else: # OSX fix
- return filter(lambda x: x.startswith(value),
- map(lambda x: suffix + x, unused))
- elif len(value) < 36 and idx != -1:
- api = None
- logger.debug("[Paramcompl] For %s %s %s=" % (verb, subject,
- param))
- if "id" in param:
- logger.debug("[Paramcompl] Using 'list' heuristics")
- if param == "id" or param == "ids":
- entity = subject
- else:
- entity = param.replace("id", "")
- apis = []
- for resource in self.apicache["list"]:
- if resource.startswith(entity):
- api = self.apicache["list"][resource]['name']
- if (entity + "s") == resource.lower():
- break
- apis.append(api)
- api = None
- if len(apis) > 0 and not api:
- logger.debug("[Paramcompl] APIs: %s" % apis)
- api = min(apis, key=len)
- logger.debug("[Paramcompl] Possible API: %s" % api)
- if not api:
- logger.debug("[Paramcompl] Using relative approx")
- params = self.apicache[verb][subject]['params']
- arg = filter(lambda x: x['name'] == param, params)[0]
- if "type" in arg and arg["type"] == "boolean":
- return filter(lambda x: x.startswith(value),
- ["true ", "false "])
- related = arg['related']
- apis = filter(lambda x: 'list' in x, related)
- logger.debug("[Paramcompl] Related APIs: %s" % apis)
- if len(apis) > 0:
- api = apis[0]
- else:
- if param == "account":
- api = "listAccounts"
- else:
- return
- uuids = []
- cache_burst_ts = int(time.time()) - 900
- logger.debug("Trying paramcompletion using API: %s" % api)
- if api in self.param_cache.keys() and \
- len(self.param_cache[api]["options"]) > 0 and \
- self.param_cache[api]["ts"] > cache_burst_ts:
- for option in self.param_cache[api]["options"]:
- uuid = option[0]
- if uuid.startswith(value):
- uuids.append(uuid)
- else:
- api_args = {'listall': 'true', 'templatefilter': 'all'}
- response = self.make_request(api, args=api_args)
- if not response:
- return
- uuids = self.update_param_cache(api, response)
- if len(uuids) > 1:
- print
- options = sorted(self.param_cache[api]["options"],
- key=lambda x: x[1])
- for option in options:
- uuid = option[0]
- name = option[1]
- if uuid.startswith(value):
- print uuid, name
- autocompletions = map(lambda x: x + " ", uuids)
- search_string = value
-
- if subject != "" and line.split(" ")[-1].find('=') == -1:
- autocompletions.append("filter=")
- return [s for s in autocompletions if s.startswith(search_string)]
-
- def do_sync(self, args):
- """
- Asks cloudmonkey to discovery and sync apis available on user specified
- CloudStack host server which has the API discovery plugin, on failure
- it rollbacks last datastore or api precached datastore.
- """
- response = self.make_request("listApis")
- if not response:
- monkeyprint("Failed to sync apis, please check your config?")
- monkeyprint("Note: `sync` requires api discovery service enabled" +
- " on the CloudStack management server")
- return
- self.apicache = monkeycache(response)
- savecache(self.apicache, self.cache_file)
- monkeyprint("%s APIs discovered and cached" % self.apicache["count"])
- self.loadcache()
-
- def do_api(self, args):
- """
- Make raw api calls. Syntax: api <apiName> <args>=<values>.
-
- Example:
- api listAccount listall=true
- """
- if len(args) > 0:
- return self.default(args)
- else:
- self.monkeyprint("Please use a valid syntax")
-
- def do_set(self, args):
- """
- Set config for cloudmonkey. For example, options can be:
- url, auth, log_file, history_file
- You may also edit your ~/.cloudmonkey_config instead of using set.
-
- Example:
- set url http://localhost:8080/client/api
- set prompt 🐵 cloudmonkey>
- set log_file /var/log/cloudmonkey.log
- """
- args = args.strip().partition(" ")
- key, value = (args[0].strip(), args[2].strip())
- if not key:
- return
- allowed_blank_keys = ["username", "password", "apikey", "secretkey",
- "domain"]
- if key not in allowed_blank_keys and not value:
- print "Blank value of %s is not allowed" % key
- return
-
- self.prompt = self.get_prompt()
- setattr(self, key, value)
- if key in ['host', 'port', 'path', 'protocol']:
- key = 'url'
- self.url = "%s://%s:%s%s" % (self.protocol, self.host,
- self.port, self.path)
- print "This option has been deprecated, please set 'url' instead"
- print "This server url will be used:", self.url
- write_config(self.get_attr, self.config_file)
- read_config(self.get_attr, self.set_attr, self.config_file)
- self.init_credential_store()
- if key.strip() == 'profile' and self.interpreterMode:
- print "\nLoaded server profile '%s' with options:" % value
- for option in default_profile.keys():
- value = self.get_attr(option)
- if option in ["password", "apikey", "secretkey"] and value:
- value = value[:2] + "XXX" + value[4:6] + "YYY...(hidden)"
- print " %s = %s" % (option, value)
- print
-
- def complete_set(self, text, line, begidx, endidx):
- mline = line.partition(" ")[2].lstrip().partition(" ")
- option = mline[0].strip()
- separator = mline[1]
- value = mline[2].lstrip()
- if separator == "":
- return [s for s in self.config_options if s.startswith(option)] + self.completedefault(text, line, begidx, endidx)
- elif option == "profile":
- return [s for s in self.profile_names if s.startswith(value)]
- elif option == "display":
- return [s for s in display_types
- if s.startswith(value)]
- elif option in ["asyncblock", "color", "paramcompletion",
- "verifysslcert"]:
- return [s for s in ["true", "false"] if s.startswith(value)]
- elif "set" in self.apicache["verbs"]:
- return self.completedefault(text, line, begidx, endidx)
-
- return []
-
- def do_login(self, args):
- """
- Login using stored credentials. Starts a session to be reused for
- subsequent api calls
- """
- try:
- session, sessionkey = login(self.url, self.username, self.password)
- self.credentials['session'] = session
- self.credentials['sessionkey'] = sessionkey
- except Exception, e:
- self.monkeyprint("Error: Login failed to the server: ", unicode(e))
-
- def do_logout(self, args):
- """
- Logout of session started with login with username and password
- """
- try:
- logout(self.url, self.credentials.get('session'))
- except Exception, e:
- pass
- self.credentials['session'] = None
- self.credentials['sessionkey'] = None
-
- def pipe_runner(self, args):
- if args.find(" |") > -1:
- pname = self.program_name
- if '.py' in pname:
- pname = "python " + pname
- if isinstance(args, str):
- self.do_shell("{0} {1}".format(pname, args))
- else:
- self.do_shell(u"{0} {1}".format(pname, args))
- return True
- return False
-
- def do_shell(self, args):
- """
- Execute shell commands using shell <command> or !<command>
-
- Example:
- !ls
- shell ls
- !for((i=0; i<10; i++)); do cloudmonkey create user account=admin \
- email=test@test.tt firstname=user$i lastname=user$i \
- password=password username=user$i; done
- """
- if args.isdigit():
- self.do_history("!" + args)
- return
- if isinstance(args, str):
- os.system(args)
- else:
- os.system(args.encode("utf-8"))
-
- def do_history(self, args):
- """
- Prints cloudmonkey history
- """
- if self.pipe_runner("history " + args):
- return
- startIdx = 1
- endIdx = readline.get_current_history_length()
- numLen = len(str(endIdx))
- historyArg = args.split(' ')[0]
- if historyArg.isdigit():
- startIdx = endIdx - long(historyArg)
- if startIdx < 1:
- startIdx = 1
- elif historyArg == "clear" or historyArg == "c":
- readline.clear_history()
- print "CloudMonkey history cleared"
- return
- elif len(historyArg) > 1 and historyArg[0] == "!" and historyArg[1:].isdigit():
- command = readline.get_history_item(long(historyArg[1:]))
- readline.set_startup_hook(lambda: readline.insert_text(command))
- self.hook_count = 1
- return
- for idx in xrange(startIdx, endIdx):
- self.monkeyprint("%s %s" % (str(idx).rjust(numLen),
- readline.get_history_item(idx)))
-
- def do_help(self, args):
- """
- Show help docs for various topics
-
- Example:
- help list
- help list users
- ?list
- ?list users
- """
- fields = args.partition(" ")
- if fields[2] == "":
- cmd.Cmd.do_help(self, args)
- else:
- verb = fields[0]
- subject = fields[2].partition(" ")[0]
- if subject in self.apicache[verb]:
- api = self.apicache[verb][subject]
- helpdoc = "(%s) %s" % (api['name'], api['description'])
- if api['isasync']:
- helpdoc += "\nThis API is asynchronous."
- required = api['requiredparams']
- if len(required) > 0:
- helpdoc += "\nRequired params are %s" % ' '.join(required)
- helpdoc += "\nParameters\n" + "=" * 10
- for param in api['params']:
- helpdoc += "\n%s = (%s) %s" % (
- param['name'], param['type'],
- param['description'])
- self.monkeyprint(helpdoc)
- else:
- self.monkeyprint("Error: no such api (%s) on %s" %
- (subject, verb))
-
- def complete_help(self, text, line, begidx, endidx):
- fields = line.partition(" ")
- subfields = fields[2].partition(" ")
-
- if subfields[1] != " ":
- return cmd.Cmd.complete_help(self, text, line, begidx, endidx)
- else:
- line = fields[2]
- text = subfields[2]
- return self.completedefault(text, line, begidx, endidx)
-
- def do_EOF(self, args):
- """
- Quit on Ctrl+d or EOF
- """
- self.do_logout(None)
- sys.exit()
-
- def do_exit(self, args):
- """
- Quit CloudMonkey CLI
- """
- return self.do_quit(args)
-
- def do_quit(self, args):
- """
- Quit CloudMonkey CLI
- """
- self.monkeyprint("Bye!")
- return self.do_EOF(args)
-
-
-def main():
- parser = argparse.ArgumentParser(usage="cloudmonkey [options] [commands]",
- description=__description__,
- epilog="Try cloudmonkey [help|?]")
-
- parser.add_argument("-v", "--version", action="version",
- default=argparse.SUPPRESS,
- version="cloudmonkey %s" % __version__,
- help="show CloudMonkey's version and exit")
-
- parser.add_argument("-c", "--config-file",
- dest="configFile", default=config_file,
- help="config file for cloudmonkey", metavar="FILE")
-
- parser.add_argument("-b", "--block-async", action="store_true",
- help="block and poll result on async API calls")
-
- parser.add_argument("-n", "--noblock-async", action="store_true",
- help="do not block on async API calls")
-
- parser.add_argument("-d", "--display-type",
- dest="displayType", default=None,
- help="output displays: json, xml, table or default",
- choices=tuple(display_types))
-
- parser.add_argument("-p", "--profile",
- dest="serverProfile", default=None,
- help="server profile to load")
-
- parser.add_argument("commands", nargs=argparse.REMAINDER,
- help="API commands")
-
- argcomplete.autocomplete(parser)
- args = parser.parse_args()
-
- shell = CloudMonkeyShell(sys.argv[0], args.configFile)
-
- if args.displayType and args.displayType in display_types:
- shell.set_attr("display", args.displayType)
-
- if args.noblock_async:
- shell.set_attr("asyncblock", "false")
-
- if args.block_async:
- shell.set_attr("asyncblock", "true")
-
- if args.serverProfile and args.serverProfile.strip() != '':
- shell.do_set("profile %s" % args.serverProfile)
-
- if len(args.commands) > 0:
- shell.set_attr("color", "false")
- commands = []
- for command in args.commands:
- split_command = command.split("=", 1)
- if len(split_command) > 1:
- key = split_command[0]
- value = split_command[1]
- if " " not in value or \
- (value.startswith("\"") and value.endswith("\"")) or \
- (value.startswith("\'") and value.endswith("\'")):
- commands.append(command)
- else:
- commands.append("%s=\"%s\"" % (key, value))
- else:
- commands.append(command)
- shell.onecmd(" ".join(commands))
- if shell.error_on_last_command:
- sys.exit(1)
- else:
- shell.cmdloop()
-
- try:
- sys.stdout.close()
- except:
- pass
- try:
- sys.stderr.close()
- except:
- pass
-
-
-if __name__ == "__main__":
- main()
diff --git a/cloudmonkey/config.py b/cloudmonkey/config.py
deleted file mode 100644
index c5faec2..0000000
--- a/cloudmonkey/config.py
+++ /dev/null
@@ -1,209 +0,0 @@
-# -*- coding: utf-8 -*-
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you 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.
-
-__version__ = "5.3.3"
-__description__ = "Command Line Interface for Apache CloudStack"
-__maintainer__ = "The Apache CloudStack Team"
-__maintaineremail__ = "dev@cloudstack.apache.org"
-__project__ = "The Apache CloudStack Team"
-__projectemail__ = "dev@cloudstack.apache.org"
-__projecturl__ = "http://cloudstack.apache.org"
-
-try:
- import os
- import sys
-
- from ConfigParser import ConfigParser
- from os.path import expanduser
-except ImportError, e:
- print "ImportError", e
-
-param_type = ['boolean', 'date', 'float', 'integer', 'short', 'list',
- 'long', 'object', 'map', 'string', 'tzdate', 'uuid']
-
-iterable_type = ['set', 'list', 'object']
-
-# cloudmonkey display types
-display_types = ["json", "xml", "csv", "table", "default"]
-
-config_dir = expanduser('~/.cloudmonkey')
-config_file = expanduser(config_dir + '/config')
-
-# cloudmonkey config fields
-mandatory_sections = ['core', 'ui']
-default_profile_name = 'local'
-config_fields = {'core': {}, 'ui': {}}
-
-# core
-config_fields['core']['asyncblock'] = 'true'
-config_fields['core']['paramcompletion'] = 'true'
-config_fields['core']['cache_file'] = expanduser(config_dir + '/cache')
-config_fields['core']['history_file'] = expanduser(config_dir + '/history')
-config_fields['core']['log_file'] = expanduser(config_dir + '/log')
-config_fields['core']['profile'] = default_profile_name
-
-# ui
-config_fields['ui']['color'] = 'true'
-config_fields['ui']['prompt'] = '🐵 > '
-config_fields['ui']['display'] = 'default'
-
-# default profile
-default_profile = {}
-default_profile['url'] = 'http://localhost:8080/client/api'
-default_profile['timeout'] = '3600'
-default_profile['expires'] = '600'
-default_profile['username'] = 'admin'
-default_profile['password'] = 'password'
-default_profile['domain'] = '/'
-default_profile['apikey'] = ''
-default_profile['secretkey'] = ''
-default_profile['verifysslcert'] = 'true'
-default_profile['signatureversion'] = '3'
-
-
-def write_config(get_attr, config_file):
- global config_fields, mandatory_sections
- global default_profile, default_profile_name
- config = ConfigParser()
- if os.path.exists(config_file):
- try:
- with open(config_file, 'r') as cfg:
- config.readfp(cfg)
- except IOError, e:
- print "Error: config_file not found", e
-
- profile = None
- try:
- profile = get_attr('profile')
- except AttributeError, e:
- pass
- if profile is None or profile == '':
- profile = default_profile_name
- if profile in mandatory_sections:
- print "Server profile name cannot be '%s'" % profile
- sys.exit(1)
-
- has_profile_changed = False
- profile_in_use = default_profile_name
- try:
- profile_in_use = config.get('core', 'profile')
- except Exception:
- pass
- if profile_in_use != profile:
- has_profile_changed = True
-
- for section in (mandatory_sections + [profile]):
- if not config.has_section(section):
- try:
- config.add_section(section)
- if section not in mandatory_sections:
- for key in default_profile.keys():
- config.set(section, key, default_profile[key])
- else:
- for key in config_fields[section].keys():
- config.set(section, key, config_fields[section][key])
- except ValueError, e:
- print "Server profile name cannot be", profile
- sys.exit(1)
- if section in mandatory_sections:
- section_keys = config_fields[section].keys()
- else:
- section_keys = default_profile.keys()
- for key in section_keys:
- try:
- if not (has_profile_changed and section == profile):
- config.set(section, key, get_attr(key))
- except Exception:
- pass
- with open(config_file, 'w') as cfg:
- config.write(cfg)
- return config
-
-
-def read_config(get_attr, set_attr, config_file):
- global config_fields, config_dir, mandatory_sections
- global default_profile, default_profile_name
- if not os.path.exists(config_dir):
- os.makedirs(config_dir)
-
- config_options = reduce(lambda x, y: x + y, map(lambda x:
- config_fields[x].keys(), config_fields.keys()))
- config_options += default_profile.keys()
-
- config = ConfigParser()
- if os.path.exists(config_file):
- try:
- with open(config_file, 'r') as cfg:
- config.readfp(cfg)
- except IOError, e:
- print "Error: config_file not found", e
- else:
- config = write_config(get_attr, config_file)
- print "Welcome! Use the `set` command to configure options"
- print "Config file:", config_file
- print "After setting up, run the `sync` command to sync apis\n"
-
- missing_keys = []
- if config.has_option('core', 'profile'):
- profile = config.get('core', 'profile')
- else:
- global default_profile_name
- profile = default_profile_name
-
- if profile is None or profile == '' or profile in mandatory_sections:
- print "Server profile cannot be", profile
- sys.exit(1)
-
- set_attr("profile_names", filter(lambda x: x != "core" and x != "ui",
- config.sections()))
-
- if not config.has_section(profile):
- print ("Selected profile (%s) does not exist," +
- " using default values") % profile
- try:
- config.add_section(profile)
- except ValueError, e:
- print "Server profile name cannot be", profile
- sys.exit(1)
- for key in default_profile.keys():
- config.set(profile, key, default_profile[key])
-
- for section in (mandatory_sections + [profile]):
- if section in mandatory_sections:
- section_keys = config_fields[section].keys()
- else:
- section_keys = default_profile.keys()
- for key in section_keys:
- try:
- set_attr(key, config.get(section, key))
- except Exception, e:
- if section in mandatory_sections:
- set_attr(key, config_fields[section][key])
- else:
- set_attr(key, default_profile[key])
- missing_keys.append("%s = %s" % (key, get_attr(key)))
- # Cosmetic fix for prompt
- if key == 'prompt':
- set_attr(key, get_attr('prompt').strip() + " ")
-
- if len(missing_keys) > 0:
- print "Missing configuration was set using default values for keys:"
- print "`%s` in %s" % (', '.join(missing_keys), config_file)
- write_config(get_attr, config_file)
-
- return config_options
diff --git a/cloudmonkey/precache.py b/cloudmonkey/precache.py
deleted file mode 100644
index ac7d880..0000000
--- a/cloudmonkey/precache.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# -*- coding: utf-8 -*-
-# Auto-generated code by cachemaker.py
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you 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.
-apicache = {u'authorize': {u'securitygroupingress': {u'name': u'authorizeSecurityGroupIngress', u'related': [u'authorizeSecurityGroupEgress'], u'isasync': True, u'params': [{u'name': u'projectid', u'required': False, u'related': [u'listProjectAccounts', u'listProjects', u'activateProject', u'createProject', u'updateProject'], u'length': 255, u'type': u'uuid', u'description': u'an optional project of the security group'}, {u'name': u'cidrlist', u'required': False, u'related': [], u'length [...]
\ No newline at end of file
diff --git a/cloudmonkey/printer.py b/cloudmonkey/printer.py
deleted file mode 100644
index 29d5903..0000000
--- a/cloudmonkey/printer.py
+++ /dev/null
@@ -1,124 +0,0 @@
-# -*- coding: utf-8 -*-
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you 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.
-
-try:
- from pygments import highlight
- from pygments.console import ansiformat
- from pygments.formatter import Formatter
- from pygments.lexer import bygroups, RegexLexer
- from pygments.token import *
-
- import sys
-except ImportError, e:
- print e
-
-
-MONKEY_COLORS = {
- Token: '',
- Whitespace: 'reset',
- Text: 'reset',
-
- Name: 'green',
- Operator: 'teal',
- Operator.Word: 'lightgray',
- String: 'purple',
-
- Keyword: '_red_',
- Error: 'red',
- Literal: 'yellow',
- Number: 'blue',
-}
-
-
-def get_colorscheme():
- return MONKEY_COLORS
-
-
-class MonkeyLexer(RegexLexer):
- keywords = ['[a-z]*id', '"[a-z]*id"', '^[a-z A-Z]*:']
- attributes = ['[Tt]rue', '[Ff]alse']
- params = ['[a-z]*[Nn]ame', 'type', '[Ss]tate']
-
- uuid_rgx = r'[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}'
- date_rgx = r'[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9:]{8}[0-9+]{5}'
-
- def makelistre(lis):
- return r'(' + r'|'.join(lis) + r')'
-
- tokens = {
- 'root': [
- (r' ', Whitespace),
- (date_rgx, Number),
- (r'"' + date_rgx + r'"', Number),
- (uuid_rgx, Literal),
- (r'"' + uuid_rgx + r'"', Literal),
- (r'(?:\b\d+\b(?:-\b\d+|%)?)', Number),
- (r'^[-=]*\n', Operator.Word),
- (r'Error', Error),
- (makelistre(attributes), Literal),
- (makelistre(params) + r'( = )(.*)', bygroups(Name, Operator,
- String)),
- (makelistre(keywords), Keyword),
- (makelistre(params), Name),
- (r'(^[a-zA-Z]* )(=)', bygroups(Name, Operator)),
- (r'\S+', Text),
- ]
- }
-
- def analyse_text(text):
- npos = text.find('\n')
- if npos < 3:
- return False
- return text[0] == '[' and text[npos - 1] == ']'
-
-
-class MonkeyFormatter(Formatter):
- def __init__(self, **options):
- Formatter.__init__(self, **options)
- self.colorscheme = get_colorscheme()
-
- def format(self, tokensource, outfile):
- return Formatter.format(self, tokensource, outfile)
-
- def format_unencoded(self, tokensource, outfile):
- for ttype, value in tokensource:
- color = self.colorscheme.get(ttype)
- while color is None:
- ttype = ttype[:-1]
- color = self.colorscheme.get(ttype)
- if color:
- spl = value.split('\n')
- for line in spl[:-1]:
- if line:
- outfile.write(ansiformat(color, line))
- outfile.write('\n')
- if spl[-1]:
- outfile.write(ansiformat(color, spl[-1]))
- else:
- outfile.write(value)
-
-
-def monkeyprint(text):
- fmter = MonkeyFormatter()
- lexer = MonkeyLexer()
- lexer.encoding = 'utf-8'
- fmter.encoding = 'utf-8'
- if text.startswith("Error"):
- highlight(text, lexer, fmter, sys.stderr)
- else:
- highlight(text, lexer, fmter, sys.stdout)
diff --git a/cloudmonkey/requester.py b/cloudmonkey/requester.py
deleted file mode 100644
index 914854f..0000000
--- a/cloudmonkey/requester.py
+++ /dev/null
@@ -1,335 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you 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.
-
-try:
- import base64
- import hashlib
- import hmac
- import itertools
- import json
- import requests
- import ssl
- import sys
- import time
- import urllib
- import urllib2
-
- from datetime import datetime, timedelta
- from requests_toolbelt import SSLAdapter
- from urllib2 import HTTPError, URLError
-except ImportError, e:
- print "Import error in %s : %s" % (__name__, e)
- import sys
- sys.exit()
-
-
-# Disable HTTPS verification warnings.
-from requests.packages import urllib3
-urllib3.disable_warnings()
-
-
-def logger_debug(logger, message):
- if logger is not None:
- logger.debug(message)
-
-
-def writeError(msg):
- sys.stderr.write(msg)
- sys.stderr.write("\n")
- sys.stderr.flush()
-
-
-def login(url, username, password, domain="/", verifysslcert=False):
- """
- Login and obtain a session to be used for subsequent API calls
- Wrong username/password leads to HTTP error code 531
- """
- args = {}
-
- args["command"] = 'login'
- args["username"] = username
- args["password"] = password
- args["domain"] = domain
- args["response"] = "json"
-
- sessionkey = ''
- session = requests.Session()
- session.mount('https://', SSLAdapter(ssl.PROTOCOL_TLSv1))
-
- try:
- resp = session.post(url, params=args, verify=verifysslcert)
- except requests.exceptions.ConnectionError, e:
- writeError("Connection refused by server: %s" % e)
- return None, None
-
- if resp.status_code == 200:
- sessionkey = resp.json()['loginresponse']['sessionkey']
- elif resp.status_code == 405:
- writeError("Method not allowed, unauthorized access on URL: %s" % url)
- session = None
- sessionkey = None
- elif resp.status_code == 531:
- writeError("Error authenticating at %s using username: %s"
- ", password: %s, domain: %s" % (url, username, password,
- domain))
- session = None
- sessionkey = None
- else:
- resp.raise_for_status()
-
- return session, sessionkey
-
-
-def logout(url, session):
- if not session:
- return
- session.get(url, params={'command': 'logout'})
-
-
-def make_request_with_password(command, args, logger, url, credentials,
- verifysslcert=False):
- error = None
- args = args.copy()
- username = credentials['username']
- password = credentials['password']
- domain = credentials['domain']
-
- if not (username and password):
- error = "Username and password cannot be empty"
- result = None
- return result, error
-
- tries = 0
- retry = True
-
- while tries < 2 and retry:
- sessionkey = credentials.get('sessionkey')
- session = credentials.get('session')
- tries += 1
-
- # obtain a valid session if not supplied
- if not (session and sessionkey):
- session, sessionkey = login(url, username, password, domain,
- verifysslcert)
- if not (session and sessionkey):
- return None, 'Authentication failed'
- credentials['session'] = session
- credentials['sessionkey'] = sessionkey
-
- args['sessionkey'] = sessionkey
-
- # make the api call
- resp = session.get(url, params=args, verify=verifysslcert)
- result = resp.text
- logger_debug(logger, "Response received: %s" % resp.text)
-
- if resp.status_code == 200: # success
- retry = False
- break
- if resp.status_code == 401: # sessionkey is wrong
- credentials['session'] = None
- credentials['sessionkey'] = None
- continue
-
- if resp.status_code != 200 and resp.status_code != 401:
- error_message = resp.headers.get('X-Description')
- if not error_message:
- error_message = resp.text
- error = "{0}: {1}".format(resp.status_code, error_message)
- result = None
- retry = False
-
- return result, error
-
-
-def make_request(command, args, logger, url, credentials, expires,
- verifysslcert=False, signatureversion=3):
- result = None
- error = None
-
- if not url.startswith('http'):
- error = "Server URL should start with 'http' or 'https', " + \
- "please check and fix the url"
- return None, error
-
- if not args:
- args = {}
-
- args = args.copy()
- args["command"] = command
- args["response"] = "json"
- signatureversion = int(signatureversion)
- if signatureversion >= 3:
- args["signatureversion"] = signatureversion
- if not expires:
- expires = 600
- expirationtime = datetime.utcnow() + timedelta(seconds=int(expires))
- args["expires"] = expirationtime.strftime('%Y-%m-%dT%H:%M:%S+0000')
-
- for key in args.keys():
- value = args[key]
- if isinstance(value, unicode):
- value = value.encode("utf-8")
- args[key] = value
- if not key:
- args.pop(key)
-
- # try to use the apikey/secretkey method by default
- # followed by trying to check if we're using integration port
- # finally use the username/password method
- if not credentials['apikey'] and not ("8096" in url):
- try:
- return make_request_with_password(command, args, logger, url,
- credentials, verifysslcert)
- except (requests.exceptions.ConnectionError, Exception), e:
- return None, e
-
- def sign_request(params, secret_key):
- request = zip(params.keys(), params.values())
- request.sort(key=lambda x: x[0].lower())
- hash_str = "&".join(
- ["=".join(
- [r[0].lower(),
- urllib.quote_plus(str(r[1]), safe="*").lower()
- .replace("+", "%20").replace("%3A", ":")]
- ) for r in request]
- )
- return base64.encodestring(hmac.new(secret_key, hash_str,
- hashlib.sha1).digest()).strip()
-
- args['apiKey'] = credentials['apikey']
- args["signature"] = sign_request(args, credentials['secretkey'])
-
- session = requests.Session()
- session.mount('https://', SSLAdapter(ssl.PROTOCOL_TLSv1))
-
- try:
- response = session.get(url, params=args, verify=verifysslcert)
- logger_debug(logger, "Request sent: %s" % response.url)
- result = response.text
-
- if response.status_code == 200: # success
- error = None
- elif response.status_code == 401: # auth issue
- error = "401 Authentication error"
- elif response.status_code != 200 and response.status_code != 401:
- error = "{0}: {1}".format(response.status_code,
- response.headers.get('X-Description'))
- except requests.exceptions.ConnectionError, e:
- return None, "Connection refused by server: %s" % e
- except Exception, pokemon:
- error = pokemon.message
-
- logger_debug(logger, "Response received: %s" % result)
- if error is not None:
- logger_debug(logger, "Error: %s" % (error))
- return result, error
-
- return result, error
-
-
-def monkeyrequest(command, args, isasync, asyncblock, logger, url,
- credentials, timeout, expires, verifysslcert=False,
- signatureversion=3):
- response = None
- error = None
- logger_debug(logger, "======== START Request ========")
- logger_debug(logger, "Requesting command=%s, args=%s" % (command, args))
- response, error = make_request(command, args, logger, url,
- credentials, expires, verifysslcert,
- signatureversion)
-
- logger_debug(logger, "======== END Request ========\n")
-
- if error is not None and not response:
- return response, error
-
- def process_json(response):
- try:
- response = json.loads(response, "utf-8")
- except ValueError, e:
- logger_debug(logger, "Error processing json: %s" % e)
- writeError("Error processing json: %s" % e)
- response = None
- error = e
- return response
-
- response = process_json(response)
- if not response or not isinstance(response, dict):
- return response, error
-
- m = list(v for v in response.keys() if 'response' in v.lower())
- if not m:
- return response, 'Invalid response received: %s' % response
-
- isasync = isasync and (asyncblock == "true" or asyncblock == "True")
- responsekey = filter(lambda x: 'response' in x, response.keys())[0]
-
- if isasync and 'jobid' in response[responsekey]:
- jobid = response[responsekey]['jobid']
- command = "queryAsyncJobResult"
- request = {'jobid': jobid}
- if not timeout:
- timeout = 3600
- timeout = int(timeout)
- cursor = itertools.cycle([u'|', u'/', u'-', u'\\'])
- while timeout > 0:
- interval = 2
- while interval > 0:
- sys.stdout.write(u"%s\r" % cursor.next())
- sys.stdout.flush()
- time.sleep(0.1)
- interval -= 0.1
- timeout = timeout - 2
- logger_debug(logger, "Job %s to timeout in %ds" % (jobid, timeout))
-
- response, error = make_request(command, request, logger, url,
- credentials, expires, verifysslcert)
- if error and not response:
- return response, error
-
- response = process_json(response)
- responsekeys = filter(lambda x: 'response' in x, response.keys())
-
- if len(responsekeys) < 1:
- continue
-
- result = response[responsekeys[0]]
- if "errorcode" in result or "errortext" in result:
- return response, error
-
- jobstatus = result['jobstatus']
- if jobstatus == 2:
- jobresult = result["jobresult"]
- error = "\rAsync job %s failed\nError %s, %s" % (
- jobid, jobresult["errorcode"], jobresult["errortext"])
- return response, error
- elif jobstatus == 1:
- sys.stdout.write(u"\r \n")
- sys.stdout.flush()
- return response, error
- elif jobstatus == 0:
- pass # Job in progress
- else:
- logger_debug(logger, "We should not arrive here!")
- sys.stdout.flush()
-
- error = "Error: Async query timeout occurred for jobid %s" % jobid
-
- return response, error
diff --git a/config.docker b/config.docker
deleted file mode 100644
index 17c536a..0000000
--- a/config.docker
+++ /dev/null
@@ -1,25 +0,0 @@
-[core]
-profile = container
-asyncblock = true
-paramcompletion = true
-history_file = /cloudmonkey/history
-log_file = /cloudmonkey/log
-cache_file = /cloudmonkey/cache
-
-
-[ui]
-color = true
-prompt = >
-display = default
-
-[container]
-url = http://cloudstack:8080/client/api
-username = admin
-password = password
-apikey =
-secretkey =
-timeout = 3600
-expires = 600
-verifysslcert = false
-signatureversion = 3
-domain = /
\ No newline at end of file
diff --git a/docs/.gitignore b/docs/.gitignore
deleted file mode 100644
index e35d885..0000000
--- a/docs/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-_build
diff --git a/docs/Makefile b/docs/Makefile
deleted file mode 100644
index 681b3a3..0000000
--- a/docs/Makefile
+++ /dev/null
@@ -1,177 +0,0 @@
-# Makefile for Sphinx documentation
-#
-
-# You can set these variables from the command line.
-SPHINXOPTS =
-SPHINXBUILD = sphinx-build
-PAPER =
-BUILDDIR = build
-
-# User-friendly check for sphinx-build
-ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
-$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
-endif
-
-# Internal variables.
-PAPEROPT_a4 = -D latex_paper_size=a4
-PAPEROPT_letter = -D latex_paper_size=letter
-ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
-# the i18n builder cannot share the environment and doctrees with the others
-I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
-
-.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
-
-help:
- @echo "Please use \`make <target>' where <target> is one of"
- @echo " html to make standalone HTML files"
- @echo " dirhtml to make HTML files named index.html in directories"
- @echo " singlehtml to make a single large HTML file"
- @echo " pickle to make pickle files"
- @echo " json to make JSON files"
- @echo " htmlhelp to make HTML files and a HTML help project"
- @echo " qthelp to make HTML files and a qthelp project"
- @echo " devhelp to make HTML files and a Devhelp project"
- @echo " epub to make an epub"
- @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
- @echo " latexpdf to make LaTeX files and run them through pdflatex"
- @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
- @echo " text to make text files"
- @echo " man to make manual pages"
- @echo " texinfo to make Texinfo files"
- @echo " info to make Texinfo files and run them through makeinfo"
- @echo " gettext to make PO message catalogs"
- @echo " changes to make an overview of all changed/added/deprecated items"
- @echo " xml to make Docutils-native XML files"
- @echo " pseudoxml to make pseudoxml-XML files for display purposes"
- @echo " linkcheck to check all external links for integrity"
- @echo " doctest to run all doctests embedded in the documentation (if enabled)"
-
-clean:
- rm -rf $(BUILDDIR)/*
-
-html:
- $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
- @echo
- @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
-
-dirhtml:
- $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
- @echo
- @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
-
-singlehtml:
- $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
- @echo
- @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
-
-pickle:
- $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
- @echo
- @echo "Build finished; now you can process the pickle files."
-
-json:
- $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
- @echo
- @echo "Build finished; now you can process the JSON files."
-
-htmlhelp:
- $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
- @echo
- @echo "Build finished; now you can run HTML Help Workshop with the" \
- ".hhp project file in $(BUILDDIR)/htmlhelp."
-
-qthelp:
- $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
- @echo
- @echo "Build finished; now you can run "qcollectiongenerator" with the" \
- ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
- @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/ApacheCloudStackCloudMonkey.qhcp"
- @echo "To view the help file:"
- @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/ApacheCloudStackCloudMonkey.qhc"
-
-devhelp:
- $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
- @echo
- @echo "Build finished."
- @echo "To view the help file:"
- @echo "# mkdir -p $$HOME/.local/share/devhelp/ApacheCloudStackCloudMonkey"
- @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/ApacheCloudStackCloudMonkey"
- @echo "# devhelp"
-
-epub:
- $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
- @echo
- @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
-
-latex:
- $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
- @echo
- @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
- @echo "Run \`make' in that directory to run these through (pdf)latex" \
- "(use \`make latexpdf' here to do that automatically)."
-
-latexpdf:
- $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
- @echo "Running LaTeX files through pdflatex..."
- $(MAKE) -C $(BUILDDIR)/latex all-pdf
- @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
-
-latexpdfja:
- $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
- @echo "Running LaTeX files through platex and dvipdfmx..."
- $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
- @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
-
-text:
- $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
- @echo
- @echo "Build finished. The text files are in $(BUILDDIR)/text."
-
-man:
- $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
- @echo
- @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
-
-texinfo:
- $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
- @echo
- @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
- @echo "Run \`make' in that directory to run these through makeinfo" \
- "(use \`make info' here to do that automatically)."
-
-info:
- $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
- @echo "Running Texinfo files through makeinfo..."
- make -C $(BUILDDIR)/texinfo info
- @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
-
-gettext:
- $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
- @echo
- @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
-
-changes:
- $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
- @echo
- @echo "The overview file is in $(BUILDDIR)/changes."
-
-linkcheck:
- $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
- @echo
- @echo "Link check complete; look for any errors in the above output " \
- "or in $(BUILDDIR)/linkcheck/output.txt."
-
-doctest:
- $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
- @echo "Testing of doctests in the sources finished, look at the " \
- "results in $(BUILDDIR)/doctest/output.txt."
-
-xml:
- $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
- @echo
- @echo "Build finished. The XML files are in $(BUILDDIR)/xml."
-
-pseudoxml:
- $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
- @echo
- @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
diff --git a/docs/source/cloudmonkey.rst b/docs/source/cloudmonkey.rst
deleted file mode 100644
index 22bf625..0000000
--- a/docs/source/cloudmonkey.rst
+++ /dev/null
@@ -1,62 +0,0 @@
-cloudmonkey package
-===================
-
-Submodules
-----------
-
-cloudmonkey.cachemaker module
------------------------------
-
-.. automodule:: cloudmonkey.cachemaker
- :members:
- :undoc-members:
- :show-inheritance:
-
-cloudmonkey.cloudmonkey module
-------------------------------
-
-.. automodule:: cloudmonkey.cloudmonkey
- :members:
- :undoc-members:
- :show-inheritance:
-
-cloudmonkey.config module
--------------------------
-
-.. automodule:: cloudmonkey.config
- :members:
- :undoc-members:
- :show-inheritance:
-
-cloudmonkey.precache module
----------------------------
-
-.. automodule:: cloudmonkey.precache
- :members:
- :undoc-members:
- :show-inheritance:
-
-cloudmonkey.printer module
---------------------------
-
-.. automodule:: cloudmonkey.printer
- :members:
- :undoc-members:
- :show-inheritance:
-
-cloudmonkey.requester module
-----------------------------
-
-.. automodule:: cloudmonkey.requester
- :members:
- :undoc-members:
- :show-inheritance:
-
-
-Module contents
----------------
-
-.. automodule:: cloudmonkey
- :members:
- :undoc-members:
- :show-inheritance:
diff --git a/docs/source/conf.py b/docs/source/conf.py
deleted file mode 100644
index 9c30ccb..0000000
--- a/docs/source/conf.py
+++ /dev/null
@@ -1,262 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Apache CloudStack CloudMonkey documentation build configuration file, created by
-# sphinx-quickstart on Tue Sep 24 13:08:09 2013.
-#
-# This file is execfile()d with the current directory set to its
-# containing dir.
-#
-# Note that not all possible configuration values are present in this
-# autogenerated file.
-#
-# All configuration values have a default; values that are commented out
-# serve to show the default.
-
-import sys
-import os
-
-# If extensions (or modules to document with autodoc) are in another directory,
-# add these directories to sys.path here. If the directory is relative to the
-# documentation root, use os.path.abspath to make it absolute, like shown here.
-#sys.path.insert(0, os.path.abspath('.'))
-
-# -- General configuration ------------------------------------------------
-
-# If your documentation needs a minimal Sphinx version, state it here.
-#needs_sphinx = '1.0'
-
-# Add any Sphinx extension module names here, as strings. They can be
-# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
-# ones.
-extensions = [
- 'sphinx.ext.autodoc',
- 'sphinx.ext.coverage',
- 'sphinx.ext.viewcode',
-]
-
-# Add any paths that contain templates here, relative to this directory.
-templates_path = ['_templates']
-
-# The suffix of source filenames.
-source_suffix = '.rst'
-
-# The encoding of source files.
-#source_encoding = 'utf-8-sig'
-
-# The master toctree document.
-master_doc = 'index'
-
-# General information about the project.
-project = u'Apache CloudStack CloudMonkey'
-copyright = u'2012-2014, The Apache Software Foundation'
-
-# The version info for the project you're documenting, acts as replacement for
-# |version| and |release|, also used in various other places throughout the
-# built documents.
-#
-# The short X.Y version.
-version = '5.3.3'
-# The full version, including alpha/beta/rc tags.
-release = version
-
-# The language for content autogenerated by Sphinx. Refer to documentation
-# for a list of supported languages.
-#language = None
-
-# There are two options for replacing |today|: either, you set today to some
-# non-false value, then it is used:
-#today = ''
-# Else, today_fmt is used as the format for a strftime call.
-#today_fmt = '%B %d, %Y'
-
-# List of patterns, relative to source directory, that match files and
-# directories to ignore when looking for source files.
-exclude_patterns = []
-
-# The reST default role (used for this markup: `text`) to use for all
-# documents.
-#default_role = None
-
-# If true, '()' will be appended to :func: etc. cross-reference text.
-#add_function_parentheses = True
-
-# If true, the current module name will be prepended to all description
-# unit titles (such as .. function::).
-#add_module_names = True
-
-# If true, sectionauthor and moduleauthor directives will be shown in the
-# output. They are ignored by default.
-#show_authors = False
-
-# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
-
-# A list of ignored prefixes for module index sorting.
-#modindex_common_prefix = []
-
-# If true, keep warnings as "system message" paragraphs in the built documents.
-#keep_warnings = False
-
-
-# -- Options for HTML output ----------------------------------------------
-
-# The theme to use for HTML and HTML Help pages. See the documentation for
-# a list of builtin themes.
-html_theme = 'default'
-
-# Theme options are theme-specific and customize the look and feel of a theme
-# further. For a list of options available for each theme, see the
-# documentation.
-#html_theme_options = {}
-
-# Add any paths that contain custom themes here, relative to this directory.
-#html_theme_path = []
-
-# The name for this set of Sphinx documents. If None, it defaults to
-# "<project> v<release> documentation".
-#html_title = None
-
-# A shorter title for the navigation bar. Default is the same as html_title.
-#html_short_title = None
-
-# The name of an image file (relative to this directory) to place at the top
-# of the sidebar.
-#html_logo = None
-
-# The name of an image file (within the static path) to use as favicon of the
-# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
-# pixels large.
-#html_favicon = None
-
-# Add any paths that contain custom static files (such as style sheets) here,
-# relative to this directory. They are copied after the builtin static files,
-# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['_static']
-
-# Add any extra paths that contain custom files (such as robots.txt or
-# .htaccess) here, relative to this directory. These files are copied
-# directly to the root of the documentation.
-#html_extra_path = []
-
-# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
-# using the given strftime format.
-#html_last_updated_fmt = '%b %d, %Y'
-
-# If true, SmartyPants will be used to convert quotes and dashes to
-# typographically correct entities.
-#html_use_smartypants = True
-
-# Custom sidebar templates, maps document names to template names.
-#html_sidebars = {}
-
-# Additional templates that should be rendered to pages, maps page names to
-# template names.
-#html_additional_pages = {}
-
-# If false, no module index is generated.
-#html_domain_indices = True
-
-# If false, no index is generated.
-#html_use_index = True
-
-# If true, the index is split into individual pages for each letter.
-#html_split_index = False
-
-# If true, links to the reST sources are added to the pages.
-#html_show_sourcelink = True
-
-# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
-#html_show_sphinx = True
-
-# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
-#html_show_copyright = True
-
-# If true, an OpenSearch description file will be output, and all pages will
-# contain a <link> tag referring to it. The value of this option must be the
-# base URL from which the finished HTML is served.
-#html_use_opensearch = ''
-
-# This is the file name suffix for HTML files (e.g. ".xhtml").
-#html_file_suffix = None
-
-# Output file base name for HTML help builder.
-htmlhelp_basename = 'ApacheCloudStackCloudMonkeydoc'
-
-
-# -- Options for LaTeX output ---------------------------------------------
-
-latex_elements = {
-# The paper size ('letterpaper' or 'a4paper').
-#'papersize': 'letterpaper',
-
-# The font size ('10pt', '11pt' or '12pt').
-#'pointsize': '10pt',
-
-# Additional stuff for the LaTeX preamble.
-#'preamble': '',
-}
-
-# Grouping the document tree into LaTeX files. List of tuples
-# (source start file, target name, title,
-# author, documentclass [howto/manual]).
-latex_documents = [
- ('index', 'ApacheCloudStackCloudMonkey.tex', u'Apache CloudStack CloudMonkey Documentation',
- u'The Apache Software Foundation', 'manual'),
-]
-
-# The name of an image file (relative to this directory) to place at the top of
-# the title page.
-#latex_logo = None
-
-# For "manual" documents, if this is true, then toplevel headings are parts,
-# not chapters.
-#latex_use_parts = False
-
-# If true, show page references after internal links.
-#latex_show_pagerefs = False
-
-# If true, show URL addresses after external links.
-#latex_show_urls = False
-
-# Documents to append as an appendix to all manuals.
-#latex_appendices = []
-
-# If false, no module index is generated.
-#latex_domain_indices = True
-
-
-# -- Options for manual page output ---------------------------------------
-
-# One entry per manual page. List of tuples
-# (source start file, name, description, authors, manual section).
-man_pages = [
- ('index', 'apachecloudstackcloudmonkey', u'Apache CloudStack CloudMonkey Documentation',
- [u'The Apache Software Foundation'], 1)
-]
-
-# If true, show URL addresses after external links.
-#man_show_urls = False
-
-
-# -- Options for Texinfo output -------------------------------------------
-
-# Grouping the document tree into Texinfo files. List of tuples
-# (source start file, target name, title, author,
-# dir menu entry, description, category)
-texinfo_documents = [
- ('index', 'ApacheCloudStackCloudMonkey', u'Apache CloudStack CloudMonkey Documentation',
- u'The Apache Software Foundation', 'ApacheCloudStackCloudMonkey', 'One line description of project.',
- 'Miscellaneous'),
-]
-
-# Documents to append as an appendix to all manuals.
-#texinfo_appendices = []
-
-# If false, no module index is generated.
-#texinfo_domain_indices = True
-
-# How to display URL addresses: 'footnote', 'no', or 'inline'.
-#texinfo_show_urls = 'footnote'
-
-# If true, do not generate a @detailmenu in the "Top" node's menu.
-#texinfo_no_detailmenu = False
diff --git a/docs/source/index.rst b/docs/source/index.rst
deleted file mode 100644
index bbb18ed..0000000
--- a/docs/source/index.rst
+++ /dev/null
@@ -1,37 +0,0 @@
-Apache CloudStack CloudMonkey
-=============================
-
-The Apache CloudStack CloudMonkey is a command line interface (CLI) tool for CloudStack written in Python. cloudmonkey
-can be use both as an interactive shell and as a command line tool which simplifies CS configuration and management.
-
-**Features**
-
-#. Usable as a command line tool and interactive shell
-#. All commands are lowercase unlike API
-#. Api Discovery using sync feature, with build time api precaching for failsafe sync
-#. Raw api execution support
-#. Auto-completion via double <tab>
-#. Reverse search using Ctrl+R
-#. Emacs compatible keybindings
-#. Pipeable output
-#. Unix shell execution
-#. Support to handle async jobs using user defined blocking or non-blocking way
-#. Tabular or JSON output with filtering of table columns
-#. Colored output
-#. Api parameter value completion (based on predication, fuzzy results may fail sometimes)
-#. Use apikey and secretkey or username/password
-
-Instructions for working with CloudMonkey can be found here:
-
-https://cwiki.apache.org/confluence/display/CLOUDSTACK/CloudStack+cloudmonkey+CLI
-
-.. toctree::
- :maxdepth: 2
-
-Indices and tables
-==================
-
-* :ref:`genindex`
-* :ref:`modindex`
-* :ref:`search`
-
diff --git a/docs/source/modules.rst b/docs/source/modules.rst
deleted file mode 100644
index 2b7efb5..0000000
--- a/docs/source/modules.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-cloudmonkey
-===========
-
-.. toctree::
- :maxdepth: 4
-
- cloudmonkey
diff --git a/setup.cfg b/setup.cfg
deleted file mode 100644
index 649ed60..0000000
--- a/setup.cfg
+++ /dev/null
@@ -1,7 +0,0 @@
-[build_sphinx]
-source-dir = docs/source
-build-dir = docs/build
-all_files = 1
-
-[upload_sphinx]
-upload-dir = docs/build/html
diff --git a/setup.py b/setup.py
deleted file mode 100644
index 4422328..0000000
--- a/setup.py
+++ /dev/null
@@ -1,86 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you 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.
-
-try:
- from setuptools import setup, find_packages
-except ImportError:
- from distribute_setup import use_setuptools
- use_setuptools()
- from setuptools import setup, find_packages
-
-import sys
-
-from cloudmonkey import __version__, __description__
-from cloudmonkey import __maintainer__, __maintaineremail__
-from cloudmonkey import __project__, __projecturl__, __projectemail__
-
-requires = [
- 'Pygments>=1.5',
- 'argcomplete',
- 'dicttoxml',
- 'prettytable>=0.6',
- 'requests',
- 'requests-toolbelt',
- ]
-
-try:
- import readline
-except ImportError:
- platform = str(sys.platform).lower()
- if 'win32' in platform or 'win64' in platform:
- requires.append('pyreadline')
- else:
- requires.append('readline')
-
-# Upgrade notes for 5.3.0
-print "If you're upgrading, run the following to enable parameter completion:"
-print " cloudmonkey sync"
-print " cloudmonkey set paramcompletion true"
-print "Parameter completion may fail, if the above is not run!"
-
-setup(
- name = 'cloudmonkey',
- version = __version__,
- author = __project__,
- author_email = __projectemail__,
- maintainer = __maintainer__,
- maintainer_email = __maintaineremail__,
- url = __projecturl__,
- description = __description__,
- long_description = "cloudmonkey is a CLI for Apache CloudStack",
- platforms = ("Any",),
- license = 'ASL 2.0',
- packages = find_packages(),
- install_requires = requires,
- include_package_data = True,
- zip_safe = False,
- classifiers = [
- "Development Status :: 5 - Production/Stable",
- "Environment :: Console",
- "Intended Audience :: Developers",
- "Intended Audience :: End Users/Desktop",
- "Operating System :: OS Independent",
- "Programming Language :: Python",
- "Topic :: Software Development :: Testing",
- "Topic :: Software Development :: Interpreters",
- "Topic :: Utilities",
- ],
- entry_points="""
- [console_scripts]
- cloudmonkey = cloudmonkey.cloudmonkey:main
- """,
-)
--
To stop receiving notification emails like this one, please contact
rohit@apache.org.