diff --git a/magnum/api/controllers/v1/certificate.py b/magnum/api/controllers/v1/certificate.py index 3ada360395..e26a990828 100644 --- a/magnum/api/controllers/v1/certificate.py +++ b/magnum/api/controllers/v1/certificate.py @@ -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) diff --git a/magnum/tests/functional/api/v1/clients/cert_client.py b/magnum/tests/functional/api/v1/clients/cert_client.py index e896ee9fbb..835484a20a 100644 --- a/magnum/tests/functional/api/v1/clients/cert_client.py +++ b/magnum/tests/functional/api/v1/clients/cert_client.py @@ -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): diff --git a/magnum/tests/functional/api/v1/test_cluster.py b/magnum/tests/functional/api/v1/test_cluster.py index 2a356a0594..a1abfa883e 100644 --- a/magnum/tests/functional/api/v1/test_cluster.py +++ b/magnum/tests/functional/api/v1/test_cluster.py @@ -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) diff --git a/magnum/tests/functional/common/datagen.py b/magnum/tests/functional/common/datagen.py index 4b15301c35..a09d7f991c 100644 --- a/magnum/tests/functional/common/datagen.py +++ b/magnum/tests/functional/common/datagen.py @@ -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 diff --git a/magnum/tests/unit/api/controllers/v1/test_certificate.py b/magnum/tests/unit/api/controllers/v1/test_certificate.py index 07a3d04f42..42065f89d9 100644 --- a/magnum/tests/unit/api/controllers/v1/test_certificate.py +++ b/magnum/tests/unit/api/controllers/v1/test_certificate.py @@ -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) diff --git a/magnum/tests/unit/api/utils.py b/magnum/tests/unit/api/utils.py index be7ee407b4..c9598a500c 100644 --- a/magnum/tests/unit/api/utils.py +++ b/magnum/tests/unit/api/utils.py @@ -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') }