marvin: code generator for marvin base library The generateBase.py will give out Entity.(create|update|list|delete) style python modules for use by the integration library.
Signed-off-by: Prasanna Santhanam <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/ddd76602 Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/ddd76602 Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/ddd76602 Branch: refs/heads/marvin-refactor Commit: ddd76602a5f3e85bbc9d0cbc7c6cc4554366718c Parents: 75b059e Author: Prasanna Santhanam <[email protected]> Authored: Wed Jan 23 16:30:02 2013 +0530 Committer: Prasanna Santhanam <[email protected]> Committed: Wed Jan 23 17:56:58 2013 +0530 ---------------------------------------------------------------------- tools/apidoc/gen_toc.py | 1 + .../marvin/marvin/integration/lib/generateBase.py | 112 +++++++++++++++ 2 files changed, 113 insertions(+), 0 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ddd76602/tools/apidoc/gen_toc.py ---------------------------------------------------------------------- diff --git a/tools/apidoc/gen_toc.py b/tools/apidoc/gen_toc.py index 7739aea..88393b2 100644 --- a/tools/apidoc/gen_toc.py +++ b/tools/apidoc/gen_toc.py @@ -130,6 +130,7 @@ known_categories = { 'Counter': 'AutoScale', 'Condition': 'AutoScale', 'Api': 'API Discovery', + 'Simulator': 'Simulator', } http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/ddd76602/tools/marvin/marvin/integration/lib/generateBase.py ---------------------------------------------------------------------- diff --git a/tools/marvin/marvin/integration/lib/generateBase.py b/tools/marvin/marvin/integration/lib/generateBase.py new file mode 100644 index 0000000..2f603ee --- /dev/null +++ b/tools/marvin/marvin/integration/lib/generateBase.py @@ -0,0 +1,112 @@ +# 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. + +import marvin +from marvin.cloudstackAPI import * + +# Add verbs in grammar - same as cloudmonkey +grammar = ['create', 'list', 'delete', 'update', + 'enable', 'activate', 'disable', 'add', 'remove', + 'attach', 'detach', 'associate', 'generate', 'ldap', + 'assign', 'authorize', 'change', 'register', 'configure', + 'start', 'restart', 'reboot', 'stop', 'reconnect', + 'cancel', 'destroy', 'revoke', 'mark', 'reset', + 'copy', 'extract', 'migrate', 'restore', 'suspend', + 'get', 'query', 'prepare', 'deploy', 'upload', 'lock', 'disassociate'] + +def get_api_cmds(): + api_classes = __import__('marvin.cloudstackAPI') + + cmdlist = map( + lambda f: getattr(api_classes.cloudstackAPI, f), + filter( + lambda t: t.startswith('__') == False, + dir(api_classes.cloudstackAPI) + ) + ) + + cmdlist = filter( + lambda g: g is not None, + cmdlist + ) + + clslist = map( + lambda g: getattr(g, g.__name__.split('.')[-1] + 'Cmd'), + filter( + lambda h: h.__name__.split('.')[-1] not in ['baseCmd', 'baseResponse', 'cloudstackAPIClient'], + cmdlist + ) + ) + + cmdlets = map(lambda t: t(), clslist) + return cmdlets + +def get_entity_from_api(api): + matching_verbs = filter(lambda v: api.__class__.__name__.startswith(v), grammar) + if len(matching_verbs) > 0: + verb = matching_verbs[0] + entity = api.__class__.__name__.replace(verb, '').replace('Cmd', '') + return entity + +def get_actionable_entities(): + cmdlets = sorted(get_api_cmds(), key=lambda k: get_entity_from_api(k)) + entities = {} + for cmd in cmdlets: + requireds = getattr(cmd, 'required') + optionals = filter(lambda x: '__' not in x and 'required' not in x and 'isAsync' not in x, dir(cmd)) + matching_verbs = filter(lambda v: cmd.__class__.__name__.startswith(v), grammar) + if len(matching_verbs)> 0: + verb = matching_verbs[0] + entity = cmd.__class__.__name__.replace(verb, '').replace('Cmd', '') + if entity[:-1] in entities: + # Accounts and Account are the same entity + entity = entity[:-1] + if entity[:-2] in entities: + # IpAddresses and IpAddress are the same entity + entity = entity[:-2] + if entity not in entities: + entities[entity] = { } + entities[entity][verb] = [requireds,optionals] + return entities + +def write_entity_classes(entities): + tabspace = ' ' + classlist = [] + code = '' + for entity, actions in entities.iteritems(): + code += 'class %s:'%entity + for action, args in actions.iteritems(): + code += '\n\n' + code += tabspace + code += 'def %s(self, apiclient, %sFactory=None'%(action, entity) + if len(args[0]) > 0: + code += ', ' + ', '.join(args[0]) + if len(args[1]) > 0: + code += ', **kwargs):\n' + else: + code += '):\n' + code += tabspace*2 + code += 'pass' + code += '\n\n' + classlist.append(code) + return list(set(classlist)) + +if __name__=='__main__': + entities = get_actionable_entities() + clslist = write_entity_classes(entities) + for cls in clslist: + print cls
