Merge "Add sign certificate action to cluster panel"

This commit is contained in:
Jenkins 2016-09-13 02:09:56 +00:00 committed by Gerrit Code Review
commit 824ea305fe
7 changed files with 341 additions and 2 deletions

View File

@ -126,8 +126,8 @@ class Clusters(generic.View):
@urls.register
class Certificates(generic.View):
"""API for Magnum Certificates"""
class Certificate(generic.View):
"""API for retrieving a single certificate"""
url_regex = r'container_infra/certificates/(?P<cluster_id>[^/]+)$'
@rest_utils.ajax()
@ -139,6 +139,12 @@ class Certificates(generic.View):
ca = magnum.certificate_show(request, cluster_id)
return ca.to_dict()
@urls.register
class Certificates(generic.View):
"""API for Magnum Certificates"""
url_regex = r'container_infra/certificates/$'
@rest_utils.ajax(data_required=True)
def post(self, request):
"""Create a new Certificate.

View File

@ -31,6 +31,7 @@
'horizon.dashboard.container-infra.clusters.create.service',
'horizon.dashboard.container-infra.clusters.delete.service',
'horizon.dashboard.container-infra.clusters.show-certificate.service',
'horizon.dashboard.container-infra.clusters.sign-certificate.service',
'horizon.dashboard.container-infra.clusters.resourceType',
];
@ -40,6 +41,7 @@
createClusterService,
deleteClusterService,
showCertificateService,
signCertificateService,
resourceType)
{
var clusterResourceType = registry.getResourceType(resourceType);
@ -58,6 +60,13 @@
template: {
text: gettext('Show Certificate')
}
})
.append({
id: 'signCertificateAction',
service: signCertificateService,
template: {
text: gettext('Sign Certificate')
}
});
clusterResourceType.batchActions

View File

@ -0,0 +1,68 @@
/**
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
(function() {
'use strict';
/**
* @ngdoc controller
* @name horizon.dashboard.container-infra.clusters.signCertificateController
* @ngController
*
* @description
* Controller for the container-infra cluster in sign certificate modal
*/
angular
.module('horizon.dashboard.container-infra.clusters')
.controller('horizon.dashboard.container-infra.clusters.signCertificateController', signCertificateController);
signCertificateController.$inject = [
'horizon.app.core.openstack-service-api.magnum',
'horizon.dashboard.container-infra.clusters.sign-certificate-model'
];
function signCertificateController(magnum, model) {
var ctrl = this;
ctrl.changeFile = changeFile;
ctrl.model = model;
ctrl.form = null;
magnum.getCluster(model.newCertificateSpec.cluster_uuid).success(onGetCluster);
function onGetCluster(response) {
ctrl.model.cluster_name = response.name;
}
function changeFile(files) {
// NOTE: this uses on-file-changed directive in Swift-UI included Horizon.
if (files.length) {
// load csr file and set into model
var reader = new FileReader();
reader.readAsText(files[0]);
reader.onload = function(ev){
model.newCertificateSpec.csr = reader.result;
ctrl.model.csrfile = files[0];
ctrl.form.$setDirty();
}
// Note that a $scope.$digest() is now needed for the change to the ngModel to be
// reflected in the page (since this callback is fired from inside a DOM event)
// but the on-file-changed directive currently does a digest after this callback
// is invoked.
} else {
model.newCertificateSpec.csr = "";
ctrl.model.csrfile = null;
ctrl.form.$setPristine();
}
}
}
})();

View File

@ -0,0 +1,39 @@
<div class="modal-header">
<button type="button" class="close" ng-click="$dismiss()" aria-hidden="true" aria-label="Close">
<span aria-hidden="true" class="fa fa-times"></span>
</button>
<div class="h3 modal-title">
<translate>Sign Certificate To Cluster: {$ ctrl.model.cluster_name $}</translate>
</div>
</div>
<div ng-form="ctrl.form">
<div class="modal-body">
<div class="row">
<div class="col-sm-6">
<fieldset>
<div class="form-group">
<label class="control-label required" for="csr-file">
<translate>CSR File</translate>
<span class="hz-icon-required fa fa-asterisk"></span>
</label>
<input id="csr-file" type="file" name="file" required
ng-model="ctrl.model.csrfile" on-file-change="ctrl.changeFile">
</div>
</fieldset>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-default" ng-click="$dismiss()">
<span class="fa fa-close"></span>
<translate>Cancel</translate>
</button>
<button class="btn btn-primary" ng-click="$close(ctrl.model)"
ng-disabled="ctrl.form.$invalid">
<span class="fa fa-upload"></span>
<translate>Sign Certificate</translate>
</button>
</div>
</div>

View File

@ -0,0 +1,66 @@
/**
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
(function() {
'use strict';
angular
.module('horizon.dashboard.container-infra.clusters')
.factory('horizon.dashboard.container-infra.clusters.sign-certificate-model', CertificateModel);
CertificateModel.$inject = [
'horizon.app.core.openstack-service-api.magnum'
];
function CertificateModel(magnum) {
var model = {
newClusterSpec: {},
cluster_name: "",
csrfile: null,
// API methods
init: init,
signCertificate: signCertificate
};
function init(cluster_id) {
// Reset the new Certificate spec
model.newCertificateSpec = {
cluster_uuid: cluster_id,
csr: ""
};
model.cluster_name = "";
model.csrfile = null;
}
function signCertificate() {
var finalSpec = angular.copy(model.newCertificateSpec);
cleanNullProperties(finalSpec);
return magnum.signCertificate(finalSpec);
}
function cleanNullProperties(finalSpec) {
// Initially clean fields that don't have any value.
for (var key in finalSpec) {
if (finalSpec.hasOwnProperty(key) && finalSpec[key] === null) {
delete finalSpec[key];
}
}
}
return model;
}
})();

View File

@ -0,0 +1,58 @@
/**
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
(function() {
'use strict';
angular
.module('horizon.dashboard.container-infra.clusters')
.controller('horizon.dashboard.container-infra.clusters.sign-certificate-modal', SignCertificateModal);
SignCertificateModal.$inject = [
'$modal',
'horizon.app.core.workflow.factory',
'horizon.framework.util.i18n.gettext',
'horizon.framework.widgets.modal-wait-spinner.service',
'horizon.framework.widgets.toast.service',
'horizon.dashboard.container-infra.basePath'
];
function SignCertificateModal(modal, gettext, spinner, toast, basePath) {
var ctrl = this;
ctrl.model = {
cluster: model.cluster_id,
view_file: null, // file object managed by angular form ngModel
upload_file: null, // file object from the DOM element with the actual upload
DELIMETER: model.DELIMETER
};
ctrl.form = null; // set by the HTML
ctrl.changeFile = changeFile;
///////////
function changeFile(files) {
if (files.length) {
// update the upload file & its name
ctrl.model.upload_file = files[0];
ctrl.model.name = files[0].name;
ctrl.form.name.$setDirty();
// Note that a $scope.$digest() is now needed for the change to the ngModel to be
// reflected in the page (since this callback is fired from inside a DOM event)
// but the on-file-changed directive currently does a digest after this callback
// is invoked.
}
} }
})();

View File

@ -0,0 +1,93 @@
/**
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
(function() {
'use strict';
/**
* @ngdoc overview
* @name horizon.dashboard.container-infra.clusters.sign-certificate.service
* @description Service for the container-infra cluster sign certificate modal
*/
angular
.module('horizon.dashboard.container-infra.clusters')
.factory('horizon.dashboard.container-infra.clusters.sign-certificate.service', signCertificateService);
signCertificateService.$inject = [
'$modal',
'horizon.app.core.openstack-service-api.magnum',
'horizon.framework.util.actions.action-result.service',
'horizon.framework.util.i18n.gettext',
'horizon.framework.util.q.extensions',
'horizon.framework.widgets.toast.service',
'horizon.dashboard.container-infra.clusters.basePath',
'horizon.dashboard.container-infra.clusters.resourceType',
'horizon.dashboard.container-infra.clusters.sign-certificate-model'
];
function signCertificateService(
$modal, magnum, actionResult, gettext, $qExtensions, toast, basePath, resourceType, model
) {
var message = {
success: gettext('Certificate %s was successfully signed.')
};
var service = {
initScope: initScope,
perform: perform,
allowed: allowed
};
return service;
//////////////
function initScope($scope) {
}
function signCertificateModal(html, $modal) {
var localSpec = {
backdrop: 'static',
controller: 'horizon.dashboard.container-infra.clusters.signCertificateController as ctrl',
templateUrl: html
};
return $modal.open(localSpec).result;
}
function perform(selected) {
model.init(selected.id);
return signCertificateModal(basePath + 'sign-certificate/sign-certificate-modal.html', $modal)
.then(submit);
}
function allowed() {
return $qExtensions.booleanAsPromise(true);
}
function submit(){
return model.signCertificate().then(success);
}
function success(response) {
magnum.downloadTextAsFile(response.data.pem, model.cluster_name + "_cert.pem");
response.data.id = response.data.uuid;
toast.add('success', interpolate(message.success, [response.data.id]));
var result = actionResult.getActionResult()
.created(resourceType, response.data.id);
return result.result;
}
}
})();