From e5ab46d36a437373b00b1cfaa628f953e9225022 Mon Sep 17 00:00:00 2001 From: Gal Sagie Date: Sun, 20 Dec 2015 09:09:09 +0200 Subject: [PATCH] Create Neutron client from cloud credentials This patch add the capabilities to create the neutron client from admin credentials by using clouds.yaml. This is done mostly for gate testing. We will need to allow the user a configuration option to disable this in production and use his own user/pass for this authentication. implements blueprint: fullstack-testing Change-Id: I1973fa6fb13cedd60f86783165f949cb5b1e5f80 --- kuryr/controllers.py | 90 ++++++++++++++++++++------- kuryr/tests/fullstack/kuryr_base.py | 33 +--------- kuryr/tests/fullstack/test_network.py | 1 + 3 files changed, 72 insertions(+), 52 deletions(-) diff --git a/kuryr/controllers.py b/kuryr/controllers.py index 60b437d9..836d3fe0 100644 --- a/kuryr/controllers.py +++ b/kuryr/controllers.py @@ -11,11 +11,14 @@ # under the License. import os +import os_client_config import flask import jsonschema import netaddr + from neutronclient.common import exceptions as n_exceptions +from neutronclient.neutron import client from oslo_concurrency import processutils from oslo_config import cfg from oslo_utils import excutils @@ -32,29 +35,74 @@ from kuryr import utils MANDATORY_NEUTRON_EXTENSION = "subnet_allocation" -def neutron_client(): +def _get_cloud_config(cloud='devstack-admin'): + return os_client_config.OpenStackConfig().get_one_cloud(cloud=cloud) + + +def _credentials(cloud='devstack-admin'): + """Retrieves credentials to run functional tests + + Credentials are either read via os-client-config from the environment + or from a config file ('clouds.yaml'). Environment variables override + those from the config file. + + devstack produces a clouds.yaml with two named clouds - one named + 'devstack' which has user privs and one named 'devstack-admin' which + has admin privs. This function will default to getting the devstack-admin + cloud as that is the current expected behavior. + """ + return _get_cloud_config(cloud=cloud).get_auth_args() + + +def _get_neutron_client_from_creds(): + creds = _credentials() + username = creds['username'] + tenant_name = creds['project_name'] + password = creds['password'] + auth_url = creds['auth_url'] + "/v2.0" + neutron_client = client.Client('2.0', username=username, + tenant_name=tenant_name, + password=password, + auth_url=auth_url) + return neutron_client + + +def get_neutron_client(): """Creates the Neutron client for communicating with Neutron.""" + try: + # First try to retrieve neutron client from a working OS deployment + # This is used for gate testing. + # Since this always use admin credentials, next patch will introduce + # a config parameter that disable this for production environments + neutron_client = _get_neutron_client_from_creds() + return neutron_client + except Exception: + pass + cfg.CONF.import_group('neutron_client', 'kuryr.common.config') + cfg.CONF.import_group('keystone_client', 'kuryr.common.config') + + keystone_conf = cfg.CONF.keystone_client + username = keystone_conf.admin_user + tenant_name = keystone_conf.admin_tenant_name + password = keystone_conf.admin_password + auth_token = keystone_conf.admin_token + auth_uri = keystone_conf.auth_uri.rstrip('/') + + neutron_uri = cfg.CONF.neutron_client.neutron_uri + if username and password: + # Authenticate with password crentials + neutron_client = utils.get_neutron_client( + url=neutron_uri, username=username, tenant_name=tenant_name, + password=password, auth_url=auth_uri) + else: + neutron_client = utils.get_neutron_client_simple( + url=neutron_uri, auth_url=auth_uri, token=auth_token) + return neutron_client + + +def neutron_client(): if not hasattr(app, 'neutron'): - cfg.CONF.import_group('neutron_client', 'kuryr.common.config') - cfg.CONF.import_group('keystone_client', 'kuryr.common.config') - - keystone_conf = cfg.CONF.keystone_client - username = keystone_conf.admin_user - tenant_name = keystone_conf.admin_tenant_name - password = keystone_conf.admin_password - auth_token = keystone_conf.admin_token - auth_uri = keystone_conf.auth_uri.rstrip('/') - - neutron_uri = cfg.CONF.neutron_client.neutron_uri - if username and password: - # Authenticate with password crentials - app.neutron = utils.get_neutron_client( - url=neutron_uri, username=username, tenant_name=tenant_name, - password=password, auth_url=auth_uri) - else: - app.neutron = utils.get_neutron_client_simple( - url=neutron_uri, auth_url=auth_uri, token=auth_token) - + app.neutron = get_neutron_client() app.enable_dhcp = cfg.CONF.neutron_client.enable_dhcp app.neutron.format = 'json' diff --git a/kuryr/tests/fullstack/kuryr_base.py b/kuryr/tests/fullstack/kuryr_base.py index 2dbc20f3..408683d2 100644 --- a/kuryr/tests/fullstack/kuryr_base.py +++ b/kuryr/tests/fullstack/kuryr_base.py @@ -11,30 +11,10 @@ # under the License. import docker -import os_client_config from oslotest import base -from neutronclient.neutron import client - - -def get_cloud_config(cloud='devstack-admin'): - return os_client_config.OpenStackConfig().get_one_cloud(cloud=cloud) - - -def credentials(cloud='devstack-admin'): - """Retrieves credentials to run functional tests - - Credentials are either read via os-client-config from the environment - or from a config file ('clouds.yaml'). Environment variables override - those from the config file. - - devstack produces a clouds.yaml with two named clouds - one named - 'devstack' which has user privs and one named 'devstack-admin' which - has admin privs. This function will default to getting the devstack-admin - cloud as that is the current expected behavior. - """ - return get_cloud_config(cloud=cloud).get_auth_args() +from kuryr import controllers class KuryrBaseTest(base.BaseTestCase): @@ -48,13 +28,4 @@ class KuryrBaseTest(base.BaseTestCase): super(KuryrBaseTest, self).setUp() self.docker_client = docker.Client( base_url='tcp://0.0.0.0:2375') - - self.creds = credentials() - username = self.creds['username'] - tenant_name = self.creds['project_name'] - password = self.creds['password'] - auth_url = self.creds['auth_url'] - self.neutron_client = client.Client('2.0', username=username, - tenant_name=tenant_name, - password=password, - auth_url=auth_url) + self.neutron_client = controllers.get_neutron_client() diff --git a/kuryr/tests/fullstack/test_network.py b/kuryr/tests/fullstack/test_network.py index 4798f7b1..c2c0f448 100644 --- a/kuryr/tests/fullstack/test_network.py +++ b/kuryr/tests/fullstack/test_network.py @@ -26,3 +26,4 @@ class NetworkTest(kuryr_base.KuryrBaseTest): # TODO(gsagie) refactor this method self.docker_client.create_network(name='fakenet', driver='kuryr') self.docker_client.remove_network('fakenet') + self.neutron_client.list_networks()