From 9136a050770429c59d2a85a20492bb6457fe1f9e Mon Sep 17 00:00:00 2001 From: Sergey Lyopka Date: Mon, 1 Jul 2013 17:21:59 +0300 Subject: [PATCH] ostf-117-141 Network Client for Nova * network_client.py: new NovaNetworkClient added * test.py, manager.py, clients/py were updated to silently apply appropriate network client * base.py, test_sanity_* were updated to use new network client and to use new fuel_health structure of modules --- fuel_health/clients.py | 9 ++- fuel_health/manager.py | 4 +- .../services/network/json/network_client.py | 59 ++++++++++++++++++- fuel_health/test.py | 4 +- fuel_health/tests/sanity/base.py | 2 - .../tests/sanity/test_sanity_compute.py | 4 +- .../sanity/test_sanity_infrastructure.py | 24 ++++---- .../tests/sanity/test_sanity_networking.py | 23 ++++---- 8 files changed, 96 insertions(+), 33 deletions(-) diff --git a/fuel_health/clients.py b/fuel_health/clients.py index e0dd024c..9f0fb18c 100644 --- a/fuel_health/clients.py +++ b/fuel_health/clients.py @@ -39,7 +39,8 @@ from fuel_health.services.compute.json.tenant_usages_client import \ TenantUsagesClientJSON from fuel_health.services.identity.json.identity_client import IdentityClientJSON from fuel_health.services.identity.json.identity_client import TokenClientJSON -from fuel_health.services.network.json.network_client import NetworkClient +from fuel_health.services.network.json.network_client import NovaNetworkClient +from fuel_health.services.network.json.network_client import QuantumNetworkClient from fuel_health.services.volume.json.admin.volume_types_client import \ VolumeTypesClientJSON @@ -51,7 +52,7 @@ LOG = logging.getLogger(__name__) IMAGES_CLIENTS = { "json": ImagesClientJSON, - } +} KEYPAIRS_CLIENTS = { "json": KeyPairsClientJSON, @@ -206,6 +207,10 @@ class Manager(object): except KeyError: msg = "Unsupported interface type `%s'" % interface raise exceptions.InvalidConfiguration(msg) + + NetworkClient = QuantumNetworkClient + if not self.config.network.quantum_available: + NetworkClient = NovaNetworkClient self.network_client = NetworkClient(*client_args) self.hosts_client = HostsClientJSON(*client_args) diff --git a/fuel_health/manager.py b/fuel_health/manager.py index 091806dc..11e9a64f 100644 --- a/fuel_health/manager.py +++ b/fuel_health/manager.py @@ -32,7 +32,6 @@ from fuel_health.services.network.json import network_client from fuel_health.services.volume.json import snapshots_client from fuel_health.services.volume.json import volumes_client -NetworkClient = network_client.NetworkClient ImagesClient = images_client.ImagesClientJSON FlavorsClient = flavors_client.FlavorsClientJSON ServersClient = servers_client.ServersClientJSON @@ -44,6 +43,9 @@ VolumesClient = volumes_client.VolumesClientJSON SnapshotsClient = snapshots_client.SnapshotsClientJSON QuotasClient = quotas_client.QuotasClientJSON HypervisorClient = hypervisor_client.HypervisorClientJSON +NetworkClient = network_client.QuantumNetworkClient +if not fuel_health.config.FuelConfig().network.quantum_available: + NetworkClient = network_client.NovaNetworkClient LOG = logging.getLogger(__name__) diff --git a/fuel_health/services/network/json/network_client.py b/fuel_health/services/network/json/network_client.py index 93ce8544..dc7c6f72 100644 --- a/fuel_health/services/network/json/network_client.py +++ b/fuel_health/services/network/json/network_client.py @@ -2,7 +2,62 @@ import json from fuel_health.common.rest_client import RestClient -class NetworkClient(RestClient): +class NovaNetworkClient(RestClient): + + """ + REST client for Compute allows manipulate network data. + Uses v2 of the Compute API. + """ + + def __init__(self, config, username, password, auth_url, tenant_name=None): + super(NovaNetworkClient, self).__init__(config, username, password, + auth_url, tenant_name) + self.service = self.config.compute.catalog_type + + def list_networks(self): + resp, body = self.get("os-networks") + body = json.loads(body) + return resp, body + + def create_network(self, label): + body = { + 'network': { + 'label': label, + } + } + body = json.dumps(body) + resp, body = self.post("os-networks/add", body, self.headers) + body = json.loads(body) + return resp, body + + def show_network(self, uuid): + resp, body = self.get("/os-networks/%s" % uuid) + body = json.loads(body) + return resp, body + + def delete_network(self, uuid): + resp, body = self.delete("/os-networks/%s" % uuid, self.headers) + return resp, body + + def list_ports(self): + ports = {u'ports': []} + resp, body = self.get("os-networks") + networks = json.loads(body)[u'networks'] + ports[u'ports'] = [{net['id']: net['vpn_public_port']} + for net in networks] + return resp, ports + + def show_port(self, port_id): + ports = {u'ports': []} + resp, body = self.get("os-networks") + networks = json.loads(body)[u'networks'] + ports[u'ports'] = [{net['id']: net['vpn_public_port']} + for net in networks + if net['vpn_public_port'] == port_id] + return resp, ports + + +class QuantumNetworkClient(RestClient): """ REST client for Quantum. Uses v2 of the Quantum API, since the @@ -18,7 +73,7 @@ class NetworkClient(RestClient): """ def __init__(self, config, username, password, auth_url, tenant_name=None): - super(NetworkClient, self).__init__(config, username, password, + super(QuantumNetworkClient, self).__init__(config, username, password, auth_url, tenant_name) self.service = self.config.network.catalog_type self.version = '2.0' diff --git a/fuel_health/test.py b/fuel_health/test.py index 47b0d9a1..700d2755 100644 --- a/fuel_health/test.py +++ b/fuel_health/test.py @@ -42,10 +42,10 @@ def _raise_TimeOut(sig, stack): raise TimeOutError() -class timeout(object): +class ExecutionTimeout(object): """ Timeout context that will stop code running within context - if timeout is reached + if timeout (sec) is reached >>with timeout(2): ... requests.get("http://msdn.com") diff --git a/fuel_health/tests/sanity/base.py b/fuel_health/tests/sanity/base.py index cc7022ce..e3e1c0f5 100644 --- a/fuel_health/tests/sanity/base.py +++ b/fuel_health/tests/sanity/base.py @@ -304,8 +304,6 @@ class BaseNetworkTest(BaseIdentityAdminTest): def setUpClass(cls): os = clients.AdminManager() cls.network_cfg = os.config.network - if not cls.network_cfg.quantum_available: - raise cls.skipException("Quantum support is required") cls.client = os.network_client cls.networks = [] cls.subnets = [] diff --git a/fuel_health/tests/sanity/test_sanity_compute.py b/fuel_health/tests/sanity/test_sanity_compute.py index 9419059a..9271a594 100644 --- a/fuel_health/tests/sanity/test_sanity_compute.py +++ b/fuel_health/tests/sanity/test_sanity_compute.py @@ -105,7 +105,7 @@ class SanityComputeTest(base.BaseComputeTest): 3. Check response contains absolute limits in "limits" section. """ resp, body = self.limits_client.get_absolute_limits() - self.verify_response_status(resp.status, 'Compute') + self.verify_response_status(resp.status, 'Cinder') self.verify_response_body(body["limits"], u'absolute', 'Limits are unavailable. ' - 'Looks like something broken in Compute.') + 'Looks like something broken in Cinder.') diff --git a/fuel_health/tests/sanity/test_sanity_infrastructure.py b/fuel_health/tests/sanity/test_sanity_infrastructure.py index 54b1e32d..48dc33f6 100644 --- a/fuel_health/tests/sanity/test_sanity_infrastructure.py +++ b/fuel_health/tests/sanity/test_sanity_infrastructure.py @@ -1,5 +1,7 @@ from fuel_health.common.ssh import Client as SSHClient +from fuel_health.exceptions import SSHExecCommandFailed from fuel_health.test import attr +from fuel_health.test import ExecutionTimeout from fuel_health.tests.sanity import base @@ -53,8 +55,9 @@ class SanityInfrastructureTest(base.BaseComputeAdminTest): 4. Check number of normally executed services (with :-) state is equal to the number of expected services """ - output = SSHClient(self.host, self.usr, self.pwd).exec_command( - "nova-manage service list") + with ExecutionTimeout(5): + output = SSHClient(self.host, self.usr, self.pwd).exec_command( + "nova-manage service list") self.assertFalse(u'XXX' in output) self.assertEqual(len(self.list_of_expected_services), output.count(u':-)'), @@ -82,11 +85,12 @@ class SanityInfrastructureTest(base.BaseComputeAdminTest): was successfully resolved. """ output = '' - try: - output = SSHClient(self.host, self.usr, self.pwd).exec_command( - "host " + self.host) - finally: - expected_output = 'in-addr.arpa domain name pointer ' + \ - self.hostname - self.assertTrue(expected_output in output, - 'DNS name cannot be resolved') + expected_output = "in-addr.arpa domain name pointer " + self.hostname + with ExecutionTimeout(10): + try: + output = SSHClient(self.host, self.usr, self.pwd).exec_command( + "host " + self.host) + except SSHExecCommandFailed: + output = "'host' command failed." + self.assertTrue(expected_output in output, + 'DNS name cannot be resolved') diff --git a/fuel_health/tests/sanity/test_sanity_networking.py b/fuel_health/tests/sanity/test_sanity_networking.py index be46bc37..0f3112cd 100644 --- a/fuel_health/tests/sanity/test_sanity_networking.py +++ b/fuel_health/tests/sanity/test_sanity_networking.py @@ -5,41 +5,40 @@ from fuel_health.tests.sanity import base class NetworksTest(base.BaseNetworkTest): """ TestClass contains tests check base networking functionality - Special requirements: Quantum section should be on in the config """ @attr(type=['sanity', 'fuel']) def test_list_networks(self): """ Test checks list of networks is available. - Target component: Quantum - Special requirements: Quantum section should be on in the config + Target component: Neutron or Nova Scenario: 1. Request list of networks. - 2. Check response status is equal to 200. + 2. Check response status is positive. 3. Check response contains "networks" section. """ resp, body = self.client.list_networks() - self.verify_response_status(resp.status, u'Quantum') + self.verify_response_status(resp.status, u'Network (Neutron or Nova)') self.verify_response_body(body, u'networks', - 'Network list is unavailable. ' - 'Looks like something broken in Quantum.') + "Network list is unavailable. " + "Looks like something broken in Network " + "(Neutron or Nova).") @attr(type=['sanity', 'fuel']) def test_list_ports(self): """ Test checks list of ports is available. - Target component: Quantum - Special requirements: Quantum section should be on in the config + Target component: Neutron or Nova Scenario: 1. Request list of ports. - 2. Check response status is equal to 200. + 2. Check response status is positive. 3. Check response contains "ports" section. """ resp, body = self.client.list_ports() - self.verify_response_status(resp.status, u'Quantum') + self.verify_response_status(resp.status, u'Network (Neutron or Nova)') self.verify_response_body(body, u'ports', 'Ports list is unavailable. ' - 'Looks like something broken in Quantum.') + 'Looks like something broken in Network ' + '(Neutron or Nova).') \ No newline at end of file