Add REST api for Certificates

This patch adds REST API for Certificates.

Change-Id: Ifb97de4536e00bdfc806f579784609d9bdac1911
Partial-Implements: blueprint cluster-certificates
This commit is contained in:
Shu Muto 2016-08-30 15:49:12 +09:00
parent 319253acf1
commit 415cb2f64f
5 changed files with 109 additions and 5 deletions

View File

@ -40,6 +40,8 @@ CLUSTER_CREATE_ATTRS = ['name', 'baymodel_id', 'node_count',
'discovery_url', 'cluster_create_timeout', 'discovery_url', 'cluster_create_timeout',
'master_count'] 'master_count']
CERTIFICATE_CREATE_ATTRS = ['cluster_uuid', 'csr']
@memoized @memoized
def magnumclient(request): def magnumclient(request):
@ -125,3 +127,18 @@ def cluster_list(request, limit=None, marker=None, sort_key=None,
def cluster_show(request, id): def cluster_show(request, id):
return magnumclient(request).bays.get(id) return magnumclient(request).bays.get(id)
def certificate_create(request, **kwargs):
args = {}
for (key, value) in kwargs.items():
if key in CERTIFICATE_CREATE_ATTRS:
args[key] = value
else:
raise exceptions.BadRequest(
"Key must be in %s" % ",".join(CERTIFICATE_CREATE_ATTRS))
return magnumclient(request).certificates.create(**args)
def certificate_show(request, id):
return magnumclient(request).certificates.get(id)

View File

@ -123,3 +123,29 @@ class Clusters(generic.View):
return rest_utils.CreatedResponse( return rest_utils.CreatedResponse(
'/api/container_infra/cluster/%s' % new_cluster.uuid, '/api/container_infra/cluster/%s' % new_cluster.uuid,
new_cluster.to_dict()) new_cluster.to_dict())
@urls.register
class Certificates(generic.View):
"""API for Magnum Certificates"""
url_regex = r'container_infra/certificates/(?P<cluster_id>[^/]+)$'
@rest_utils.ajax()
def get(self, request, cluster_id):
"""Get a certificate from a cluster.
Returns the CA.pem string on success
"""
ca = magnum.certificate_show(request, cluster_id)
return ca.to_dict()
@rest_utils.ajax(data_required=True)
def post(self, request):
"""Create a new Certificate.
Returns the new Cert.pem string from csr for a cluster on success.
"""
new_cert = magnum.certificate_create(request, **request.DATA)
return rest_utils.CreatedResponse(
'/api/container_infra/certificates/',
new_cert.to_dict())

View File

@ -38,13 +38,15 @@
getClusterTemplates: getClusterTemplates, getClusterTemplates: getClusterTemplates,
deleteClusterTemplate: deleteClusterTemplate, deleteClusterTemplate: deleteClusterTemplate,
deleteClusterTemplates: deleteClusterTemplates, deleteClusterTemplates: deleteClusterTemplates,
showCertificate: showCertificate,
signCertificate: signCertificate,
}; };
return service; return service;
////////// //////////////
// Clusters // // Clusters //
////////// //////////////
function createCluster(params) { function createCluster(params) {
return apiService.post('/api/container_infra/clusters/', params) return apiService.post('/api/container_infra/clusters/', params)
@ -83,14 +85,14 @@
}); });
} }
/////////////// //////////////////////
// ClusterTemplates // // ClusterTemplates //
/////////////// //////////////////////
function createClusterTemplate(params) { function createClusterTemplate(params) {
return apiService.post('/api/container_infra/cluster_templates/', params) return apiService.post('/api/container_infra/cluster_templates/', params)
.error(function() { .error(function() {
toastService.add('error', gettext('Unable to create cluster template')); toastService.add('error', gettext('Unable to create cluster template.'));
}); });
} }
@ -123,5 +125,23 @@
toastService.add('error', gettext('Unable to delete the cluster templates.')); toastService.add('error', gettext('Unable to delete the cluster templates.'));
}) })
} }
//////////////////
// Certificates //
//////////////////
function signCertificate(params) {
return apiService.post('/api/container_infra/certificates/', params)
.error(function() {
toastService.add('error', gettext('Unable to sign certificate.'));
});
}
function showCertificate(id) {
return apiService.get('/api/container_infra/certificates/' + id)
.error(function() {
toastService.add('error', gettext('Unable to retrieve the certificate.'));
});
}
} }
}()); }());

View File

@ -105,6 +105,26 @@ class MagnumRestTestCase(test.TestCase):
request, request,
u'bay_id') u'bay_id')
# Certificates
@mock.patch.object(magnum, 'magnum')
def test_certificate_create(self, client):
test_certificates = mock_resource(TEST.certificates.list())
test_certificate = test_certificates[0]
test_body = json.dumps(test_certificate.to_dict())
request = self.mock_rest_request(body=test_body)
test_res_list = mock_resource(TEST.certificate_res_list.list())
test_res = test_res_list[0]
client.certificate_create.return_value = test_res
response = magnum.Certificates().post(request)
res_body = json.loads(response.content)
self.assertStatusCode(response, 201)
self.assertEqual(res_body['pem'], test_res.to_dict()['pem'])
client.certificate_create.assert_called_once_with(
request, **test_certificate.to_dict())
def mock_resource(resource): def mock_resource(resource):
"""Utility function to make mocking more DRY""" """Utility function to make mocking more DRY"""

View File

@ -19,6 +19,8 @@ def data(TEST):
# Test Data Container in Horizon # Test Data Container in Horizon
TEST.cluster_templates = utils.TestDataContainer() TEST.cluster_templates = utils.TestDataContainer()
TEST.clusters = utils.TestDataContainer() TEST.clusters = utils.TestDataContainer()
TEST.certificates = utils.TestDataContainer()
TEST.certificate_res_list = utils.TestDataContainer()
# Cluster Templates # Cluster Templates
cluster_template_dict_1 = {"uuid": 1, cluster_template_dict_1 = {"uuid": 1,
@ -56,3 +58,22 @@ def data(TEST):
"timeout": 0} "timeout": 0}
TEST.clusters.add(cluster_dict_1) TEST.clusters.add(cluster_dict_1)
# Certificates
certificate_1 = {"cluster_uuid": 1,
"csr": "kore-ya-kono\n"
"yuku-mo-kaheru-mo\n"
"wakarete-ha\n"
"shiru-mo-shiranu-mo\n"
"afusaka-no-seki"}
TEST.certificates.add(certificate_1)
certificate_res = {"cluster_uuid": 1,
"pem": "wata-no-hara\n"
"yasoshima-kakete\n"
"kogi-idenu-to\n"
"hito-niwa-tsugeyo\n"
"ama-no-tsuri-fune"}
TEST.certificate_res_list.add(certificate_res)