diff --git a/quantum/client/__init__.py b/quantum/client/__init__.py index 861d4a0a4..7b43b977c 100644 --- a/quantum/client/__init__.py +++ b/quantum/client/__init__.py @@ -167,6 +167,7 @@ class Client(object): ports_path = "/networks/%s/ports" port_path = "/networks/%s/ports/%s" attachment_path = "/networks/%s/ports/%s/attachment" + detail_path = "/detail" def __init__(self, host="127.0.0.1", port=9696, use_ssl=False, tenant=None, format="xml", testingStub=None, key_file=None, cert_file=None, @@ -347,12 +348,27 @@ def list_networks(self): """ return self.do_request("GET", self.networks_path) + @ApiCall + def list_networks_details(self): + """ + Fetches a detailed list of all networks for a tenant + """ + return self.do_request("GET", self.networks_path + self.detail_path) + + @ApiCall + def show_network(self, network): + """ + Fetches information of a certain network + """ + return self.do_request("GET", self.network_path % (network)) + @ApiCall def show_network_details(self, network): """ Fetches the details of a certain network """ - return self.do_request("GET", self.network_path % (network)) + return self.do_request("GET", (self.network_path + self.detail_path) + % (network)) @ApiCall def create_network(self, body=None): @@ -382,12 +398,28 @@ def list_ports(self, network): """ return self.do_request("GET", self.ports_path % (network)) + @ApiCall + def list_ports_details(self, network): + """ + Fetches a detailed list of ports on a given network + """ + return self.do_request("GET", (self.ports_path + self.detail_path) + % (network)) + + @ApiCall + def show_port(self, network, port): + """ + Fetches the information of a certain port + """ + return self.do_request("GET", self.port_path % (network, port)) + @ApiCall def show_port_details(self, network, port): """ Fetches the details of a certain port """ - return self.do_request("GET", self.port_path % (network, port)) + return self.do_request("GET", (self.port_path + self.detail_path) + % (network, port)) @ApiCall def create_port(self, network, body=None): @@ -449,6 +481,14 @@ def list_networks(self, **filters): # Pass filters in "params" argument to do_request return self.do_request("GET", self.networks_path, params=filters) + @ApiCall + def list_networks_details(self, **filters): + """ + Fetches a detailed list of all networks for a tenant + """ + return self.do_request("GET", self.networks_path + self.detail_path, + params=filters) + @ApiCall def list_ports(self, network, **filters): """ @@ -457,3 +497,12 @@ def list_ports(self, network, **filters): # Pass filters in "params" argument to do_request return self.do_request("GET", self.ports_path % (network), params=filters) + + @ApiCall + def list_ports_details(self, network, **filters): + """ + Fetches a detailed list of ports on a given network + """ + return self.do_request("GET", (self.ports_path + self.detail_path) + % (network), + params=filters) diff --git a/quantum/client/cli.py b/quantum/client/cli.py index d2337fe7e..18e0a6a2e 100755 --- a/quantum/client/cli.py +++ b/quantum/client/cli.py @@ -51,6 +51,9 @@ "list_nets": { "func": cli_lib.list_nets, "args": ["tenant-id"]}, + "list_nets_detail": { + "func": cli_lib.list_nets_detail, + "args": ["tenant-id"]}, "create_net": { "func": cli_lib.create_net, "args": ["tenant-id", "net-name"]}, @@ -60,12 +63,18 @@ "show_net": { "func": cli_lib.show_net, "args": ["tenant-id", "net-id"]}, - "update_net": { + "show_net_detail": { + "func": cli_lib.show_net_detail, + "args": ["tenant-id", "net-id"]}, + "update_net": { "func": cli_lib.update_net, "args": ["tenant-id", "net-id", "new-name"]}, "list_ports": { "func": cli_lib.list_ports, "args": ["tenant-id", "net-id"]}, + "list_ports_detail": { + "func": cli_lib.list_ports_detail, + "args": ["tenant-id", "net-id"]}, "create_port": { "func": cli_lib.create_port, "args": ["tenant-id", "net-id"]}, @@ -78,11 +87,17 @@ "show_port": { "func": cli_lib.show_port, "args": ["tenant-id", "net-id", "port-id"]}, + "show_port_detail": { + "func": cli_lib.show_port_detail, + "args": ["tenant-id", "net-id", "port-id"]}, "plug_iface": { "func": cli_lib.plug_iface, "args": ["tenant-id", "net-id", "port-id", "iface-id"]}, "unplug_iface": { "func": cli_lib.unplug_iface, + "args": ["tenant-id", "net-id", "port-id"]}, + "show_iface": { + "func": cli_lib.show_iface, "args": ["tenant-id", "net-id", "port-id"]}, } commands_v11 = commands_v10.copy() @@ -92,10 +107,19 @@ "args": ["tenant-id"], "filters": ["name", "op-status", "port-op-status", "port-state", "has-attachment", "attachment", "port"]}, + "list_nets_detail": { + "func": cli_lib.list_nets_detail_v11, + "args": ["tenant-id"], + "filters": ["name", "op-status", "port-op-status", "port-state", + "has-attachment", "attachment", "port"]}, "list_ports": { "func": cli_lib.list_ports_v11, "args": ["tenant-id", "net-id"], "filters": ["name", "op-status", "has-attachment", "attachment"]}, + "list_ports_detail": { + "func": cli_lib.list_ports_detail_v11, + "args": ["tenant-id", "net-id"], + "filters": ["name", "op-status", "has-attachment", "attachment"]}, }) commands = { '1.0': commands_v10, @@ -275,3 +299,6 @@ def main(): LOG.info("Command execution completed") sys.exit(0) + +if __name__ == '__main__': + main() diff --git a/quantum/client/cli_lib.py b/quantum/client/cli_lib.py index 8d73695e1..83cd14972 100755 --- a/quantum/client/cli_lib.py +++ b/quantum/client/cli_lib.py @@ -47,7 +47,7 @@ class OutputTemplate(object): %(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 + the dictionary for performing substitution. The class implements the __str__ method, so it can be directly printed. """ @@ -60,21 +60,25 @@ def __str__(self): def __getitem__(self, key): items = key.split("|") + # Note(madhav-puri): for now the logic supports only 0 or 1 list + # indicators (|) in a template. + if len(items) > 2: + raise Exception("Found more than one list indicator (|).") 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]) + return self._make_list(self._make_attribute(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] - elif len(items) == 2: - return self.data[items[0]][items[1]] + attr = self.data[items[0]] + for _item in items[1:]: + attr = attr[_item] + return attr def _make_list(self, items, inner_template): """ Renders a list key in the template. @@ -83,7 +87,8 @@ def _make_list(self, items, inner_template): #make sure list is subscriptable if not hasattr(items, '__getitem__'): raise Exception("Element is not iterable") - return "\n".join([inner_template % item for item in items]) + return "\n".join([str(OutputTemplate(inner_template, item)) + for item in items]) class CmdOutputTemplate(OutputTemplate): @@ -92,55 +97,88 @@ class CmdOutputTemplate(OutputTemplate): """ _templates_v10 = { - "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", - "update_net": "Updated Virtual Network with ID: %(network.id)s\n" + - "for Tenant: %(tenant_id)s\n", - "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", - "update_port": "Updated Logical Port " + - "with ID: %(port.id)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"} + "list_nets": "Virtual Networks for Tenant %(tenant_id)s\n" + + "%(networks|\tNetwork ID: %(id)s)s", + "list_nets_detail": "Virtual Networks for Tenant %(tenant_id)s\n" + + "%(networks|\tNetwork %(name)s with ID: %(id)s)s", + "show_net": "Network ID: %(network.id)s\n" + + "Network Name: %(network.name)s", + "show_net_detail": "Network ID: %(network.id)s\n" + + "Network Name: %(network.name)s\n" + + "Ports: %(network.ports|\tID: %(id)s\n" + + "\t\tadministrative state: %(state)s\n" + + "\t\tinterface: %(attachment.id)s)s", + "create_net": "Created a new Virtual Network with ID: " + + "%(network_id)s\n" + + "for Tenant: %(tenant_id)s", + "update_net": "Updated Virtual Network with ID: " + + "%(network.id)s\n" + + "for Tenant: %(tenant_id)s\n", + "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", + "list_ports_detail": "Ports on Virtual Network: %(network_id)s\n" + + "for Tenant: %(tenant_id)s\n" + + "%(ports|\tLogical Port: %(id)s\n" + + "\t\tadministrative State: %(state)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" + + "on Virtual Network: %(network_id)s\n" + + "for Tenant: %(tenant_id)s", + "show_port_detail": "Logical Port ID: %(port.id)s\n" + + "administrative State: %(port.state)s\n" + + "interface: %(port.attachment.id)s\n" + + "on Virtual Network: %(network_id)s\n" + + "for Tenant: %(tenant_id)s", + "update_port": "Updated Logical Port " + + "with ID: %(port.id)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", + "show_iface": "interface: %(iface.id)s\n" + + "plugged in Logical Port ID: %(port_id)s\n" + + "on Virtual Network: %(network_id)s\n" + + "for Tenant: %(tenant_id)s"} _templates_v11 = _templates_v10.copy() _templates_v11.update({ - "show_net": "Network ID: %(network.id)s\n" + - "network Name: %(network.name)s\n" + - "operational Status: %(network.op-status)s", - "show_port": "Logical Port ID: %(port.id)s\n" + - "administrative state: %(port.state)s\n" + - "operational status: %(port.op-status)s\n" + - "interface: %(port.attachment)s\n" + - "on Virtual Network: %(network_id)s\n" + - "for Tenant: %(tenant_id)s", + "show_net": "Network ID: %(network.id)s\n" + + "network Name: %(network.name)s\n" + + "operational Status: %(network.op-status)s", + "show_net_detail": "Network ID: %(network.id)s\n" + + "Network Name: %(network.name)s\n" + + "operational Status: %(network.op-status)s\n" + + "Ports: %(network.ports|\tID: %(id)s\n" + + "\t\tadministrative state: %(state)s\n" + + "\t\tinterface: %(attachment.id)s)s", + "show_port": "Logical Port ID: %(port.id)s\n" + + "administrative state: %(port.state)s\n" + + "operational status: %(port.op-status)s\n" + + "on Virtual Network: %(network_id)s\n" + + "for Tenant: %(tenant_id)s", + "show_port_detail": "Logical Port ID: %(port.id)s\n" + + "administrative State: %(port.state)s\n" + + "operational status: %(port.op-status)s\n" + + "interface: %(port.attachment.id)s\n" + + "on Virtual Network: %(network_id)s\n" + + "for Tenant: %(tenant_id)s", }) _templates = { @@ -206,6 +244,31 @@ def list_nets_v11(client, *args): _handle_exception(ex) +def list_nets_detail(client, *args): + tenant_id, version = args + try: + res = client.list_networks_details() + LOG.debug("Operation 'list_networks_details' executed.") + output = prepare_output("list_nets_detail", tenant_id, res, version) + print output + except Exception as ex: + _handle_exception(ex) + + +def list_nets_detail_v11(client, *args): + filters = {} + tenant_id, version = args[:2] + if len(args) > 2: + filters = args[2] + try: + res = client.list_networks_details(**filters) + LOG.debug("Operation 'list_networks_details' executed.") + output = prepare_output("list_nets_detail", tenant_id, res, version) + print output + except Exception as ex: + _handle_exception(ex) + + def create_net(client, *args): tenant_id, name, version = args data = {'network': {'name': name}} @@ -240,11 +303,31 @@ def delete_net(client, *args): def show_net(client, *args): tenant_id, network_id, version = args try: - #NOTE(salvatore-orlando) changed for returning exclusively - # output for GET /networks/{net-id} API operation + res = client.show_network(network_id)["network"] + LOG.debug("Operation 'show_network' executed.") + output = prepare_output("show_net", tenant_id, + dict(network=res), + version) + print output + except Exception as ex: + _handle_exception(ex) + + +def show_net_detail(client, *args): + tenant_id, network_id, version = args + try: res = client.show_network_details(network_id)["network"] LOG.debug("Operation 'show_network_details' executed.") - output = prepare_output("show_net", + if not len(res["ports"]): + res["ports"] = [{"id": "", + "state": "", + "attachment": {"id": ""}}] + else: + for port in res["ports"]: + if "attachment" not in port: + port["attachment"] = {"id": ""} + + output = prepare_output("show_net_detail", tenant_id, dict(network=res), version) @@ -299,6 +382,35 @@ def list_ports_v11(client, *args): _handle_exception(ex) +def list_ports_detail(client, *args): + tenant_id, network_id, version = args + try: + ports = client.list_ports_details(network_id) + LOG.debug("Operation 'list_ports_details' executed.") + data = ports + data['network_id'] = network_id + output = prepare_output("list_ports_detail", tenant_id, data, version) + print output + except Exception as ex: + _handle_exception(ex) + + +def list_ports_detail_v11(client, *args): + filters = {} + tenant_id, network_id, version = args[:3] + if len(args) > 3: + filters = args[3] + try: + ports = client.list_ports_details(network_id, **filters) + LOG.debug("Operation 'list_ports' executed.") + data = ports + data['network_id'] = network_id + output = prepare_output("list_ports_detail", tenant_id, data, version) + print output + except Exception as ex: + _handle_exception(ex) + + def create_port(client, *args): tenant_id, network_id, version = args try: @@ -332,21 +444,27 @@ def delete_port(client, *args): def show_port(client, *args): + tenant_id, network_id, port_id, version = args + try: + port = client.show_port(network_id, port_id)["port"] + LOG.debug("Operation 'show_port' executed.") + output = prepare_output("show_port", tenant_id, + dict(network_id=network_id, + port=port), + version) + print output + except Exception as ex: + _handle_exception(ex) + + +def show_port_detail(client, *args): tenant_id, network_id, port_id, version = args try: port = client.show_port_details(network_id, port_id)["port"] - LOG.debug("Operation 'list_port_details' executed.") - #NOTE(salvatore-orland): current API implementation does not - #return attachment with GET operation on port. Once API alignment - #branch is merged, update client to use the detail action. - # (danwent) Until then, just make additonal webservice call. - attach = client.show_port_attachment(network_id, port_id)['attachment'] - if "id" in attach: - port['attachment'] = attach['id'] - else: - port['attachment'] = '' - output = prepare_output("show_port", - tenant_id, + LOG.debug("Operation 'show_port_details' executed.") + if 'attachment' not in port: + port['attachment'] = {'id': ''} + output = prepare_output("show_port_detail", tenant_id, dict(network_id=network_id, port=port), version) @@ -402,3 +520,20 @@ def unplug_iface(client, *args): print output except Exception as ex: _handle_exception(ex) + + +def show_iface(client, *args): + tenant_id, network_id, port_id, version = args + try: + iface = client.show_port_attachment(network_id, port_id)['attachment'] + if 'id' not in iface: + iface['id'] = '' + LOG.debug("Operation 'show_port_attachment' executed.") + output = prepare_output("show_iface", tenant_id, + dict(network_id=network_id, + port_id=port_id, + iface=iface), + version) + print output + except Exception as ex: + _handle_exception(ex) diff --git a/quantum/client/tests/unit/test_cli.py b/quantum/client/tests/unit/test_cli.py index bfd2f02d6..571012a28 100644 --- a/quantum/client/tests/unit/test_cli.py +++ b/quantum/client/tests/unit/test_cli.py @@ -79,6 +79,19 @@ def _verify_list_networks(self): # Must add newline at the end to match effect of print call self.assertEquals(self.fake_stdout.make_string(), output + '\n') + def _verify_list_networks_details(self): + # Verification - get raw result from db + nw_list = db.network_list(self.tenant_id) + networks = [dict(id=nw.uuid, name=nw.name) for nw in nw_list] + # Fill CLI template + output = cli.prepare_output('list_nets_detail', + self.tenant_id, + dict(networks=networks), + self.version) + # Verify! + # Must add newline at the end to match effect of print call + self.assertEquals(self.fake_stdout.make_string(), output + '\n') + def _verify_create_network(self): # Verification - get raw result from db nw_list = db.network_list(self.tenant_id) @@ -138,6 +151,35 @@ def _verify_show_network(self): # Must add newline at the end to match effect of print call self.assertEquals(self.fake_stdout.make_string(), output + '\n') + def _verify_show_network_details(self): + # Verification - get raw result from db + nw = db.network_list(self.tenant_id)[0] + network = {'id': nw.uuid, + 'name': nw.name, + 'op-status': nw.op_status} + port_list = db.port_list(nw.uuid) + if not port_list: + network['ports'] = [{'id': '', + 'state': '', + 'attachment': {'id': ''}}] + else: + network['ports'] = [] + for port in port_list: + network['ports'].append({'id': port.uuid, + 'state': port.state, + 'attachment': {'id': + port.interface_id + or ''}}) + + # Fill CLI template + output = cli.prepare_output('show_net_detail', + self.tenant_id, + dict(network=network), + self.version) + # Verify! + # Must add newline at the end to match effect of print call + self.assertEquals(self.fake_stdout.make_string(), output + '\n') + def _verify_list_ports(self, network_id): # Verification - get raw result from db port_list = db.port_list(network_id) @@ -153,6 +195,21 @@ def _verify_list_ports(self, network_id): # Must add newline at the end to match effect of print call self.assertEquals(self.fake_stdout.make_string(), output + '\n') + def _verify_list_ports_details(self, network_id): + # Verification - get raw result from db + port_list = db.port_list(network_id) + ports = [dict(id=port.uuid, state=port.state) + for port in port_list] + # Fill CLI template + output = cli.prepare_output('list_ports_detail', + self.tenant_id, + dict(network_id=network_id, + ports=ports), + self.version) + # Verify! + # Must add newline at the end to match effect of print call + self.assertEquals(self.fake_stdout.make_string(), output + '\n') + def _verify_create_port(self, network_id): # Verification - get raw result from db port_list = db.port_list(network_id) @@ -201,19 +258,35 @@ def _verify_update_port(self, network_id, port_id): self.assertEquals(self.fake_stdout.make_string(), output + '\n') def _verify_show_port(self, network_id, port_id): + # Verification - get raw result from db + port = db.port_get(port_id, network_id) + port_data = {'id': port.uuid, + 'state': port.state, + 'attachment': {'id': port.interface_id or ''}, + 'op-status': port.op_status} + + # Fill CLI template + output = cli.prepare_output('show_port', + self.tenant_id, + dict(network_id=network_id, + port=port_data), + self.version) + # Verify! + # Must add newline at the end to match effect of print call + self.assertEquals(self.fake_stdout.make_string(), output + '\n') + + def _verify_show_port_details(self, network_id, port_id): # Verification - get raw result from db # TODO(salvatore-orlando): Must resolve this issue with # attachment in separate bug fix. port = db.port_get(port_id, network_id) port_data = {'id': port.uuid, 'state': port.state, - 'attachment': "", + 'attachment': {'id': port.interface_id or ''}, 'op-status': port.op_status} - if port.interface_id is not None: - port_data['attachment'] = port.interface_id # Fill CLI template - output = cli.prepare_output('show_port', + output = cli.prepare_output('show_port_detail', self.tenant_id, dict(network_id=network_id, port=port_data), @@ -249,7 +322,23 @@ def _verify_unplug_iface(self, network_id, port_id): # Must add newline at the end to match effect of print call self.assertEquals(self.fake_stdout.make_string(), output + '\n') - def test_list_networks(self): + def _verify_show_iface(self, network_id, port_id): + # Verification - get raw result from db + port = db.port_get(port_id, network_id) + iface = {'id': port.interface_id or ''} + + # Fill CLI template + output = cli.prepare_output('show_iface', + self.tenant_id, + dict(network_id=network_id, + port_id=port.uuid, + iface=iface), + self.version) + # Verify! + # Must add newline at the end to match effect of print call + self.assertEquals(self.fake_stdout.make_string(), output + '\n') + + def test_list_networks_v10(self): try: # Pre-populate data for testing using db api db.network_create(self.tenant_id, self.network_name_1) @@ -260,12 +349,65 @@ def test_list_networks(self): self.version) except: LOG.exception("Exception caught: %s", sys.exc_info()) - self.fail("test_list_networks failed due to an exception") + self.fail("test_list_networks_v10 failed due to an exception") + + LOG.debug("Operation completed. Verifying result") + LOG.debug(self.fake_stdout.content) + self._verify_list_networks() + + def test_list_networks_details_v10(self): + try: + # Pre-populate data for testing using db api + db.network_create(self.tenant_id, self.network_name_1) + db.network_create(self.tenant_id, self.network_name_2) + + cli.list_nets_detail(self.client, + self.tenant_id, + self.version) + except: + LOG.exception("Exception caught: %s", sys.exc_info()) + self.fail("test_list_networks_details_v10 failed due to" + + " an exception") + + LOG.debug("Operation completed. Verifying result") + LOG.debug(self.fake_stdout.content) + self._verify_list_networks_details() + + def test_list_networks_v11(self): + try: + # Pre-populate data for testing using db api + db.network_create(self.tenant_id, self.network_name_1) + db.network_create(self.tenant_id, self.network_name_2) + #TODO: test filters + cli.list_nets_v11(self.client, + self.tenant_id, + self.version) + except: + LOG.exception("Exception caught: %s", sys.exc_info()) + self.fail("test_list_networks_v11 failed due to an exception") LOG.debug("Operation completed. Verifying result") LOG.debug(self.fake_stdout.content) self._verify_list_networks() + def test_list_networks_details_v11(self): + try: + # Pre-populate data for testing using db api + db.network_create(self.tenant_id, self.network_name_1) + db.network_create(self.tenant_id, self.network_name_2) + #TODO: test filters + cli.list_nets_detail_v11(self.client, + self.tenant_id, + self.version) + except: + LOG.exception("Exception caught: %s", sys.exc_info()) + self.fail("test_list_networks_details_v11 failed due to " + + "an exception") + + LOG.debug("Operation completed. Verifying result") + LOG.debug(self.fake_stdout.content) + self._verify_list_networks_details() + def test_create_network(self): try: cli.create_net(self.client, @@ -312,6 +454,46 @@ def test_show_network(self): LOG.debug(self.fake_stdout.content) self._verify_show_network() + def test_show_network_details_no_ports(self): + try: + # Load some data into the datbase + net = db.network_create(self.tenant_id, self.network_name_1) + network_id = net['uuid'] + cli.show_net_detail(self.client, + self.tenant_id, + network_id, + self.version) + except: + LOG.exception("Exception caught: %s", sys.exc_info()) + self.fail("test_show_network_details_no_ports failed due to" + + " an exception") + + LOG.debug("Operation completed. Verifying result") + LOG.debug(self.fake_stdout.content) + self._verify_show_network_details() + + def test_show_network_details(self): + iface_id = "flavor crystals" + try: + # Load some data into the datbase + net = db.network_create(self.tenant_id, self.network_name_1) + network_id = net['uuid'] + port = db.port_create(network_id) + port_id = port['uuid'] + db.port_set_attachment(port_id, network_id, iface_id) + port = db.port_create(network_id) + cli.show_net_detail(self.client, + self.tenant_id, + network_id, + self.version) + except: + LOG.exception("Exception caught: %s", sys.exc_info()) + self.fail("test_show_network_details failed due to an exception") + + LOG.debug("Operation completed. Verifying result") + LOG.debug(self.fake_stdout.content) + self._verify_show_network_details() + def test_update_network(self): try: net = db.network_create(self.tenant_id, self.network_name_1) @@ -329,7 +511,7 @@ def test_update_network(self): LOG.debug(self.fake_stdout.content) self._verify_update_network() - def test_list_ports(self): + def test_list_ports_v10(self): try: # Pre-populate data for testing using db api net = db.network_create(self.tenant_id, self.network_name_1) @@ -348,6 +530,67 @@ def test_list_ports(self): LOG.debug(self.fake_stdout.content) self._verify_list_ports(network_id) + def test_list_ports_details_v10(self): + try: + # Pre-populate data for testing using db api + net = db.network_create(self.tenant_id, self.network_name_1) + network_id = net['uuid'] + db.port_create(network_id) + db.port_create(network_id) + cli.list_ports_detail(self.client, + self.tenant_id, + network_id, + self.version) + except: + LOG.exception("Exception caught: %s", sys.exc_info()) + self.fail("test_list_ports_details_v10 failed due to" + + " an exception") + + LOG.debug("Operation completed. Verifying result") + LOG.debug(self.fake_stdout.content) + self._verify_list_ports_details(network_id) + + def test_list_ports_v11(self): + try: + # Pre-populate data for testing using db api + net = db.network_create(self.tenant_id, self.network_name_1) + network_id = net['uuid'] + db.port_create(network_id) + db.port_create(network_id) + #TODO: test filters + cli.list_ports_v11(self.client, + self.tenant_id, + network_id, + self.version) + except: + LOG.exception("Exception caught: %s", sys.exc_info()) + self.fail("test_list_ports_v11 failed due to an exception") + + LOG.debug("Operation completed. Verifying result") + LOG.debug(self.fake_stdout.content) + self._verify_list_ports(network_id) + + def test_list_ports_details_v11(self): + try: + # Pre-populate data for testing using db api + net = db.network_create(self.tenant_id, self.network_name_1) + network_id = net['uuid'] + db.port_create(network_id) + db.port_create(network_id) + #TODO: test filters + cli.list_ports_detail_v11(self.client, + self.tenant_id, + network_id, + self.version) + except: + LOG.exception("Exception caught: %s", sys.exc_info()) + self.fail("test_list_ports_details_v11 failed due to " + + "an exception") + + LOG.debug("Operation completed. Verifying result") + LOG.debug(self.fake_stdout.content) + self._verify_list_ports_details(network_id) + def test_create_port(self): network_id = None try: @@ -409,7 +652,7 @@ def test_update_port(self): LOG.debug(self.fake_stdout.content) self._verify_update_port(network_id, port_id) - def test_show_port_no_attach(self): + def test_show_port(self): network_id = None port_id = None try: @@ -425,13 +668,36 @@ def test_show_port_no_attach(self): self.version) except: LOG.exception("Exception caught: %s", sys.exc_info()) - self.fail("test_show_port_no_attach failed due to an exception") + self.fail("test_show_port failed due to an exception") LOG.debug("Operation completed. Verifying result") LOG.debug(self.fake_stdout.content) self._verify_show_port(network_id, port_id) - def test_show_port_with_attach(self): + def test_show_port_details_no_attach(self): + network_id = None + port_id = None + try: + # Pre-populate data for testing using db api + net = db.network_create(self.tenant_id, self.network_name_1) + network_id = net['uuid'] + port = db.port_create(network_id) + port_id = port['uuid'] + cli.show_port_detail(self.client, + self.tenant_id, + network_id, + port_id, + self.version) + except: + LOG.exception("Exception caught: %s", sys.exc_info()) + self.fail("test_show_port_details_no_attach failed due to" + + " an exception") + + LOG.debug("Operation completed. Verifying result") + LOG.debug(self.fake_stdout.content) + self._verify_show_port_details(network_id, port_id) + + def test_show_port_details_with_attach(self): network_id = None port_id = None iface_id = "flavor crystals" @@ -442,18 +708,19 @@ def test_show_port_with_attach(self): port = db.port_create(network_id) port_id = port['uuid'] db.port_set_attachment(port_id, network_id, iface_id) - cli.show_port(self.client, - self.tenant_id, - network_id, - port_id, - self.version) + cli.show_port_detail(self.client, + self.tenant_id, + network_id, + port_id, + self.version) except: LOG.exception("Exception caught: %s", sys.exc_info()) - self.fail("test_show_port_with_attach failed due to an exception") + self.fail("test_show_port_details_with_attach failed due" + + " to an exception") LOG.debug("Operation completed. Verifying result") LOG.debug(self.fake_stdout.content) - self._verify_show_port(network_id, port_id) + self._verify_show_port_details(network_id, port_id) def test_plug_iface(self): network_id = None @@ -500,3 +767,51 @@ def test_unplug_iface(self): LOG.debug("Operation completed. Verifying result") LOG.debug(self.fake_stdout.content) self._verify_unplug_iface(network_id, port_id) + + def test_show_iface_no_attach(self): + network_id = None + port_id = None + try: + # Pre-populate data for testing using db api + net = db.network_create(self.tenant_id, self.network_name_1) + network_id = net['uuid'] + port = db.port_create(network_id) + port_id = port['uuid'] + cli.show_iface(self.client, + self.tenant_id, + network_id, + port_id, + self.version) + except: + LOG.exception("Exception caught: %s", sys.exc_info()) + self.fail("test_show_iface_no_attach failed due to" + + " an exception") + + LOG.debug("Operation completed. Verifying result") + LOG.debug(self.fake_stdout.content) + self._verify_show_iface(network_id, port_id) + + def test_show_iface_with_attach(self): + network_id = None + port_id = None + iface_id = "flavor crystals" + try: + # Pre-populate data for testing using db api + net = db.network_create(self.tenant_id, self.network_name_1) + network_id = net['uuid'] + port = db.port_create(network_id) + port_id = port['uuid'] + db.port_set_attachment(port_id, network_id, iface_id) + cli.show_iface(self.client, + self.tenant_id, + network_id, + port_id, + self.version) + except: + LOG.exception("Exception caught: %s", sys.exc_info()) + self.fail("test_show_iface_with_attach failed due" + + " to an exception") + + LOG.debug("Operation completed. Verifying result") + LOG.debug(self.fake_stdout.content) + self._verify_show_iface(network_id, port_id) diff --git a/quantum/client/tests/unit/test_clientlib.py b/quantum/client/tests/unit/test_clientlib.py index b87050f17..f198d2a43 100644 --- a/quantum/client/tests/unit/test_clientlib.py +++ b/quantum/client/tests/unit/test_clientlib.py @@ -131,6 +131,37 @@ def _test_list_networks(self, tenant=TENANT_1, format='json', status=200): LOG.debug("_test_list_networks - tenant:%s "\ "- format:%s - END", format, tenant) + def _test_list_networks_details(self, + tenant=TENANT_1, format='json', + status=200): + LOG.debug("_test_list_networks_details - tenant:%s "\ + "- format:%s - START", format, tenant) + + self._assert_sanity(self.client.list_networks_details, + status, + "GET", + "networks/detail", + data=[], + params={'tenant': tenant, 'format': format}) + + LOG.debug("_test_list_networks_details - tenant:%s "\ + "- format:%s - END", format, tenant) + + def _test_show_network(self, + tenant=TENANT_1, format='json', status=200): + LOG.debug("_test_show_network - tenant:%s "\ + "- format:%s - START", format, tenant) + + self._assert_sanity(self.client.show_network, + status, + "GET", + "networks/001", + data=["001"], + params={'tenant': tenant, 'format': format}) + + LOG.debug("_test_show_network - tenant:%s "\ + "- format:%s - END", format, tenant) + def _test_show_network_details(self, tenant=TENANT_1, format='json', status=200): LOG.debug("_test_show_network_details - tenant:%s "\ @@ -139,7 +170,7 @@ def _test_show_network_details(self, self._assert_sanity(self.client.show_network_details, status, "GET", - "networks/001", + "networks/001/detail", data=["001"], params={'tenant': tenant, 'format': format}) @@ -203,6 +234,35 @@ def _test_list_ports(self, tenant=TENANT_1, format='json', status=200): LOG.debug("_test_list_ports - tenant:%s "\ "- format:%s - END", format, tenant) + def _test_list_ports_details(self, + tenant=TENANT_1, format='json', status=200): + LOG.debug("_test_list_ports_details - tenant:%s "\ + "- format:%s - START", format, tenant) + + self._assert_sanity(self.client.list_ports_details, + status, + "GET", + "networks/001/ports/detail", + data=["001"], + params={'tenant': tenant, 'format': format}) + + LOG.debug("_test_list_ports_details - tenant:%s "\ + "- format:%s - END", format, tenant) + + def _test_show_port(self, tenant=TENANT_1, format='json', status=200): + LOG.debug("_test_show_port - tenant:%s "\ + "- format:%s - START", format, tenant) + + self._assert_sanity(self.client.show_port, + status, + "GET", + "networks/001/ports/001", + data=["001", "001"], + params={'tenant': tenant, 'format': format}) + + LOG.debug("_test_show_port - tenant:%s "\ + "- format:%s - END", format, tenant) + def _test_show_port_details(self, tenant=TENANT_1, format='json', status=200): LOG.debug("_test_show_port_details - tenant:%s "\ @@ -211,7 +271,7 @@ def _test_show_port_details(self, self._assert_sanity(self.client.show_port_details, status, "GET", - "networks/001/ports/001", + "networks/001/ports/001/detail", data=["001", "001"], params={'tenant': tenant, 'format': format}) @@ -345,6 +405,39 @@ def test_list_networks_error_470(self): def test_list_networks_error_401(self): self._test_list_networks(status=401) + def test_list_networks_details_json(self): + self._test_list_networks_details(format='json') + + def test_list_networks_details_xml(self): + self._test_list_networks_details(format='xml') + + def test_list_networks_details_alt_tenant(self): + self._test_list_networks_details(tenant=TENANT_2) + + def test_list_networks_details_error_470(self): + self._test_list_networks_details(status=470) + + def test_list_networks_details_error_401(self): + self._test_list_networks_details(status=401) + + def test_show_network_json(self): + self._test_show_network(format='json') + + def test_show_network__xml(self): + self._test_show_network(format='xml') + + def test_show_network_alt_tenant(self): + self._test_show_network(tenant=TENANT_2) + + def test_show_network_error_470(self): + self._test_show_network(status=470) + + def test_show_network_error_401(self): + self._test_show_network(status=401) + + def test_show_network_error_420(self): + self._test_show_network(status=420) + def test_show_network_details_json(self): self._test_show_network_details(format='json') @@ -447,14 +540,53 @@ def test_list_ports_error_401(self): def test_list_ports_error_420(self): self._test_list_ports(status=420) + def test_list_ports_details_json(self): + self._test_list_ports_details(format='json') + + def test_list_ports_details_xml(self): + self._test_list_ports_details(format='xml') + + def test_list_ports_details_alt_tenant(self): + self._test_list_ports_details(tenant=TENANT_2) + + def test_list_ports_details_error_470(self): + self._test_list_ports_details(status=470) + + def test_list_ports_details_error_401(self): + self._test_list_ports_details(status=401) + + def test_list_ports_details_error_420(self): + self._test_list_ports_details(status=420) + + def test_show_port_json(self): + self._test_show_port(format='json') + + def test_show_port_xml(self): + self._test_show_port(format='xml') + + def test_show_port_alt_tenant(self): + self._test_show_port(tenant=TENANT_2) + + def test_show_port_error_470(self): + self._test_show_port(status=470) + + def test_show_port_error_401(self): + self._test_show_port(status=401) + + def test_show_port_error_420(self): + self._test_show_port(status=420) + + def test_show_port_error_430(self): + self._test_show_port(status=430) + def test_show_port_details_json(self): - self._test_list_ports(format='json') + self._test_show_port_details(format='json') def test_show_port_details_xml(self): - self._test_list_ports(format='xml') + self._test_show_port_details(format='xml') def test_show_port_details_alt_tenant(self): - self._test_list_ports(tenant=TENANT_2) + self._test_show_port_details(tenant=TENANT_2) def test_show_port_details_error_470(self): self._test_show_port_details(status=470)