Store credential ID for AccessKey and SignalResponder
These resources create an ec2 keypair, which when managed via the keystone v3/credentials should be accessed via credential ID not the access key ID, so store the credential ID for performing any operations (get/update/delete) on the credential, as it's preferable to having to do a brute-force lookup by access key (no way to filter on the access key via v3/credentials) Change-Id: I5995fb003c998fc2d7f331c6da7430adcab168b2 blueprint: keystone-v3-only
This commit is contained in:
parent
ece8eefbc0
commit
bc1a93c856
|
@ -226,6 +226,10 @@ class AccessKey(resource.Resource):
|
|||
# SecretAccessKey attribute
|
||||
db_api.resource_data_set(self, 'secret_key', kp.secret,
|
||||
redact=True)
|
||||
# Also store the credential ID as this should be used to manage
|
||||
# the credential rather than the access key via v3/credentials
|
||||
db_api.resource_data_set(self, 'credential_id', kp.id,
|
||||
redact=True)
|
||||
|
||||
def handle_delete(self):
|
||||
self._secret = None
|
||||
|
@ -270,6 +274,9 @@ class AccessKey(resource.Resource):
|
|||
# Store the key in resource_data
|
||||
db_api.resource_data_set(self, 'secret_key',
|
||||
kp.secret, redact=True)
|
||||
# And the ID of the v3 credential
|
||||
db_api.resource_data_set(self, 'credential_id',
|
||||
kp.id, redact=True)
|
||||
except Exception as ex:
|
||||
logger.warn(_('could not get secret for %(username)s '
|
||||
'Error:%(msg)s') % {
|
||||
|
|
|
@ -56,6 +56,8 @@ class SignalResponder(resource.Resource):
|
|||
raise exception.Error(_("Error creating ec2 keypair for user %s") %
|
||||
user_id)
|
||||
else:
|
||||
db_api.resource_data_set(self, 'credential_id', kp.id,
|
||||
redact=True)
|
||||
db_api.resource_data_set(self, 'access_key', kp.access,
|
||||
redact=True)
|
||||
db_api.resource_data_set(self, 'secret_key', kp.secret,
|
||||
|
@ -80,7 +82,8 @@ class SignalResponder(resource.Resource):
|
|||
self.keystone().delete_stack_user(user_id)
|
||||
except clients.hkc.kc.exceptions.NotFound:
|
||||
pass
|
||||
for data_key in ('ec2_signed_url', 'access_key', 'secret_key'):
|
||||
for data_key in ('ec2_signed_url', 'access_key', 'secret_key',
|
||||
'credential_id'):
|
||||
try:
|
||||
db_api.resource_data_delete(self, data_key)
|
||||
except exception.NotFound:
|
||||
|
|
|
@ -78,12 +78,14 @@ class FakeClient(object):
|
|||
|
||||
class FakeKeystoneClient(object):
|
||||
def __init__(self, username='test_user', password='apassword',
|
||||
user_id='1234', access='4567', secret='8901'):
|
||||
user_id='1234', access='4567', secret='8901',
|
||||
credential_id='abcdxyz'):
|
||||
self.username = username
|
||||
self.password = password
|
||||
self.user_id = user_id
|
||||
self.access = access
|
||||
self.secret = secret
|
||||
self.credential_id = credential_id
|
||||
self.creds = None
|
||||
self.auth_token = 'abcd1234'
|
||||
|
||||
|
@ -107,6 +109,7 @@ class FakeKeystoneClient(object):
|
|||
if user_id == self.user_id:
|
||||
if not self.creds:
|
||||
class FakeCred(object):
|
||||
id = self.credential_id
|
||||
access = self.access
|
||||
secret = self.secret
|
||||
self.creds = FakeCred()
|
||||
|
|
|
@ -169,7 +169,9 @@ class SignalTest(HeatTestCase):
|
|||
self.m.StubOutWithMock(clients.OpenStackClients, 'keystone')
|
||||
clients.OpenStackClients.keystone().MultipleTimes().AndReturn(
|
||||
fakes.FakeKeystoneClient(
|
||||
access='anaccesskey', secret='verysecret'))
|
||||
access='anaccesskey',
|
||||
secret='verysecret',
|
||||
credential_id='mycredential'))
|
||||
self.m.ReplayAll()
|
||||
|
||||
self.stack.create()
|
||||
|
@ -179,11 +181,12 @@ class SignalTest(HeatTestCase):
|
|||
|
||||
# Ensure the resource data has been stored correctly
|
||||
rs_data = db_api.resource_data_get_all(rsrc)
|
||||
self.assertEqual('mycredential', rs_data.get('credential_id'))
|
||||
self.assertEqual('anaccesskey', rs_data.get('access_key'))
|
||||
self.assertEqual('verysecret', rs_data.get('secret_key'))
|
||||
self.assertEqual('1234', rs_data.get('user_id'))
|
||||
self.assertEqual(rsrc.resource_id, rs_data.get('user_id'))
|
||||
self.assertEqual(3, len(rs_data.keys()))
|
||||
self.assertEqual(4, len(rs_data.keys()))
|
||||
|
||||
# And that we remove it on delete
|
||||
scheduler.TaskRunner(rsrc.delete)()
|
||||
|
|
|
@ -299,7 +299,8 @@ class AccessKeyTest(UserPolicyTestCase):
|
|||
# Ensure the resource data has been stored correctly
|
||||
rs_data = db_api.resource_data_get_all(rsrc)
|
||||
self.assertEqual(self.fc.secret, rs_data.get('secret_key'))
|
||||
self.assertEqual(1, len(rs_data.keys()))
|
||||
self.assertEqual(self.fc.credential_id, rs_data.get('credential_id'))
|
||||
self.assertEqual(2, len(rs_data.keys()))
|
||||
|
||||
self.assertEqual(utils.PhysName(stack.name, 'CfnUser'),
|
||||
rsrc.FnGetAtt('UserName'))
|
||||
|
@ -332,6 +333,7 @@ class AccessKeyTest(UserPolicyTestCase):
|
|||
# Delete the resource data for secret_key, to test that existing
|
||||
# stacks which don't have the resource_data stored will continue
|
||||
# working via retrieving the keypair from keystone
|
||||
db_api.resource_data_delete(rsrc, 'credential_id')
|
||||
db_api.resource_data_delete(rsrc, 'secret_key')
|
||||
rs_data = db_api.resource_data_get_all(rsrc)
|
||||
self.assertEqual(0, len(rs_data.keys()))
|
||||
|
|
Loading…
Reference in New Issue