Send swiftclient username/password and token

For longer-lived operations, tokens can timeout and we need to get new
ones. While in theory we should be keystoneauth aware and passing around
sessions, swiftclient does not yet support this. So, instead of passing
in just a preauthtoken, also pass in credentials if we have them. However, for
plugin types that swift does not know about directly, only preauthtoken will
be used as before.

Change-Id: If724fdcd0649d9fa3b3ee7b127e49a3f77e3b767
This commit is contained in:
Monty Taylor 2016-02-10 17:37:54 -06:00
parent 10a9369062
commit dd1f03c597
2 changed files with 176 additions and 18 deletions

View File

@ -355,22 +355,53 @@ class CloudConfig(object):
return client_class(**constructor_kwargs)
def _get_swift_client(self, client_class, **kwargs):
auth_args = self.get_auth_args()
auth_version = self.get_api_version('identity')
session = self.get_session()
token = session.get_token()
endpoint = self.get_session_endpoint(service_key='object-store')
if not endpoint:
return None
# If we have a username/password, we want to pass them to
# swift - because otherwise it will not re-up tokens appropriately
# However, if we only have non-password auth, then get a token
# and pass it in
swift_kwargs = dict(
auth_version=auth_version,
preauthurl=endpoint,
preauthtoken=token,
auth_version=self.get_api_version('identity'),
os_options=dict(
region_name=self.get_region_name(),
auth_token=token,
object_storage_url=endpoint,
region_name=self.get_region_name()),
)
service_type=self.get_service_type('object-store'),
endpoint_type=self.get_interface('object-store'),
))
if self.config['api_timeout'] is not None:
swift_kwargs['timeout'] = float(self.config['api_timeout'])
# create with password
swift_kwargs['user'] = auth_args.get('username')
swift_kwargs['key'] = auth_args.get('password')
swift_kwargs['authurl'] = auth_args.get('auth_url')
os_options = {}
if auth_version == '2.0':
os_options['tenant_name'] = auth_args.get('project_name')
os_options['tenant_id'] = auth_args.get('project_id')
else:
os_options['project_name'] = auth_args.get('project_name')
os_options['project_id'] = auth_args.get('project_id')
for key in (
'user_id',
'project_domain_id',
'project_domain_name',
'user_domain_id',
'user_domain_name'):
os_options[key] = auth_args.get(key)
swift_kwargs['os_options'].update(os_options)
return client_class(**swift_kwargs)
def get_cache_expiration_time(self):

View File

@ -235,10 +235,23 @@ class TestCloudConfig(base.TestCase):
region_name='region-al',
service_type='orchestration')
@mock.patch.object(cloud_config.CloudConfig, 'get_api_version')
@mock.patch.object(cloud_config.CloudConfig, 'get_auth_args')
@mock.patch.object(cloud_config.CloudConfig, 'get_session_endpoint')
def test_legacy_client_object_store(self, mock_get_session_endpoint):
def test_legacy_client_object_store_password(
self,
mock_get_session_endpoint,
mock_get_auth_args,
mock_get_api_version):
mock_client = mock.Mock()
mock_get_session_endpoint.return_value = 'http://example.com/v2'
mock_get_session_endpoint.return_value = 'http://swift.example.com'
mock_get_api_version.return_value = '3'
mock_get_auth_args.return_value = dict(
username='testuser',
password='testpassword',
project_name='testproject',
auth_url='http://example.com',
)
config_dict = defaults.get_defaults()
config_dict.update(fake_services_dict)
cc = cloud_config.CloudConfig(
@ -246,19 +259,106 @@ class TestCloudConfig(base.TestCase):
cc.get_legacy_client('object-store', mock_client)
mock_client.assert_called_with(
preauthtoken=mock.ANY,
auth_version=u'3',
authurl='http://example.com',
key='testpassword',
os_options={
'auth_token': mock.ANY,
'region_name': 'region-al',
'object_storage_url': 'http://example.com/v2'
'object_storage_url': 'http://swift.example.com',
'user_id': None,
'user_domain_name': None,
'project_name': 'testproject',
'project_domain_name': None,
'project_domain_id': None,
'project_id': None,
'service_type': 'object-store',
'endpoint_type': 'public',
'user_domain_id': None
},
preauthurl='http://example.com/v2',
auth_version='2.0')
preauthurl='http://swift.example.com',
user='testuser')
@mock.patch.object(cloud_config.CloudConfig, 'get_auth_args')
@mock.patch.object(cloud_config.CloudConfig, 'get_session_endpoint')
def test_legacy_client_object_store_timeout(
self, mock_get_session_endpoint):
def test_legacy_client_object_store_password_v2(
self, mock_get_session_endpoint, mock_get_auth_args):
mock_client = mock.Mock()
mock_get_session_endpoint.return_value = 'http://swift.example.com'
mock_get_auth_args.return_value = dict(
username='testuser',
password='testpassword',
project_name='testproject',
auth_url='http://example.com',
)
config_dict = defaults.get_defaults()
config_dict.update(fake_services_dict)
cc = cloud_config.CloudConfig(
"test1", "region-al", config_dict, auth_plugin=mock.Mock())
cc.get_legacy_client('object-store', mock_client)
mock_client.assert_called_with(
preauthtoken=mock.ANY,
auth_version=u'2.0',
authurl='http://example.com',
key='testpassword',
os_options={
'auth_token': mock.ANY,
'region_name': 'region-al',
'object_storage_url': 'http://swift.example.com',
'user_id': None,
'user_domain_name': None,
'tenant_name': 'testproject',
'project_domain_name': None,
'project_domain_id': None,
'tenant_id': None,
'service_type': 'object-store',
'endpoint_type': 'public',
'user_domain_id': None
},
preauthurl='http://swift.example.com',
user='testuser')
@mock.patch.object(cloud_config.CloudConfig, 'get_auth_args')
@mock.patch.object(cloud_config.CloudConfig, 'get_session_endpoint')
def test_legacy_client_object_store(
self, mock_get_session_endpoint, mock_get_auth_args):
mock_client = mock.Mock()
mock_get_session_endpoint.return_value = 'http://example.com/v2'
mock_get_auth_args.return_value = {}
config_dict = defaults.get_defaults()
config_dict.update(fake_services_dict)
cc = cloud_config.CloudConfig(
"test1", "region-al", config_dict, auth_plugin=mock.Mock())
cc.get_legacy_client('object-store', mock_client)
mock_client.assert_called_with(
preauthtoken=mock.ANY,
auth_version=u'2.0',
authurl=None,
key=None,
os_options={
'auth_token': mock.ANY,
'region_name': 'region-al',
'object_storage_url': 'http://example.com/v2',
'user_id': None,
'user_domain_name': None,
'tenant_name': None,
'project_domain_name': None,
'project_domain_id': None,
'tenant_id': None,
'service_type': 'object-store',
'endpoint_type': 'public',
'user_domain_id': None
},
preauthurl='http://example.com/v2',
user=None)
@mock.patch.object(cloud_config.CloudConfig, 'get_auth_args')
@mock.patch.object(cloud_config.CloudConfig, 'get_session_endpoint')
def test_legacy_client_object_store_timeout(
self, mock_get_session_endpoint, mock_get_auth_args):
mock_client = mock.Mock()
mock_get_session_endpoint.return_value = 'http://example.com/v2'
mock_get_auth_args.return_value = {}
config_dict = defaults.get_defaults()
config_dict.update(fake_services_dict)
config_dict['api_timeout'] = 9
@ -267,32 +367,59 @@ class TestCloudConfig(base.TestCase):
cc.get_legacy_client('object-store', mock_client)
mock_client.assert_called_with(
preauthtoken=mock.ANY,
auth_version=u'2.0',
authurl=None,
key=None,
os_options={
'auth_token': mock.ANY,
'region_name': 'region-al',
'object_storage_url': 'http://example.com/v2'
'object_storage_url': 'http://example.com/v2',
'user_id': None,
'user_domain_name': None,
'tenant_name': None,
'project_domain_name': None,
'project_domain_id': None,
'tenant_id': None,
'service_type': 'object-store',
'endpoint_type': 'public',
'user_domain_id': None
},
preauthurl='http://example.com/v2',
auth_version='2.0',
timeout=9.0)
timeout=9.0,
user=None)
def test_legacy_client_object_store_endpoint(self):
@mock.patch.object(cloud_config.CloudConfig, 'get_auth_args')
def test_legacy_client_object_store_endpoint(
self, mock_get_auth_args):
mock_client = mock.Mock()
mock_get_auth_args.return_value = {}
config_dict = defaults.get_defaults()
config_dict.update(fake_services_dict)
config_dict['object_store_endpoint'] = 'http://example.com/v2'
config_dict['object_store_endpoint'] = 'http://example.com/swift'
cc = cloud_config.CloudConfig(
"test1", "region-al", config_dict, auth_plugin=mock.Mock())
cc.get_legacy_client('object-store', mock_client)
mock_client.assert_called_with(
preauthtoken=mock.ANY,
auth_version=u'2.0',
authurl=None,
key=None,
os_options={
'auth_token': mock.ANY,
'region_name': 'region-al',
'object_storage_url': 'http://example.com/v2'
'object_storage_url': 'http://example.com/swift',
'user_id': None,
'user_domain_name': None,
'tenant_name': None,
'project_domain_name': None,
'project_domain_id': None,
'tenant_id': None,
'service_type': 'object-store',
'endpoint_type': 'public',
'user_domain_id': None
},
preauthurl='http://example.com/v2',
auth_version='2.0')
preauthurl='http://example.com/swift',
user=None)
@mock.patch.object(cloud_config.CloudConfig, 'get_session_endpoint')
def test_legacy_client_image(self, mock_get_session_endpoint):