Merge "Add cluster to cert commands"
This commit is contained in:
commit
abafc6ef1c
|
@ -35,31 +35,35 @@ class Certificate(base.APIBase):
|
|||
certificate.
|
||||
"""
|
||||
|
||||
_bay_uuid = None
|
||||
"""uuid or logical name of bay"""
|
||||
_cluster_uuid = None
|
||||
"""uuid or logical name of cluster"""
|
||||
|
||||
_bay = None
|
||||
_cluster = None
|
||||
|
||||
def _get_bay_uuid(self):
|
||||
return self._bay_uuid
|
||||
def _get_cluster_uuid(self):
|
||||
return self._cluster_uuid
|
||||
|
||||
def _set_bay_uuid(self, value):
|
||||
if value and self._bay_uuid != value:
|
||||
def _set_cluster_uuid(self, value):
|
||||
if value and self._cluster_uuid != value:
|
||||
try:
|
||||
self._bay = api_utils.get_resource('Bay', value)
|
||||
self._bay_uuid = self._bay.uuid
|
||||
self._cluster = api_utils.get_resource('Bay', value)
|
||||
self._cluster_uuid = self._cluster.uuid
|
||||
except exception.ClusterNotFound as e:
|
||||
# Change error code because 404 (NotFound) is inappropriate
|
||||
# response for a POST request to create a Bay
|
||||
e.code = 400 # BadRequest
|
||||
raise
|
||||
elif value == wtypes.Unset:
|
||||
self._bay_uuid = wtypes.Unset
|
||||
self._cluster_uuid = wtypes.Unset
|
||||
|
||||
bay_uuid = wsme.wsproperty(wtypes.text, _get_bay_uuid,
|
||||
_set_bay_uuid, mandatory=True)
|
||||
bay_uuid = wsme.wsproperty(wtypes.text, _get_cluster_uuid,
|
||||
_set_cluster_uuid)
|
||||
"""The bay UUID or id"""
|
||||
|
||||
cluster_uuid = wsme.wsproperty(wtypes.text, _get_cluster_uuid,
|
||||
_set_cluster_uuid)
|
||||
"""The cluster UUID or id"""
|
||||
|
||||
links = wsme.wsattr([link.Link], readonly=True)
|
||||
"""A list containing a self link and associated certificate links"""
|
||||
|
||||
|
@ -80,15 +84,22 @@ class Certificate(base.APIBase):
|
|||
self.fields.append(field)
|
||||
setattr(self, field, kwargs.get(field, wtypes.Unset))
|
||||
|
||||
def get_bay(self):
|
||||
if not self._bay:
|
||||
self._bay = api_utils.get_resource('Bay', self.bay_uuid)
|
||||
return self._bay
|
||||
# set the attribute for cluster_uuid
|
||||
self.fields.append('cluster_uuid')
|
||||
if 'cluster_uuid' in kwargs.keys():
|
||||
setattr(self, 'cluster_uuid', kwargs.get('cluster_uuid',
|
||||
wtypes.Unset))
|
||||
|
||||
def get_cluster(self):
|
||||
if not self._cluster:
|
||||
self._cluster = api_utils.get_resource('Bay', self.cluster_uuid)
|
||||
return self._cluster
|
||||
|
||||
@staticmethod
|
||||
def _convert_with_links(certificate, url, expand=True):
|
||||
if not expand:
|
||||
certificate.unset_fields_except(['bay_uuid', 'csr', 'pem'])
|
||||
certificate.unset_fields_except(['bay_uuid', 'cluster_uuid',
|
||||
'csr', 'pem'])
|
||||
|
||||
certificate.links = [link.Link.make_link('self', url,
|
||||
'certificates',
|
||||
|
@ -108,6 +119,7 @@ class Certificate(base.APIBase):
|
|||
@classmethod
|
||||
def sample(cls, expand=True):
|
||||
sample = cls(bay_uuid='7ae81bb3-dec3-4289-8d6c-da80bd8001ae',
|
||||
cluster_uuid='7ae81bb3-dec3-4289-8d6c-da80bd8001ae',
|
||||
created_at=timeutils.utcnow(),
|
||||
csr='AAA....AAA')
|
||||
return cls._convert_with_links(sample, 'http://localhost:9511', expand)
|
||||
|
@ -124,17 +136,17 @@ class CertificateController(base.Controller):
|
|||
}
|
||||
|
||||
@expose.expose(Certificate, types.uuid_or_name)
|
||||
def get_one(self, bay_ident):
|
||||
"""Retrieve CA information about the given bay.
|
||||
def get_one(self, cluster_ident):
|
||||
"""Retrieve CA information about the given cluster.
|
||||
|
||||
:param bay_ident: UUID of a bay or
|
||||
logical name of the bay.
|
||||
:param cluster_ident: UUID of a cluster or
|
||||
logical name of the cluster.
|
||||
"""
|
||||
context = pecan.request.context
|
||||
bay = api_utils.get_resource('Bay', bay_ident)
|
||||
policy.enforce(context, 'certificate:get', bay,
|
||||
cluster = api_utils.get_resource('Bay', cluster_ident)
|
||||
policy.enforce(context, 'certificate:get', cluster,
|
||||
action='certificate:get')
|
||||
certificate = pecan.request.rpcapi.get_ca_certificate(bay)
|
||||
certificate = pecan.request.rpcapi.get_ca_certificate(cluster)
|
||||
return Certificate.convert_with_links(certificate)
|
||||
|
||||
@expose.expose(Certificate, body=Certificate, status_code=201)
|
||||
|
@ -144,14 +156,14 @@ class CertificateController(base.Controller):
|
|||
:param certificate: a certificate within the request body.
|
||||
"""
|
||||
context = pecan.request.context
|
||||
bay = certificate.get_bay()
|
||||
policy.enforce(context, 'certificate:create', bay,
|
||||
cluster = certificate.get_cluster()
|
||||
policy.enforce(context, 'certificate:create', cluster,
|
||||
action='certificate:create')
|
||||
certificate_dict = certificate.as_dict()
|
||||
certificate_dict['project_id'] = context.project_id
|
||||
certificate_dict['user_id'] = context.user_id
|
||||
cert_obj = objects.Certificate(context, **certificate_dict)
|
||||
|
||||
new_cert = pecan.request.rpcapi.sign_certificate(bay,
|
||||
new_cert = pecan.request.rpcapi.sign_certificate(cluster,
|
||||
cert_obj)
|
||||
return Certificate.convert_with_links(new_cert)
|
||||
|
|
|
@ -20,25 +20,25 @@ class CertClient(client.MagnumClient):
|
|||
url = "/certificates"
|
||||
|
||||
@classmethod
|
||||
def cert_uri(cls, bay_id):
|
||||
"""Construct bay uri
|
||||
def cert_uri(cls, cluster_id):
|
||||
"""Construct cluster uri
|
||||
|
||||
:param bay_id: bay uuid or name
|
||||
:param cluster_id: cluster uuid or name
|
||||
:returns: url string
|
||||
"""
|
||||
|
||||
return "{0}/{1}".format(cls.url, bay_id)
|
||||
return "{0}/{1}".format(cls.url, cluster_id)
|
||||
|
||||
def get_cert(self, bay_id, **kwargs):
|
||||
"""Makes GET /certificates/bay_id request and returns CertEntity
|
||||
def get_cert(self, cluster_id, **kwargs):
|
||||
"""Makes GET /certificates/cluster_id request and returns CertEntity
|
||||
|
||||
Abstracts REST call to return a single cert based on uuid or name
|
||||
|
||||
:param bay_id: bay uuid or name
|
||||
:returns: response object and BayCollection object
|
||||
:param cluster_id: cluster uuid or name
|
||||
:returns: response object and ClusterCollection object
|
||||
"""
|
||||
|
||||
resp, body = self.get(self.cert_uri(bay_id))
|
||||
resp, body = self.get(self.cert_uri(cluster_id))
|
||||
return self.deserialize(resp, body, cert_model.CertEntity)
|
||||
|
||||
def post_cert(self, model, **kwargs):
|
||||
|
|
|
@ -182,7 +182,7 @@ Q0uA0aVog3f5iJxCa3Hp5gxbJQ6zV6kJ0TEsuaaOhEko9sdpCoPOnRBm2i/XRD2D
|
|||
resp, cert_model = self.cert_client.post_cert(cert_data_model)
|
||||
self.LOG.debug("cert resp: %s" % resp)
|
||||
self.assertEqual(201, resp.status)
|
||||
self.assertEqual(cert_model.bay_uuid, cluster_model.uuid)
|
||||
self.assertEqual(cert_model.cluster_uuid, cluster_model.uuid)
|
||||
self.assertIsNotNone(cert_model.pem)
|
||||
self.assertIn('-----BEGIN CERTIFICATE-----', cert_model.pem)
|
||||
self.assertIn('-----END CERTIFICATE-----', cert_model.pem)
|
||||
|
|
|
@ -322,11 +322,11 @@ def bay_node_count_patch_data(node_count=2):
|
|||
return baypatch_model.BayPatchCollection.from_dict(data)
|
||||
|
||||
|
||||
def cert_data(bay_uuid, csr_data):
|
||||
def cert_data(cluster_uuid, csr_data):
|
||||
data = {
|
||||
"bay_uuid": bay_uuid,
|
||||
"csr": csr_data,
|
||||
}
|
||||
"cluster_uuid": cluster_uuid,
|
||||
"csr": csr_data}
|
||||
|
||||
model = cert_model.CertEntity.from_dict(data)
|
||||
|
||||
return model
|
||||
|
|
|
@ -25,13 +25,13 @@ class TestCertObject(base.TestCase):
|
|||
@mock.patch('magnum.api.utils.get_resource')
|
||||
def test_cert_init(self, mock_get_resource):
|
||||
cert_dict = api_utils.cert_post_data()
|
||||
mock_bay = mock.MagicMock()
|
||||
mock_bay.uuid = cert_dict['bay_uuid']
|
||||
mock_get_resource.return_value = mock_bay
|
||||
mock_cluster = mock.MagicMock()
|
||||
mock_cluster.uuid = cert_dict['cluster_uuid']
|
||||
mock_get_resource.return_value = mock_cluster
|
||||
|
||||
cert = api_cert.Certificate(**cert_dict)
|
||||
|
||||
self.assertEqual(cert_dict['bay_uuid'], cert.bay_uuid)
|
||||
self.assertEqual(cert_dict['cluster_uuid'], cert.cluster_uuid)
|
||||
self.assertEqual(cert_dict['csr'], cert.csr)
|
||||
self.assertEqual(cert_dict['pem'], cert.pem)
|
||||
|
||||
|
@ -40,7 +40,7 @@ class TestGetCertificate(api_base.FunctionalTest):
|
|||
|
||||
def setUp(self):
|
||||
super(TestGetCertificate, self).setUp()
|
||||
self.bay = obj_utils.create_test_bay(self.context)
|
||||
self.cluster = obj_utils.create_test_cluster(self.context)
|
||||
|
||||
conductor_api_patcher = mock.patch('magnum.conductor.api.API')
|
||||
self.conductor_api_class = conductor_api_patcher.start()
|
||||
|
@ -54,9 +54,11 @@ class TestGetCertificate(api_base.FunctionalTest):
|
|||
mock_cert.as_dict.return_value = fake_cert
|
||||
self.conductor_api.get_ca_certificate.return_value = mock_cert
|
||||
|
||||
response = self.get_json('/certificates/%s' % self.bay.uuid)
|
||||
response = self.get_json('/certificates/%s' % self.cluster.uuid)
|
||||
|
||||
self.assertEqual(self.bay.uuid, response['bay_uuid'])
|
||||
self.assertEqual(self.cluster.uuid, response['cluster_uuid'])
|
||||
# check that bay is still valid as well
|
||||
self.assertEqual(self.cluster.uuid, response['bay_uuid'])
|
||||
self.assertEqual(fake_cert['csr'], response['csr'])
|
||||
self.assertEqual(fake_cert['pem'], response['pem'])
|
||||
|
||||
|
@ -66,9 +68,11 @@ class TestGetCertificate(api_base.FunctionalTest):
|
|||
mock_cert.as_dict.return_value = fake_cert
|
||||
self.conductor_api.get_ca_certificate.return_value = mock_cert
|
||||
|
||||
response = self.get_json('/certificates/%s' % self.bay.name)
|
||||
response = self.get_json('/certificates/%s' % self.cluster.name)
|
||||
|
||||
self.assertEqual(self.bay.uuid, response['bay_uuid'])
|
||||
self.assertEqual(self.cluster.uuid, response['cluster_uuid'])
|
||||
# check that bay is still valid as well
|
||||
self.assertEqual(self.cluster.uuid, response['bay_uuid'])
|
||||
self.assertEqual(fake_cert['csr'], response['csr'])
|
||||
self.assertEqual(fake_cert['pem'], response['pem'])
|
||||
|
||||
|
@ -80,13 +84,13 @@ class TestGetCertificate(api_base.FunctionalTest):
|
|||
self.assertEqual('application/json', response.content_type)
|
||||
self.assertTrue(response.json['errors'])
|
||||
|
||||
def test_get_one_by_name_multiple_bay(self):
|
||||
obj_utils.create_test_bay(self.context, name='test_bay',
|
||||
uuid=uuidutils.generate_uuid())
|
||||
obj_utils.create_test_bay(self.context, name='test_bay',
|
||||
uuid=uuidutils.generate_uuid())
|
||||
def test_get_one_by_name_multiple_cluster(self):
|
||||
obj_utils.create_test_cluster(self.context, name='test_cluster',
|
||||
uuid=uuidutils.generate_uuid())
|
||||
obj_utils.create_test_cluster(self.context, name='test_cluster',
|
||||
uuid=uuidutils.generate_uuid())
|
||||
|
||||
response = self.get_json('/certificates/test_bay',
|
||||
response = self.get_json('/certificates/test_cluster',
|
||||
expect_errors=True)
|
||||
|
||||
self.assertEqual(409, response.status_int)
|
||||
|
@ -99,11 +103,11 @@ class TestGetCertificate(api_base.FunctionalTest):
|
|||
mock_cert.as_dict.return_value = fake_cert
|
||||
self.conductor_api.get_ca_certificate.return_value = mock_cert
|
||||
|
||||
response = self.get_json('/certificates/%s' % self.bay.uuid)
|
||||
response = self.get_json('/certificates/%s' % self.cluster.uuid)
|
||||
|
||||
self.assertIn('links', response.keys())
|
||||
self.assertEqual(2, len(response['links']))
|
||||
self.assertIn(self.bay.uuid, response['links'][0]['href'])
|
||||
self.assertIn(self.cluster.uuid, response['links'][0]['href'])
|
||||
for l in response['links']:
|
||||
bookmark = l['rel'] == 'bookmark'
|
||||
self.assertTrue(self.validate_link(l['href'], bookmark=bookmark))
|
||||
|
@ -113,7 +117,7 @@ class TestPost(api_base.FunctionalTest):
|
|||
|
||||
def setUp(self):
|
||||
super(TestPost, self).setUp()
|
||||
self.bay = obj_utils.create_test_bay(self.context)
|
||||
self.cluster = obj_utils.create_test_cluster(self.context)
|
||||
|
||||
conductor_api_patcher = mock.patch('magnum.conductor.api.API')
|
||||
self.conductor_api_class = conductor_api_patcher.start()
|
||||
|
@ -124,33 +128,51 @@ class TestPost(api_base.FunctionalTest):
|
|||
self.conductor_api.sign_certificate.side_effect = self._fake_sign
|
||||
|
||||
@staticmethod
|
||||
def _fake_sign(bay, cert):
|
||||
def _fake_sign(cluster, cert):
|
||||
cert.pem = 'fake-pem'
|
||||
return cert
|
||||
|
||||
def test_create_cert(self, ):
|
||||
new_cert = api_utils.cert_post_data(bay_uuid=self.bay.uuid)
|
||||
new_cert = api_utils.cert_post_data(cluster_uuid=self.cluster.uuid)
|
||||
del new_cert['pem']
|
||||
|
||||
response = self.post_json('/certificates', new_cert)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
self.assertEqual(201, response.status_int)
|
||||
self.assertEqual(new_cert['bay_uuid'], response.json['bay_uuid'])
|
||||
self.assertEqual(new_cert['cluster_uuid'],
|
||||
response.json['cluster_uuid'])
|
||||
# verify bay_uuid is still valid as well
|
||||
self.assertEqual(new_cert['cluster_uuid'], response.json['bay_uuid'])
|
||||
self.assertEqual('fake-pem', response.json['pem'])
|
||||
|
||||
# Test that bay_uuid is still backward compatible
|
||||
def test_create_cert_by_bay_name(self, ):
|
||||
new_cert = api_utils.cert_post_data(bay_uuid=self.bay.name)
|
||||
new_cert = api_utils.cert_post_data(cluster_uuid=self.cluster.uuid)
|
||||
del new_cert['pem']
|
||||
new_cert['bay_uuid'] = new_cert['cluster_uuid']
|
||||
del new_cert['cluster_uuid']
|
||||
|
||||
response = self.post_json('/certificates', new_cert)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
self.assertEqual(201, response.status_int)
|
||||
self.assertEqual(self.cluster.uuid, response.json['cluster_uuid'])
|
||||
# verify bay_uuid is still valid as well
|
||||
self.assertEqual(self.cluster.uuid, response.json['bay_uuid'])
|
||||
self.assertEqual('fake-pem', response.json['pem'])
|
||||
|
||||
def test_create_cert_by_cluster_name(self, ):
|
||||
new_cert = api_utils.cert_post_data(cluster_uuid=self.cluster.name)
|
||||
del new_cert['pem']
|
||||
|
||||
response = self.post_json('/certificates', new_cert)
|
||||
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
self.assertEqual(201, response.status_int)
|
||||
self.assertEqual(self.bay.uuid, response.json['bay_uuid'])
|
||||
self.assertEqual(self.cluster.uuid, response.json['cluster_uuid'])
|
||||
self.assertEqual('fake-pem', response.json['pem'])
|
||||
|
||||
def test_create_cert_bay_not_found(self, ):
|
||||
new_cert = api_utils.cert_post_data(bay_uuid='not_found')
|
||||
def test_create_cert_cluster_not_found(self, ):
|
||||
new_cert = api_utils.cert_post_data(cluster_uuid='not_found')
|
||||
del new_cert['pem']
|
||||
|
||||
response = self.post_json('/certificates', new_cert,
|
||||
|
@ -176,15 +198,15 @@ class TestCertPolicyEnforcement(api_base.FunctionalTest):
|
|||
response.json['errors'][0]['detail'])
|
||||
|
||||
def test_policy_disallow_get_one(self):
|
||||
bay = obj_utils.create_test_bay(self.context)
|
||||
cluster = obj_utils.create_test_cluster(self.context)
|
||||
self._common_policy_check(
|
||||
"certificate:get", self.get_json,
|
||||
'/certificates/%s' % bay.uuid,
|
||||
'/certificates/%s' % cluster.uuid,
|
||||
expect_errors=True)
|
||||
|
||||
def test_policy_disallow_create(self):
|
||||
bay = obj_utils.create_test_bay(self.context)
|
||||
cert = api_utils.cert_post_data(bay_uuid=bay.uuid)
|
||||
cluster = obj_utils.create_test_cluster(self.context)
|
||||
cert = api_utils.cert_post_data(cluster_uuid=cluster.uuid)
|
||||
self._common_policy_check(
|
||||
"certificate:create", self.post_json, '/certificates', cert,
|
||||
expect_errors=True)
|
||||
|
|
|
@ -61,7 +61,8 @@ def cluster_post_data(**kw):
|
|||
|
||||
def cert_post_data(**kw):
|
||||
return {
|
||||
'bay_uuid': kw.get('bay_uuid', '5d12f6fd-a196-4bf0-ae4c-1f639a523a52'),
|
||||
'cluster_uuid': kw.get('cluster_uuid',
|
||||
'5d12f6fd-a196-4bf0-ae4c-1f639a523a52'),
|
||||
'csr': kw.get('csr', 'fake-csr'),
|
||||
'pem': kw.get('pem', 'fake-pem')
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue