Calls to federated service providers using Keystone-to-Keystone
Allow users to direct calls using the OpenStackClient to a remote federated service provider using Keystone 2 Keystone federation. Change-Id: Icbdb286f840ecd3a57c64ef69b9e55925439b2f1
This commit is contained in:
parent
5482f52612
commit
572eddc142
@ -15,6 +15,7 @@
|
||||
|
||||
import argparse
|
||||
|
||||
from keystoneauth1.identity.v3 import k2k
|
||||
from keystoneauth1.loading import base
|
||||
|
||||
from osc_lib import exceptions as exc
|
||||
@ -190,3 +191,25 @@ def build_auth_plugins_option_parser(parser):
|
||||
help=argparse.SUPPRESS,
|
||||
)
|
||||
return parser
|
||||
|
||||
|
||||
def get_keystone2keystone_auth(local_auth, service_provider,
|
||||
project_id=None, project_name=None,
|
||||
project_domain_id=None,
|
||||
project_domain_name=None):
|
||||
"""Return Keystone 2 Keystone authentication for service provider.
|
||||
|
||||
:param local_auth: authentication to use with the local Keystone
|
||||
:param service_provider: service provider id as registered in Keystone
|
||||
:param project_id: project id to scope to in the service provider
|
||||
:param project_name: project name to scope to in the service provider
|
||||
:param project_domain_id: id of domain in the service provider
|
||||
:param project_domain_name: name of domain to in the service provider
|
||||
:return: Keystone2Keystone auth object for service provider
|
||||
"""
|
||||
return k2k.Keystone2Keystone(local_auth,
|
||||
service_provider,
|
||||
project_id=project_id,
|
||||
project_name=project_name,
|
||||
project_domain_id=project_domain_id,
|
||||
project_domain_name=project_domain_name)
|
||||
|
@ -169,6 +169,17 @@ class ClientManager(object):
|
||||
LOG.debug('Using parameters %s',
|
||||
strutils.mask_password(self._cli_options.auth))
|
||||
self.auth = self._cli_options.get_auth()
|
||||
|
||||
if self._cli_options.service_provider:
|
||||
self.auth = auth.get_keystone2keystone_auth(
|
||||
self.auth,
|
||||
self._cli_options.service_provider,
|
||||
self._cli_options.remote_project_id,
|
||||
self._cli_options.remote_project_name,
|
||||
self._cli_options.remote_project_domain_id,
|
||||
self._cli_options.remote_project_domain_name
|
||||
)
|
||||
|
||||
self.session = osc_session.TimingSession(
|
||||
auth=self.auth,
|
||||
verify=self.verify,
|
||||
|
@ -25,10 +25,13 @@ AUTH_URL = "http://0.0.0.0"
|
||||
USERNAME = "itchy"
|
||||
PASSWORD = "scratchy"
|
||||
PROJECT_NAME = "poochie"
|
||||
PROJECT_ID = "30c3da29-61f5-4b7b-8eb2-3d18287428c7"
|
||||
REGION_NAME = "richie"
|
||||
INTERFACE = "catchy"
|
||||
VERSION = "3"
|
||||
|
||||
SERVICE_PROVIDER_ID = "bob"
|
||||
|
||||
TEST_RESPONSE_DICT = fixture.V2Token(token_id=AUTH_TOKEN,
|
||||
user_name=USERNAME)
|
||||
_s = TEST_RESPONSE_DICT.add_service('identity', name='keystone')
|
||||
|
@ -19,6 +19,7 @@ import mock
|
||||
from keystoneauth1.access import service_catalog
|
||||
from keystoneauth1 import exceptions as ksa_exceptions
|
||||
from keystoneauth1.identity import generic as generic_plugin
|
||||
from keystoneauth1.identity.v3 import k2k
|
||||
from keystoneauth1 import loading
|
||||
from os_client_config import cloud_config
|
||||
|
||||
@ -32,6 +33,13 @@ AUTH_REF = {'version': 'v2.0'}
|
||||
AUTH_REF.update(fakes.TEST_RESPONSE_DICT['access'])
|
||||
SERVICE_CATALOG = service_catalog.ServiceCatalogV2(AUTH_REF)
|
||||
|
||||
AUTH_DICT = {
|
||||
'auth_url': fakes.AUTH_URL,
|
||||
'username': fakes.USERNAME,
|
||||
'password': fakes.PASSWORD,
|
||||
'project_name': fakes.PROJECT_NAME
|
||||
}
|
||||
|
||||
|
||||
# This is deferred in api.auth but we need it here...
|
||||
auth.get_options_list()
|
||||
@ -257,21 +265,15 @@ class TestClientManager(utils.TestClientManager):
|
||||
|
||||
@mock.patch('osc_lib.api.auth.check_valid_authentication_options')
|
||||
def test_client_manager_auth_setup_once(self, check_authn_options_func):
|
||||
auth_dict = {
|
||||
'auth_url': fakes.AUTH_URL,
|
||||
'username': fakes.USERNAME,
|
||||
'password': fakes.PASSWORD,
|
||||
'project_name': fakes.PROJECT_NAME,
|
||||
}
|
||||
loader = loading.get_plugin_loader('password')
|
||||
auth_plugin = loader.load_from_options(**auth_dict)
|
||||
auth_plugin = loader.load_from_options(**AUTH_DICT)
|
||||
client_manager = self._clientmanager_class()(
|
||||
cli_options=cloud_config.CloudConfig(
|
||||
name='t1',
|
||||
region='1',
|
||||
config=dict(
|
||||
auth_type='password',
|
||||
auth=auth_dict,
|
||||
auth=AUTH_DICT,
|
||||
interface=fakes.INTERFACE,
|
||||
region_name=fakes.REGION_NAME,
|
||||
),
|
||||
@ -306,3 +308,34 @@ class TestClientManager(utils.TestClientManager):
|
||||
)
|
||||
|
||||
self.assertFalse(client_manager.is_service_available('network'))
|
||||
|
||||
def test_client_manager_k2k_auth_setup(self):
|
||||
loader = loading.get_plugin_loader('password')
|
||||
auth_plugin = loader.load_from_options(**AUTH_DICT)
|
||||
client_manager = self._clientmanager_class()(
|
||||
cli_options=cloud_config.CloudConfig(
|
||||
name='t1',
|
||||
region='1',
|
||||
config=dict(
|
||||
auth_type='password',
|
||||
auth=AUTH_DICT,
|
||||
interface=fakes.INTERFACE,
|
||||
region_name=fakes.REGION_NAME,
|
||||
service_provider=fakes.SERVICE_PROVIDER_ID,
|
||||
remote_project_id=fakes.PROJECT_ID
|
||||
),
|
||||
auth_plugin=auth_plugin,
|
||||
),
|
||||
api_version={
|
||||
'identity': '3',
|
||||
},
|
||||
)
|
||||
|
||||
self.assertFalse(client_manager._auth_setup_completed)
|
||||
client_manager.setup_auth()
|
||||
# Note(knikolla): Make sure that the auth object is of the correct
|
||||
# type and that the service_provider is correctly set.
|
||||
self.assertIsInstance(client_manager.auth, k2k.Keystone2Keystone)
|
||||
self.assertEqual(client_manager.auth._sp_id, fakes.SERVICE_PROVIDER_ID)
|
||||
self.assertEqual(client_manager.auth.project_id, fakes.PROJECT_ID)
|
||||
self.assertTrue(client_manager._auth_setup_completed)
|
||||
|
Loading…
Reference in New Issue
Block a user