lxc: wizard: ssh key

This commit is contained in:
Wolfgang Bumiller 2016-08-10 12:13:19 +02:00 committed by Fabian Grünbichler
parent 6acb632a54
commit b1339314b6
2 changed files with 154 additions and 39 deletions

View File

@ -493,5 +493,35 @@ Ext.define('PVE.Parser', { statics: {
}
return cpustr + optstr;
},
parseSSHKey: function(key) {
// |--- options can have quotes--| type key comment
var keyre = /^(?:((?:[^\s"]|\"(?:\\.|[^"\\])*")+)\s+)?(\S+)\s+(\S+)(?:\s+(.*))?$/;
var typere = /^(?:ssh-(?:dss|rsa|ed25519)|ecdsa-sha2-nistp\d+)$/;
var m = key.match(keyre);
if (!m) {
return null;
}
if (m.length < 3 || !m[2]) { // [2] is always either type or key
return null;
}
if (m[1] && m[1].match(typere)) {
return {
type: m[1],
key: m[2],
comment: m[3]
};
}
if (m[2].match(typere)) {
return {
options: m[1],
type: m[2],
key: m[3],
comment: m[4]
};
}
return null;
}
}});

View File

@ -2,6 +2,23 @@
Ext.define('PVE.lxc.CreateWizard', {
extend: 'PVE.window.Wizard',
loadSSHKeyFromFile: function(file) {
var me = this;
// ssh-keygen produces 740 bytes for an average 4096 bit rsa key, with
// a user@host comment, 1420 for 8192 bits; current max is 16kbit
// assume: 740*8 for max. 32kbit (5920 byte file)
// round upwards to nearest nice number => 8192 bytes, leaves lots of comment space
if (file.size > 8192) {
Ext.Msg.alert(gettext('Error'), gettext("Invalid file size: ") + file.size);
return;
}
var reader = new FileReader();
reader.onload = function(evt) {
me.sshkeyfield.setValue(evt.target.result);
};
reader.readAsText(file);
},
initComponent: function() {
var me = this;
@ -50,6 +67,106 @@ Ext.define('PVE.lxc.CreateWizard', {
create: true
});
var passwordfield = Ext.createWidget('textfield', {
inputType: 'password',
name: 'password',
value: '',
fieldLabel: gettext('Password'),
allowBlank: false,
minLength: 5,
change: function(f, value) {
if (!me.rendered) {
return;
}
me.down('field[name=confirmpw]').validate();
}
});
me.sshkeyfield = Ext.createWidget('textfield', {
xtype: 'textfield',
name: 'ssh-public-keys',
value: '',
fieldLabel: gettext('SSH public key'),
allowBlank: true,
validator: function(value) {
if (value.length) {
var key = PVE.Parser.parseSSHKey(value);
if (!key) {
return "Failed to recognize ssh key";
}
me.down('field[name=password]').allowBlank = true;
} else {
me.down('field[name=password]').allowBlank = false;
}
me.down('field[name=password]').validate();
return true;
},
afterRender: function() {
if (!window.FileReader) {
// No FileReader support in this browser
return;
}
var cancel = function(ev) {
ev = ev.event;
if (ev.preventDefault) {
ev.preventDefault();
}
};
me.sshkeyfield.inputEl.on('dragover', cancel);
me.sshkeyfield.inputEl.on('dragenter', cancel);
me.sshkeyfield.inputEl.on('drop', function(ev) {
ev = ev.event;
if (ev.preventDefault) {
ev.preventDefault();
}
var files = ev.dataTransfer.files;
me.loadSSHKeyFromFile(files[0]);
});
},
});
var column2 = [
{
xtype: 'pvePoolSelector',
fieldLabel: gettext('Resource Pool'),
name: 'pool',
value: '',
allowBlank: true
},
passwordfield,
{
xtype: 'textfield',
inputType: 'password',
name: 'confirmpw',
value: '',
fieldLabel: gettext('Confirm password'),
allowBlank: true,
validator: function(value) {
var pw = me.down('field[name=password]').getValue();
if (pw !== value) {
return "Passwords does not match!";
}
return true;
}
},
me.sshkeyfield
];
if (window.FileReader) {
column2.push({
xtype: 'filebutton',
name: 'file',
text: gettext('Load SSH Key File'),
listeners: {
change: function(btn, e, value) {
e = e.event;
me.loadSSHKeyFromFile(e.target.files[0]);
btn.reset();
}
}
});
}
Ext.applyIf(me, {
subject: gettext('LXC Container'),
items: [
@ -90,45 +207,7 @@ Ext.define('PVE.lxc.CreateWizard', {
allowBlank: true
}
],
column2: [
{
xtype: 'pvePoolSelector',
fieldLabel: gettext('Resource Pool'),
name: 'pool',
value: '',
allowBlank: true
},
{
xtype: 'textfield',
inputType: 'password',
name: 'password',
value: '',
fieldLabel: gettext('Password'),
allowBlank: false,
minLength: 5,
change: function(f, value) {
if (!me.rendered) {
return;
}
me.down('field[name=confirmpw]').validate();
}
},
{
xtype: 'textfield',
inputType: 'password',
name: 'confirmpw',
value: '',
fieldLabel: gettext('Confirm password'),
allowBlank: false,
validator: function(value) {
var pw = me.down('field[name=password]').getValue();
if (pw !== value) {
return "Passwords does not match!";
}
return true;
}
}
],
column2: column2,
onGetValues: function(values) {
delete values.confirmpw;
if (!values.pool) {
@ -204,6 +283,12 @@ Ext.define('PVE.lxc.CreateWizard', {
delete kv.nodename;
delete kv.tmplstorage;
if (!kv['ssh-public-keys'].length) {
delete kv['ssh-public-keys'];
} else if (!kv['password'].length) {
delete kv['password'];
}
PVE.Utils.API2Request({
url: '/nodes/' + nodename + '/lxc',
waitMsgTarget: me,