Add sign certificate action to cluster panel
This patch adds sign certificate action as item action to cluster table view and details view. Change-Id: I51636c377ecc105f5b290f7fb4e5c463cdc7d950 Implements: blueprint cluster-certificates
This commit is contained in:
parent
f07baab8e0
commit
c8d9a128a1
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
})();
|
@ -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>
|
@ -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;
|
||||
}
|
||||
})();
|
@ -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.
|
||||
}
|
||||
} }
|
||||
})();
|
@ -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;
|
||||
}
|
||||
}
|
||||
})();
|
Loading…
Reference in New Issue
Block a user