From 6bae7683b8f686018c7a67f6dbedd5af4cd056bb Mon Sep 17 00:00:00 2001 From: Salvatore Orlando Date: Mon, 5 Sep 2011 18:23:18 +0100 Subject: [PATCH] Updating CLI for not using Cheetah anymore. Now using a mechanism based on Python built-in templates. --- quantum/cli_lib.py | 126 ++++++++++++++++++++++++++++++++---- quantum/cli_output.template | 56 ---------------- tools/pip-requires | 1 - 3 files changed, 115 insertions(+), 68 deletions(-) delete mode 100644 quantum/cli_output.template diff --git a/quantum/cli_lib.py b/quantum/cli_lib.py index bfee9ac43..1e6e8200d 100755 --- a/quantum/cli_lib.py +++ b/quantum/cli_lib.py @@ -19,16 +19,125 @@ # @author: Brad Hall, Nicira Networks, Inc. # @author: Salvatore Orlando, Citrix -import Cheetah.Template as cheetah_template +""" Functions providing implementation for CLI commands. """ + import logging import os import sys FORMAT = "json" -CLI_TEMPLATE = "cli_output.template" LOG = logging.getLogger('quantum.cli_lib') +class OutputTemplate(object): + """ A class for generating simple templated output. + Based on Python templating mechanism. + Templates can also express attributes on objects, such as network.id; + templates can also be nested, thus allowing for iteration on inner + templates. + + Examples: + 1) template with class attributes + Name: %(person.name)s \n + Surname: %(person.surname)s \n + 2) template with iteration + Telephone numbers: \n + %(phone_numbers|Telephone number:%(number)s) + 3) template with iteration and class attributes + Addresses: \n + %(Addresses|Street:%(address.street)s\nNumber%(address.number)) + + Instances of this class are initialized with a template string and + the dictionary for performing substition. The class implements the + __str__ method, so it can be directly printed. + """ + + def __init__(self, template, data): + self._template = template + self.data = data + + def __str__(self): + return self._template % self + + def __getitem__(self, key): + items = key.split("|") + if len(items) == 1: + return self._make_attribute(key) + else: + # Note(salvatore-orlando): items[0] must be subscriptable + return self._make_list(self.data[items[0]], items[1]) + + def _make_attribute(self, item): + """ Renders an entity attribute key in the template. + e.g.: entity.attribute + """ + items = item.split('.') + if len(items) == 1: + return self.data[item] + else: + return self.data[items[0]][items[1]] + + def _make_list(self, items, inner_template): + """ Renders a list key in the template. + e.g.: %(list|item data:%(item)) + """ + #make sure list is subscriptable + if not hasattr(items, '__getitem__'): + return inner_template % items + return "\n".join([inner_template % item for item in items]) + + +class CmdOutputTemplate(OutputTemplate): + """ This class provides templated output for CLI commands. + Extends OutputTemplate loading a different template for each command. + """ + + _templates = { + "list_nets": "Virtual Networks for Tenant %(tenant_id)s\n" + + "%(networks|\tNetwork ID: %(id)s)s", + "show_net": "Network ID: %(network.id)s\n" + + "network Name: %(network.name)s", + "create_net": "Created a new Virtual Network with ID: " + + "%(network_id)s\n" + + "for Tenant: %(tenant_id)s", + "rename_net": "Renamed Virtual Network with ID: %(network.id)s\n" + + "for Tenant: %(tenant_id)s\n" + + "new name is: %(network.name)s", + "delete_net": "Deleted Virtual Network with ID: %(network_id)s\n" + + "for Tenant %(tenant_id)s", + "list_ports": "Ports on Virtual Network: %(network_id)s\n" + + "for Tenant: %(tenant_id)s\n" + + "%(ports|\tLogical Port: %(id)s)s", + "create_port": "Created new Logical Port with ID: %(port_id)s\n" + + "on Virtual Network: %(network_id)s\n" + + "for Tenant: %(tenant_id)s", + "show_port": "Logical Port ID: %(port.id)s\n" + + "administrative State: %(port.state)s\n" + + "interface: %(port.attachment)s\n" + + "on Virtual Network: %(network_id)s\n" + + "for Tenant: %(tenant_id)s", + "set_port_state": "Updated state for Logical Port " + + "with ID: %(port.id)s\n" + + "new state is: %(port.state)s\n" + + "on Virtual Network: %(network_id)s\n" + + "for tenant: %(tenant_id)s", + "delete_port": "Deleted Logical Port with ID: %(port_id)s\n" + + "on Virtual Network: %(network_id)s\n" + + "for Tenant: %(tenant_id)s", + "plug_iface": "Plugged interface %(attachment)s\n" + + "into Logical Port: %(port_id)s\n" + + "on Virtual Network: %(network_id)s\n" + + "for Tenant: %(tenant_id)s", + "unplug_iface": "Unplugged interface from Logical Port:" + + "%(port_id)s\n" + + "on Virtual Network: %(network_id)s\n" + + "for Tenant: %(tenant_id)s" + } + + def __init__(self, cmd, data): + super(CmdOutputTemplate, self).__init__(self._templates[cmd], data) + + def _handle_exception(ex): LOG.exception(sys.exc_info()) print "Exception:%s - %s" % (sys.exc_info()[0], sys.exc_info()[1]) @@ -47,15 +156,9 @@ def _handle_exception(ex): def prepare_output(cmd, tenant_id, response): - """ Fills a cheetah template with the response """ - #add command and tenant to response for output generation LOG.debug("Preparing output for response:%s", response) - response['cmd'] = cmd response['tenant_id'] = tenant_id - template_path = os.path.join(os.path.dirname(__file__), CLI_TEMPLATE) - template_file = open(template_path).read() - output = str(cheetah_template.Template(template_file, - searchList=response)) + output = str(CmdOutputTemplate(cmd, response)) LOG.debug("Finished preparing output for command:%s", cmd) return output @@ -77,7 +180,7 @@ def create_net(client, *args): new_net_id = res["network"]["id"] LOG.debug("Operation 'create_network' executed.") output = prepare_output("create_net", tenant_id, - dict(network_id=new_net_id)) + dict(network_id=new_net_id)) print output except Exception as ex: _handle_exception(ex) @@ -102,7 +205,8 @@ def show_net(client, *args): # output for GET /networks/{net-id} API operation res = client.show_network_details(network_id)["network"] LOG.debug("Operation 'show_network_details' executed.") - output = prepare_output("show_net", tenant_id, dict(network=res)) + output = prepare_output("show_net", tenant_id, + dict(network=res)) print output except Exception as ex: _handle_exception(ex) diff --git a/quantum/cli_output.template b/quantum/cli_output.template deleted file mode 100644 index 107dceb93..000000000 --- a/quantum/cli_output.template +++ /dev/null @@ -1,56 +0,0 @@ -## Cheetah template for cli output -#if $cmd == 'list_nets' -Virtual Networks for Tenant $tenant_id -#for $network in $networks - Network ID: $network.id -#end for -#elif $cmd == 'create_net' -Created a new Virtual Network with ID: $network_id -for Tenant $tenant_id -#elif $cmd == 'delete_net' -Deleted Virtual Network with ID: $network_id -for Tenant $tenant_id -#elif $cmd == 'show_net' -Network ID: $network.id -Network Name: $network.name -for Tenant: $tenant_id -#elif $cmd == 'rename_net' -Renamed Virtual Network with ID: $network.id -New name is: $network.name -for Tenant $tenant_id, -#elif $cmd == 'list_ports' -Ports on Virtual Network: $network_id -for Tenant: $tenant_id -#for $port in $ports - Logical Port: $port.id -#end for -#elif $cmd == 'create_port' -Created new Logical Port with ID: $port_id -on Virtual Network: $network_id -for Tenant: $tenant_id -#elif $cmd == 'delete_port' -Deleted Logical Port with ID: $port_id -on Virtual Network: $network_id -for Tenant: $tenant_id -#elif $cmd == 'set_port_state' -Updated state for Logical Port with ID: $port.id -new state is: $port.state -on Virtual Network: $network_id -for tenant: $tenant_id -#elif $cmd == 'show_port' -Logical Port ID: $port.id -administrative State: $port.state -interface: $port.attachment -on Virtual Network: $network_id -for Tenant: $tenant_id -#elif $cmd == 'plug_iface' -Plugged interface $attachment -into Logical Port: $port_id -on Virtual Network: $network_id -for Tenant: $tenant_id -#elif $cmd == 'unplug_iface' -Unplugged interface from Logical Port: $port_id -on Virtual Network: $network_id -for Tenant: $tenant_id -#end if - diff --git a/tools/pip-requires b/tools/pip-requires index baa07210c..31b66c77f 100644 --- a/tools/pip-requires +++ b/tools/pip-requires @@ -1,6 +1,5 @@ eventlet>=0.9.12 Routes>=1.12.3 -Cheetah>=2.0.1 nose Paste PasteDeploy -- 2.45.2