Add support to both v2 and v3 auth_urls

This patch adds support to authenticate all datasource drivers
using both v2 and v3 auth_urls. Also made change in devstack
plugin to use v3 by default for authentication

TODO: keystone and swift datasource drivers to support v3

Change-Id: I6d3b8511be871cc8f571d2cec504d8b142c396fc
Partially-Implements: blueprint keystone-v3-api-support
This commit is contained in:
Anusha Ramineni 2016-06-09 16:40:09 +05:30
parent 88f4a87f48
commit d7e5461316
13 changed files with 55 additions and 76 deletions

View File

@ -160,8 +160,8 @@ class CeilometerDriver(datasource_driver.PollingDataSourceDriver,
super(CeilometerDriver, self).__init__(name, keys, inbox,
datapath, args)
datasource_driver.ExecutionDriver.__init__(self)
self.creds = self.get_ceilometer_credentials_v2(args)
self.ceilometer_client = cc.get_client(**self.creds)
session = ds_utils.get_keystone_session(args)
self.ceilometer_client = cc.get_client(version='2', session=session)
self.add_executable_client_methods(self.ceilometer_client,
'ceilometerclient.v2.')
self._init_end_start_poll()
@ -227,15 +227,6 @@ class CeilometerDriver(datasource_driver.PollingDataSourceDriver,
statistics.append(temp_dict)
return statistics
def get_ceilometer_credentials_v2(self, creds):
d = {}
d['version'] = '2'
d['username'] = creds['username']
d['password'] = creds['password']
d['auth_url'] = creds['auth_url']
d['tenant_name'] = creds['tenant_name']
return d
@ds_utils.update_state_on_changed(METERS)
def _translate_meters(self, obj):
"""Translate the meters represented by OBJ into tables."""

View File

@ -83,8 +83,9 @@ class CinderDriver(datasource_driver.PollingDataSourceDriver,
def __init__(self, name='', keys='', inbox=None, datapath=None, args=None):
super(CinderDriver, self).__init__(name, keys, inbox, datapath, args)
datasource_driver.ExecutionDriver.__init__(self)
self.creds = self.get_cinder_credentials_v2(args)
self.cinder_client = cinderclient.client.Client(**self.creds)
session = ds_utils.get_keystone_session(args)
self.cinder_client = cinderclient.client.Client(version='2',
session=session)
self.add_executable_client_methods(self.cinder_client,
'cinderclient.v2.')
self._init_end_start_poll()
@ -112,15 +113,6 @@ class CinderDriver(datasource_driver.PollingDataSourceDriver,
host=None, binary=None)
self._translate_services(services)
def get_cinder_credentials_v2(self, creds):
d = {}
d['version'] = '2'
d['username'] = creds['username']
d['api_key'] = creds['password']
d['auth_url'] = creds['auth_url']
d['project_id'] = creds['tenant_name']
return d
@ds_utils.update_state_on_changed(VOLUMES)
def _translate_volumes(self, obj):
row_data = CinderDriver.convert_objs(obj, self.volumes_translator)

View File

@ -19,6 +19,11 @@ from __future__ import absolute_import
import functools
import inspect
import re
from six.moves.urllib import parse as urlparse
import keystoneauth1.identity.v2 as v2
import keystoneauth1.identity.v3 as v3
import keystoneauth1.session as kssession
from congress.datasources import constants
@ -144,3 +149,27 @@ def inspect_methods(client, api_prefix):
obj_stack.append(p)
return allmethods
def get_keystone_session(creds):
url_parts = urlparse.urlparse(creds['auth_url'])
path = url_parts.path.lower()
if path.startswith('/v3'):
# Use v3 plugin to authenticate
auth = v3.Password(
auth_url=creds['auth_url'],
username=creds['username'],
password=creds['password'],
project_name=creds.get('project_name') or creds.get('tenant_name'),
user_domain_name=creds.get('user_domain_name', 'default'),
project_domain_name=creds.get('project_domain_name', 'default'))
else:
# Use v2 plugin
auth = v2.Password(auth_url=creds['auth_url'],
username=creds['username'],
password=creds['password'],
tenant_name=creds['tenant_name'])
session = kssession.Session(auth=auth)
return session

View File

@ -18,8 +18,6 @@ from __future__ import division
from __future__ import absolute_import
import glanceclient.v2.client as glclient
import keystoneauth1.identity.v2 as ksidentity
import keystoneauth1.session as kssession
from oslo_log import log as logging
from congress.datasources import datasource_driver
@ -77,11 +75,7 @@ class GlanceV2Driver(datasource_driver.PollingDataSourceDriver,
super(GlanceV2Driver, self).__init__(name, keys, inbox, datapath, args)
datasource_driver.ExecutionDriver.__init__(self)
self.creds = args
auth = ksidentity.Password(auth_url=self.creds['auth_url'],
username=self.creds['username'],
password=self.creds['password'],
tenant_name=self.creds['tenant_name'])
session = kssession.Session(auth=auth)
session = ds_utils.get_keystone_session(self.creds)
self.glance = glclient.Client(session=session)
self.add_executable_client_methods(self.glance, 'glanceclient.v2.')
self._init_end_start_poll()

View File

@ -15,9 +15,6 @@ from __future__ import division
from __future__ import absolute_import
import heatclient.v1.client as heatclient
import keystoneauth1.identity.v2 as ksidentity
import keystoneauth1.session as kssession
import keystoneclient.v2_0.client as ksclient
from oslo_log import log as logging
from congress.datasources import datasource_driver
@ -154,14 +151,9 @@ class HeatV1Driver(datasource_driver.PollingDataSourceDriver,
super(HeatV1Driver, self).__init__(name, keys, inbox, datapath, args)
datasource_driver.ExecutionDriver.__init__(self)
self.creds = args
auth = ksidentity.Password(auth_url=self.creds['auth_url'],
username=self.creds['username'],
password=self.creds['password'],
tenant_name=self.creds['tenant_name'])
session = kssession.Session(auth=auth)
keystone = ksclient.Client(**self.creds)
endpoint = keystone.service_catalog.url_for(
service_type='orchestration', endpoint_type='publicURL')
session = ds_utils.get_keystone_session(self.creds)
endpoint = session.get_endpoint(service_type='orchestration',
interface='publicURL')
self.heat = heatclient.Client(session=session, endpoint=endpoint)
self._init_end_start_poll()

View File

@ -138,7 +138,8 @@ class IronicDriver(datasource_driver.PollingDataSourceDriver,
super(IronicDriver, self).__init__(name, keys, inbox, datapath, args)
datasource_driver.ExecutionDriver.__init__(self)
self.creds = self.get_ironic_credentials(args)
self.ironic_client = client.get_client(**self.creds)
session = ds_utils.get_keystone_session(self.creds)
self.ironic_client = client.get_client(session=session)
self.add_executable_client_methods(self.ironic_client,
'ironicclient.v1.')
self._init_end_start_poll()

View File

@ -75,6 +75,7 @@ class KeystoneDriver(datasource_driver.PollingDataSourceDriver,
super(KeystoneDriver, self).__init__(name, keys, inbox, datapath, args)
datasource_driver.ExecutionDriver.__init__(self)
self.creds = self.get_keystone_credentials_v2(args)
self.creds['auth_url'] = self.creds['auth_url'].replace('v3', 'v2.0')
self.client = keystoneclient.v2_0.client.Client(**self.creds)
self.add_executable_client_methods(self.client,
'keystoneclient.v2_0.client')

View File

@ -19,9 +19,6 @@ from __future__ import absolute_import
import inspect
import keystoneauth1.identity.v2 as ksidentity
import keystoneauth1.session as kssession
import keystoneclient.v2_0.client as ksclient
import muranoclient.client
from muranoclient.common import exceptions as murano_exceptions
from oslo_log import log as logging
@ -59,23 +56,11 @@ class MuranoDriver(datasource_driver.PollingDataSourceDriver,
super(MuranoDriver, self).__init__(name, keys, inbox, datapath, args)
datasource_driver.ExecutionDriver.__init__(self)
self.creds = args
logger.debug("Credentials = %s" % self.creds)
# TODO(ekcs): factor session creation out of individual driver
# One single keystone session can be shared by all drivers
auth = ksidentity.Password(
auth_url=self.creds['auth_url'],
username=self.creds['username'],
password=self.creds['password'],
tenant_name=self.creds['tenant_name'])
session = kssession.Session(auth=auth)
keystone = ksclient.Client(**self.creds)
murano_endpoint = keystone.service_catalog.url_for(
service_type='application-catalog',
endpoint_type='publicURL')
logger.debug("murano_endpoint = %s" % murano_endpoint)
session = datasource_utils.get_keystone_session(self.creds)
client_version = "1"
self.murano_client = muranoclient.client.Client(
client_version, murano_endpoint, session=session)
client_version, session=session, endpoint_type='publicURL',
service_type='application-catalog')
self.add_executable_client_methods(
self.murano_client,
'muranoclient.v1.')

View File

@ -341,7 +341,8 @@ class NeutronV2Driver(datasource_driver.PollingDataSourceDriver,
datapath, args)
datasource_driver.ExecutionDriver.__init__(self)
self.creds = args
self.neutron = neutronclient.v2_0.client.Client(**self.creds)
session = ds_utils.get_keystone_session(self.creds)
self.neutron = neutronclient.v2_0.client.Client(session=session)
self.add_executable_client_methods(self.neutron,
'neutronclient.v2_0.client')
self._init_end_start_poll()

View File

@ -175,8 +175,10 @@ class NovaDriver(datasource_driver.PollingDataSourceDriver,
def __init__(self, name='', keys='', inbox=None, datapath=None, args=None):
super(NovaDriver, self).__init__(name, keys, inbox, datapath, args)
datasource_driver.ExecutionDriver.__init__(self)
self.creds = self.get_nova_credentials_v2(args)
self.nova_client = novaclient.client.Client(**self.creds)
self.creds = args
session = ds_utils.get_keystone_session(self.creds)
self.nova_client = novaclient.client.Client(
version=self.creds.get('api_version', '2'), session=session)
self.add_executable_method('servers_set_meta',
[{'name': 'server',
'description': 'server id'},
@ -198,15 +200,6 @@ class NovaDriver(datasource_driver.PollingDataSourceDriver,
result['secret'] = ['password']
return result
def get_nova_credentials_v2(self, creds):
d = {}
d['version'] = creds.get('api_version', '2')
d['username'] = creds['username']
d['api_key'] = creds['password']
d['auth_url'] = creds['auth_url']
d['project_id'] = creds['tenant_name']
return d
def update_from_datasource(self):
servers = self.nova_client.servers.list(
detailed=True, search_opts={"all_tenants": 1})

View File

@ -68,6 +68,8 @@ class SwiftDriver(datasource_driver.PollingDataSourceDriver,
super(SwiftDriver, self).__init__(name, keys, inbox, datapath, args)
datasource_driver.ExecutionDriver.__init__(self)
options = self.get_swift_credentials_v1(args)
# TODO(ramineni): Enable v3 support
options['os_auth_url'] = options['os_auth_url'].replace('v3', 'v2.0')
self.swift_service = swiftclient.service.SwiftService(options)
self.add_executable_client_methods(self.swift_service,
'swiftclient.service')

View File

@ -24,6 +24,7 @@ from heatclient.v1 import resources
from heatclient.v1 import software_deployments as deployments
from heatclient.v1 import stacks
from congress.datasources import datasource_utils as ds_utils
from congress.datasources import heatv1_driver
from congress.tests import base
from congress.tests import helper
@ -33,12 +34,9 @@ class TestHeatV1Driver(base.TestCase):
def setUp(self):
super(TestHeatV1Driver, self).setUp()
self.keystone_client_p = mock.patch(
"keystoneclient.v2_0.client.Client")
self.keystone_client_p.start()
self.heat_client_p = mock.patch("heatclient.v1.client.Client")
self.heat_client_p.start()
ds_utils.get_keystone_session = mock.MagicMock()
args = helper.datasource_openstack_args()
args['poll_time'] = 0
args['client'] = mock.MagicMock()

View File

@ -123,7 +123,7 @@ function _configure_service {
--config username=$OS_USERNAME \
--config tenant_name=$OS_PROJECT_NAME \
--config password=$OS_PASSWORD \
--config auth_url=http://$SERVICE_HOST:5000/v2.0
--config auth_url=http://$SERVICE_HOST:5000/v3
fi
}