[pve-devel] [PATCH manager v2 3/3] add node/Certificates.js and use it
Dominik Csapak
d.csapak at proxmox.com
Fri May 4 11:53:35 CEST 2018
this adds the grid for showing the custom/builtin Certificates
and the means to upload and delete custom ones
Signed-off-by: Dominik Csapak <d.csapak at proxmox.com>
---
www/manager6/Makefile | 1 +
www/manager6/node/Certificates.js | 379 ++++++++++++++++++++++++++++++++++++++
www/manager6/node/Config.js | 8 +
3 files changed, 388 insertions(+)
create mode 100644 www/manager6/node/Certificates.js
diff --git a/www/manager6/Makefile b/www/manager6/Makefile
index c29824bf..81ddcc8d 100644
--- a/www/manager6/Makefile
+++ b/www/manager6/Makefile
@@ -97,6 +97,7 @@ JSSRC= \
node/StatusView.js \
node/Summary.js \
node/Subscription.js \
+ node/Certificates.js \
node/ACME.js \
node/Config.js \
window/Migrate.js \
diff --git a/www/manager6/node/Certificates.js b/www/manager6/node/Certificates.js
new file mode 100644
index 00000000..2bce927b
--- /dev/null
+++ b/www/manager6/node/Certificates.js
@@ -0,0 +1,379 @@
+Ext.define('PVE.node.CertificateView', {
+ extend: 'Ext.container.Container',
+ xtype: 'pveCertificatesView',
+
+ mixins: ['Proxmox.Mixin.CBind' ],
+
+ items: [
+ {
+ xtype: 'pveCertView',
+ border: 0,
+ cbind: {
+ nodename: '{nodename}'
+ }
+ },
+ {
+ xtype: 'pveACMEView',
+ border: 0,
+ cbind: {
+ nodename: '{nodename}'
+ }
+ }
+ ]
+
+});
+
+Ext.define('PVE.node.CertificateViewer', {
+ extend: 'Proxmox.window.Edit',
+
+ title: gettext('Certificate'),
+
+ fieldDefaults: {
+ labelWidth: 120
+ },
+ width: 800,
+ resizable: true,
+
+ items: [
+ {
+ xtype: 'displayfield',
+ fieldLabel: gettext('Name'),
+ name: 'filename'
+ },
+ {
+ xtype: 'displayfield',
+ fieldLabel: gettext('Fingerprint'),
+ name: 'fingerprint'
+ },
+ {
+ xtype: 'displayfield',
+ fieldLabel: gettext('Issuer'),
+ name: 'issuer'
+ },
+ {
+ xtype: 'displayfield',
+ fieldLabel: gettext('Subject'),
+ name: 'subject'
+ },
+ {
+ xtype: 'displayfield',
+ fieldLabel: gettext('Valid Since'),
+ renderer: Proxmox.Utils.render_timestamp,
+ name: 'notbefore'
+ },
+ {
+ xtype: 'displayfield',
+ fieldLabel: gettext('Expires'),
+ renderer: Proxmox.Utils.render_timestamp,
+ name: 'notafter'
+ },
+ {
+ xtype: 'displayfield',
+ fieldLabel: gettext('Subject Alternative Names'),
+ name: 'san',
+ renderer: PVE.Utils.render_san
+ },
+ {
+ xtype: 'textarea',
+ editable: false,
+ grow: true,
+ growMax: 200,
+ fieldLabel: gettext('Certificate'),
+ name: 'pem'
+ }
+ ],
+
+ initComponent: function() {
+ var me = this;
+
+ if (!me.cert) {
+ throw "no cert given";
+ }
+
+ if (!me.nodename) {
+ throw "no nodename given";
+ }
+
+ me.url = '/nodes/' + me.nodename + '/certificates/info';
+ me.callParent();
+
+ // hide OK/Reset button, because we just want to show data
+ me.down('toolbar[dock=bottom]').setVisible(false);
+
+ me.load({
+ success: function(response) {
+ if (Ext.isArray(response.result.data)) {
+ Ext.Array.each(response.result.data, function(item) {
+ if (item.filename === me.cert) {
+ me.setValues(item);
+ return false;
+ }
+ });
+ }
+ }
+ });
+ }
+});
+
+Ext.define('PVE.node.CertUpload', {
+ extend: 'Proxmox.window.Edit',
+ xtype: 'pveCertUpload',
+
+ title: gettext('Upload Custom Certificate'),
+ resizable: false,
+ isCreate: true,
+ submitText: gettext('Upload'),
+ method: 'POST',
+ width: 600,
+
+ apiCallDone: function(success, response, options) {
+ if (!success) {
+ return;
+ }
+
+ var txt = gettext('pveproxy will be restarted with new certificates, please reload the GUI!');
+ Ext.getBody().mask(txt, ['pve-static-mask']);
+ // reload after 10 seconds automatically
+ Ext.defer(function() {
+ window.location.reload(true);
+ }, 10000);
+ },
+
+ items: [
+ {
+ fieldLabel: gettext('Private Key (Optional)'),
+ labelAlign: 'top',
+ emptyText: gettext('No change'),
+ name: 'key',
+ xtype: 'textarea'
+ },
+ {
+ xtype: 'filebutton',
+ text: gettext('From File'),
+ listeners: {
+ change: function(btn, e, value) {
+ var me = this.up('form');
+ e = e.event;
+ Ext.Array.each(e.target.files, function(file) {
+ PVE.Utils.loadSSHKeyFromFile(file, function(res) {
+ me.down('field[name=key]').setValue(res);
+ });
+ });
+ btn.reset();
+ }
+ }
+ },
+ {
+ xtype: 'box',
+ autoEl: 'hr'
+ },
+ {
+ fieldLabel: gettext('Certificate Chain'),
+ labelAlign: 'top',
+ allowBlank: false,
+ name: 'certificates',
+ xtype: 'textarea'
+ },
+ {
+ xtype: 'filebutton',
+ text: gettext('From File'),
+ listeners: {
+ change: function(btn, e, value) {
+ var me = this.up('form');
+ e = e.event;
+ Ext.Array.each(e.target.files, function(file) {
+ PVE.Utils.loadSSHKeyFromFile(file, function(res) {
+ me.down('field[name=certificates]').setValue(res);
+ });
+ });
+ btn.reset();
+ }
+ }
+ },
+ {
+ xtype: 'hidden',
+ name: 'restart',
+ value: '1'
+ },
+ {
+ xtype: 'hidden',
+ name: 'force',
+ value: '1'
+ }
+ ],
+
+ initComponent: function() {
+ var me = this;
+
+ if (!me.nodename) {
+ throw "no nodename given";
+ }
+
+ me.url = '/nodes/' + me.nodename + '/certificates/custom';
+
+ me.callParent();
+ }
+});
+
+Ext.define('pve-certificate', {
+ extend: 'Ext.data.Model',
+
+ fields: [ 'filename', 'fingerprint', 'issuer', 'notafter', 'notbefore', 'subject', 'san' ],
+ idProperty: 'filename'
+});
+
+Ext.define('PVE.node.Certificates', {
+ extend: 'Ext.grid.Panel',
+ xtype: 'pveCertView',
+
+ tbar: [
+ {
+ xtype: 'button',
+ text: gettext('Upload Custom Certificate'),
+ handler: function() {
+ var me = this.up('grid');
+ var win = Ext.create('PVE.node.CertUpload', {
+ nodename: me.nodename
+ });
+ win.show();
+ win.on('destroy', me.reload, me);
+ }
+ },
+ {
+ xtype: 'button',
+ itemId: 'deletebtn',
+ text: gettext('Delete Custom Certificate'),
+ handler: function() {
+ var me = this.up('grid');
+ Proxmox.Utils.API2Request({
+ url: '/nodes/' + me.nodename + '/certificates/custom?restart=1',
+ method: 'DELETE',
+ success: function(response, opt) {
+ var txt = gettext('pveproxy will be restarted with new certificates, please reload the GUI!');
+ Ext.getBody().mask(txt, ['pve-static-mask']);
+ // reload after 10 seconds automatically
+ Ext.defer(function() {
+ window.location.reload(true);
+ }, 10000);
+ },
+ failure: function(response, opt) {
+ Ext.Msg.alert(gettext('Error'), response.htmlStatus);
+ }
+ });
+ }
+ },
+ '-',
+ {
+ xtype: 'proxmoxButton',
+ itemId: 'viewbtn',
+ disabled: true,
+ text: gettext('View Certificate'),
+ handler: function() {
+ var me = this.up('grid');
+ me.view_certificate();
+ }
+ }
+ ],
+
+ columns: [
+ {
+ header: gettext('File'),
+ width: 150,
+ dataIndex: 'filename'
+ },
+ {
+ header: gettext('Issuer'),
+ flex: 1,
+ dataIndex: 'issuer'
+ },
+ {
+ header: gettext('Subject'),
+ flex: 1,
+ dataIndex: 'subject'
+ },
+ {
+ header: gettext('Valid Since'),
+ width: 150,
+ dataIndex: 'notbefore',
+ renderer: Proxmox.Utils.render_timestamp
+ },
+ {
+ header: gettext('Expires'),
+ width: 150,
+ dataIndex: 'notafter',
+ renderer: Proxmox.Utils.render_timestamp
+ },
+ {
+ header: gettext('Subject Alternative Names'),
+ flex: 1,
+ dataIndex: 'san',
+ renderer: PVE.Utils.render_san
+ },
+ {
+ header: gettext('Fingerprint'),
+ dataIndex: 'fingerprint',
+ hidden: true
+ },
+ {
+ header: gettext('PEM'),
+ dataIndex: 'pem',
+ hidden: true
+ }
+ ],
+
+ reload: function() {
+ var me = this;
+ me.rstore.load();
+ },
+
+ set_button_status: function() {
+ var me = this;
+ var rec = me.rstore.getById('pveproxy-ssl.pem');
+
+ me.down('#deletebtn').setDisabled(!rec);
+ },
+
+ view_certificate: function() {
+ var me = this;
+ var selection = me.getSelection();
+ if (!selection || selection.length < 1) {
+ return;
+ }
+ var win = Ext.create('PVE.node.CertificateViewer', {
+ cert: selection[0].data.filename,
+ nodename : me.nodename
+ });
+ win.show();
+ },
+
+ listeners: {
+ itemdblclick: 'view_certificate'
+ },
+
+ initComponent: function() {
+ var me = this;
+
+ if (!me.nodename) {
+ throw "no nodename given";
+ }
+
+ me.rstore = Ext.create('Proxmox.data.UpdateStore', {
+ storeid: 'certs-' + me.nodename,
+ model: 'pve-certificate',
+ proxy: {
+ type: 'proxmox',
+ url: '/api2/json/nodes/' + me.nodename + '/certificates/info'
+ }
+ });
+
+ me.store = {
+ type: 'diff',
+ rstore: me.rstore
+ };
+
+ me.callParent();
+
+ me.mon(me.rstore, 'load', me.set_button_status, me);
+ me.rstore.startUpdate();
+ }
+});
diff --git a/www/manager6/node/Config.js b/www/manager6/node/Config.js
index bd7784c9..9e9f49c5 100644
--- a/www/manager6/node/Config.js
+++ b/www/manager6/node/Config.js
@@ -169,6 +169,14 @@ Ext.define('PVE.node.Config', {
xtype: 'proxmoxNodeNetworkView'
},
{
+ title: gettext('Certificates'),
+ iconCls: 'fa fa-certificate',
+ itemId: 'certificates',
+ groups: ['services'],
+ nodename: nodename,
+ xtype: 'pveCertificatesView'
+ },
+ {
title: gettext('DNS'),
iconCls: 'fa fa-globe',
groups: ['services'],
--
2.11.0
More information about the pve-devel
mailing list