]> git.proxmox.com Git - pve-manager.git/blame - www/manager6/node/ACME.js
ui: fix align mode of two column container
[pve-manager.git] / www / manager6 / node / ACME.js
CommitLineData
488be4c2
DC
1Ext.define('PVE.node.ACMEAccountCreate', {
2 extend: 'Proxmox.window.Edit',
fc40915c 3 mixins: ['Proxmox.Mixin.CBind'],
488be4c2 4
04a8058e 5 width: 450,
488be4c2
DC
6 title: gettext('Register Account'),
7 isCreate: true,
8 method: 'POST',
9 submitText: gettext('Register'),
10 url: '/cluster/acme/account',
11 showTaskViewer: true,
fc40915c 12 defaultExists: false,
fdc4c229
FG
13 referenceHolder: true,
14 onlineHelp: "sysadmin_certs_acme_account",
15
16 viewModel: {
17 data: {
18 customDirectory: false,
c18a2db2
FG
19 eabRequired: false,
20 },
21 formulas: {
22 eabEmptyText: function(get) {
23 return get('eabRequired') ? gettext("required") : gettext("optional");
24 },
fdc4c229
FG
25 },
26 },
488be4c2
DC
27
28 items: [
c0afd5cc
DC
29 {
30 xtype: 'proxmoxtextfield',
e023535e 31 fieldLabel: gettext('Account Name'),
c0afd5cc 32 name: 'name',
fc40915c
DC
33 cbind: {
34 emptyText: (get) => get('defaultExists') ? '' : 'default',
35 allowBlank: (get) => !get('defaultExists'),
36 },
c0afd5cc 37 },
04a8058e
DC
38 {
39 xtype: 'textfield',
40 name: 'contact',
41 vtype: 'email',
42 allowBlank: false,
f6710aac 43 fieldLabel: gettext('E-Mail'),
04a8058e 44 },
488be4c2
DC
45 {
46 xtype: 'proxmoxComboGrid',
fdc4c229
FG
47 notFoundIsValid: true,
48 isFormField: false,
488be4c2
DC
49 allowBlank: false,
50 valueField: 'url',
51 displayField: 'name',
52 fieldLabel: gettext('ACME Directory'),
53 store: {
fdc4c229
FG
54 listeners: {
55 'load': function() {
56 this.add({ name: gettext("Custom"), url: '' });
57 },
58 },
488be4c2
DC
59 autoLoad: true,
60 fields: ['name', 'url'],
61 idProperty: ['name'],
62 proxy: {
63 type: 'proxmox',
f6710aac 64 url: '/api2/json/cluster/acme/directories',
488be4c2 65 },
488be4c2
DC
66 },
67 listConfig: {
68 columns: [
69 {
70 header: gettext('Name'),
71 dataIndex: 'name',
f6710aac 72 flex: 1,
488be4c2
DC
73 },
74 {
75 header: gettext('URL'),
76 dataIndex: 'url',
f6710aac
TL
77 flex: 1,
78 },
79 ],
488be4c2
DC
80 },
81 listeners: {
82 change: function(combogrid, value) {
fdc4c229 83 let me = this;
488be4c2 84
fdc4c229
FG
85 let vm = me.up('window').getViewModel();
86 let dirField = me.up('window').lookupReference('directoryInput');
87 let tosButton = me.up('window').lookupReference('queryTos');
488be4c2 88
fdc4c229
FG
89 let isCustom = combogrid.getSelection().get('name') === gettext("Custom");
90 vm.set('customDirectory', isCustom);
488be4c2 91
fdc4c229
FG
92 dirField.setValue(value);
93
94 if (!isCustom) {
95 tosButton.click();
96 } else {
97 me.up('window').clearToSFields();
98 }
99 },
100 },
101 },
102 {
103 xtype: 'fieldcontainer',
104 layout: 'hbox',
105 fieldLabel: gettext('URL'),
106 bind: {
107 hidden: '{!customDirectory}',
108 },
109 items: [
110 {
111 xtype: 'proxmoxtextfield',
112 name: 'directory',
113 reference: 'directoryInput',
114 flex: 1,
115 allowBlank: false,
116 listeners: {
117 change: function(textbox, value) {
118 let me = this;
119 me.up('window').clearToSFields();
488be4c2 120 },
fdc4c229
FG
121 },
122 },
123 {
124 xtype: 'proxmoxButton',
125 margin: '0 0 0 5',
126 reference: 'queryTos',
127 text: gettext('Query URL'),
128 listeners: {
129 click: function(button) {
130 let me = this;
131
132 let w = me.up('window');
c18a2db2 133 let vm = w.getViewModel();
fdc4c229
FG
134 let disp = w.down('#tos_url_display');
135 let field = w.down('#tos_url');
136 let checkbox = w.down('#tos_checkbox');
137 let value = w.lookupReference('directoryInput').getValue();
138 w.clearToSFields();
139
140 if (!value) {
141 return;
7fb70c3b 142 } else {
fdc4c229 143 disp.setValue(gettext("Loading"));
7fb70c3b 144 }
fdc4c229
FG
145
146 Proxmox.Utils.API2Request({
147 url: '/cluster/acme/meta',
148 method: 'GET',
149 params: {
150 directory: value,
151 },
152 success: function(response, opt) {
b3779821 153 if (response.result.data && response.result.data.termsOfService) {
fdc4c229
FG
154 field.setValue(response.result.data.termsOfService);
155 disp.setValue(response.result.data.termsOfService);
156 checkbox.setHidden(false);
157 } else {
b3779821
FG
158 // Needed to pass input verification and enable register button
159 // has no influence on the submitted form
160 checkbox.setValue(true);
fdc4c229
FG
161 disp.setValue("No terms of service agreement required");
162 }
b3779821
FG
163 vm.set('eabRequired', !!(response.result.data &&
164 response.result.data.externalAccountRequired));
fdc4c229
FG
165 },
166 failure: function(response, opt) {
167 disp.setValue(undefined);
168 Ext.Msg.alert(gettext('Error'), response.htmlStatus);
169 },
170 });
488be4c2 171 },
fdc4c229 172 },
f6710aac 173 },
fdc4c229 174 ],
488be4c2
DC
175 },
176 {
177 xtype: 'displayfield',
178 itemId: 'tos_url_display',
488be4c2 179 renderer: PVE.Utils.render_optional_url,
f6710aac 180 name: 'tos_url_display',
488be4c2
DC
181 },
182 {
183 xtype: 'hidden',
184 itemId: 'tos_url',
f6710aac 185 name: 'tos_url',
488be4c2
DC
186 },
187 {
188 xtype: 'proxmoxcheckbox',
189 itemId: 'tos_checkbox',
04a8058e 190 boxLabel: gettext('Accept TOS'),
488be4c2
DC
191 submitValue: false,
192 validateValue: function(value) {
193 if (value && this.checked) {
194 return true;
195 }
196 return false;
f6710aac 197 },
488be4c2 198 },
c18a2db2
FG
199 {
200 xtype: 'proxmoxtextfield',
201 name: 'eab-kid',
202 fieldLabel: gettext('EAB Key ID'),
203 bind: {
204 hidden: '{!customDirectory}',
205 allowBlank: '{!eabRequired}',
206 emptyText: '{eabEmptyText}',
207 },
208 },
209 {
210 xtype: 'proxmoxtextfield',
211 name: 'eab-hmac-key',
212 fieldLabel: gettext('EAB Key'),
213 bind: {
214 hidden: '{!customDirectory}',
215 allowBlank: '{!eabRequired}',
216 emptyText: '{eabEmptyText}',
217 },
218 },
f6710aac 219 ],
488be4c2 220
fdc4c229
FG
221 clearToSFields: function() {
222 let me = this;
223
224 let disp = me.down('#tos_url_display');
225 let field = me.down('#tos_url');
226 let checkbox = me.down('#tos_checkbox');
227
228 disp.setValue("Terms of service not fetched yet");
229 field.setValue(undefined);
230 checkbox.setValue(undefined);
231 checkbox.setHidden(true);
232 },
233
488be4c2
DC
234});
235
236Ext.define('PVE.node.ACMEAccountView', {
237 extend: 'Proxmox.window.Edit',
238
239 width: 600,
240 fieldDefaults: {
f6710aac 241 labelWidth: 140,
488be4c2
DC
242 },
243
244 title: gettext('Account'),
245
246 items: [
247 {
248 xtype: 'displayfield',
249 fieldLabel: gettext('E-Mail'),
f6710aac 250 name: 'email',
488be4c2
DC
251 },
252 {
253 xtype: 'displayfield',
254 fieldLabel: gettext('Created'),
f6710aac 255 name: 'createdAt',
488be4c2
DC
256 },
257 {
258 xtype: 'displayfield',
259 fieldLabel: gettext('Status'),
f6710aac 260 name: 'status',
488be4c2
DC
261 },
262 {
263 xtype: 'displayfield',
264 fieldLabel: gettext('Directory'),
265 renderer: PVE.Utils.render_optional_url,
f6710aac 266 name: 'directory',
488be4c2
DC
267 },
268 {
269 xtype: 'displayfield',
270 fieldLabel: gettext('Terms of Services'),
271 renderer: PVE.Utils.render_optional_url,
f6710aac
TL
272 name: 'tos',
273 },
488be4c2
DC
274 ],
275
276 initComponent: function() {
277 var me = this;
278
279 if (!me.accountname) {
280 throw "no account name defined";
281 }
282
283 me.url = '/cluster/acme/account/' + me.accountname;
284
285 me.callParent();
286
287 // hide OK/Reset button, because we just want to show data
288 me.down('toolbar[dock=bottom]').setVisible(false);
289
290 me.load({
291 success: function(response) {
292 var data = response.result.data;
293 data.email = data.account.contact[0];
294 data.createdAt = data.account.createdAt;
295 data.status = data.account.status;
296 me.setValues(data);
f6710aac 297 },
488be4c2 298 });
f6710aac 299 },
488be4c2
DC
300});
301
8e49a93f
DC
302Ext.define('PVE.node.ACMEDomainEdit', {
303 extend: 'Proxmox.window.Edit',
304 alias: 'widget.pveACMEDomainEdit',
305
306 subject: gettext('Domain'),
307 isCreate: false,
3c6b4c80 308 width: 450,
eff602d8 309 onlineHelp: 'sysadmin_certificate_management',
8e49a93f
DC
310
311 items: [
312 {
313 xtype: 'inputpanel',
314 onGetValues: function(values) {
315 let me = this;
316 let win = me.up('pveACMEDomainEdit');
317 let nodeconfig = win.nodeconfig;
318 let olddomain = win.domain || {};
319
320 let params = {
321 digest: nodeconfig.digest,
322 };
323
324 let configkey = olddomain.configkey;
6ac64c3a 325 let acmeObj = PVE.Parser.parseACME(nodeconfig.acme);
8e49a93f
DC
326
327 if (values.type === 'dns') {
328 if (!olddomain.configkey || olddomain.configkey === 'acme') {
329 // look for first free slot
330 for (let i = 0; i < PVE.Utils.acmedomain_count; i++) {
331 if (nodeconfig[`acmedomain${i}`] === undefined) {
332 configkey = `acmedomain${i}`;
333 break;
334 }
335 }
336 if (olddomain.domain) {
337 // we have to remove the domain from the acme domainlist
338 PVE.Utils.remove_domain_from_acme(acmeObj, olddomain.domain);
339 params.acme = PVE.Parser.printACME(acmeObj);
340 }
341 }
342
343 delete values.type;
344 params[configkey] = PVE.Parser.printPropertyString(values, 'domain');
345 } else {
346 if (olddomain.configkey && olddomain.configkey !== 'acme') {
347 // delete the old dns entry
348 params.delete = [olddomain.configkey];
349 }
350
351 // add new, remove old and make entries unique
352 PVE.Utils.add_domain_to_acme(acmeObj, values.domain);
353 PVE.Utils.remove_domain_from_acme(acmeObj, olddomain.domain);
354 params.acme = PVE.Parser.printACME(acmeObj);
355 }
356
357 return params;
358 },
359 items: [
360 {
361 xtype: 'proxmoxKVComboBox',
362 name: 'type',
3c6b4c80 363 fieldLabel: gettext('Challenge Type'),
8e49a93f 364 allowBlank: false,
3c6b4c80 365 value: 'standalone',
8e49a93f 366 comboItems: [
9c164224 367 ['standalone', 'HTTP'],
8e49a93f
DC
368 ['dns', 'DNS'],
369 ],
370 validator: function(value) {
371 let me = this;
372 let win = me.up('pveACMEDomainEdit');
373 let oldconfigkey = win.domain ? win.domain.configkey : undefined;
374 let val = me.getValue();
375 if (val === 'dns' && (!oldconfigkey || oldconfigkey === 'acme')) {
376 // we have to check if there is a 'acmedomain' slot left
377 let found = false;
378 for (let i = 0; i < PVE.Utils.acmedomain_count; i++) {
379 if (!win.nodeconfig[`acmedomain${i}`]) {
380 found = true;
381 }
382 }
383 if (!found) {
384 return gettext('Only 5 Domains with type DNS can be configured');
385 }
386 }
387
388 return true;
389 },
390 listeners: {
391 change: function(cb, value) {
392 let me = this;
393 let view = me.up('pveACMEDomainEdit');
a94b71fb
TL
394 let pluginField = view.down('field[name=plugin]');
395 pluginField.setDisabled(value !== 'dns');
396 pluginField.setHidden(value !== 'dns');
8e49a93f
DC
397 },
398 },
399 },
400 {
401 xtype: 'hidden',
402 name: 'alias',
403 },
8e49a93f
DC
404 {
405 xtype: 'pveACMEPluginSelector',
406 name: 'plugin',
407 disabled: true,
a94b71fb 408 hidden: true,
8e49a93f
DC
409 allowBlank: false,
410 },
a94b71fb
TL
411 {
412 xtype: 'proxmoxtextfield',
413 name: 'domain',
414 allowBlank: false,
415 vtype: 'DnsName',
416 value: '',
417 fieldLabel: gettext('Domain'),
418 },
8e49a93f
DC
419 ],
420 },
421 ],
422
423 initComponent: function() {
424 let me = this;
425
426 if (!me.nodename) {
427 throw 'no nodename given';
428 }
429
430 if (!me.nodeconfig) {
431 throw 'no nodeconfig given';
432 }
433
434 me.isCreate = !me.domain;
8b779b4a
TL
435 if (me.isCreate) {
436 me.domain = `${me.nodename}.`; // TODO: FQDN of node
437 }
8e49a93f
DC
438
439 me.url = `/api2/extjs/nodes/${me.nodename}/config`;
440
441 me.callParent();
442
443 if (!me.isCreate) {
444 me.setValues(me.domain);
8b779b4a
TL
445 } else {
446 me.setValues({ domain: me.domain });
8e49a93f
DC
447 }
448 },
449});
450
fd254233
DC
451Ext.define('pve-acme-domains', {
452 extend: 'Ext.data.Model',
453 fields: ['domain', 'type', 'alias', 'plugin', 'configkey'],
454 idProperty: 'domain',
455});
456
488be4c2 457Ext.define('PVE.node.ACME', {
fd254233
DC
458 extend: 'Ext.grid.Panel',
459 alias: 'widget.pveACMEView',
488be4c2
DC
460
461 margin: '10 0 0 0',
462 title: 'ACME',
463
e666f688
DC
464 emptyText: gettext('No Domains configured'),
465
fd254233
DC
466 viewModel: {
467 data: {
1580b605 468 domaincount: 0,
3071cc5b
DC
469 account: undefined, // the account we display
470 configaccount: undefined, // the account set in the config
fd254233 471 accountEditable: false,
a8b6a80a 472 accountsAvailable: false,
fd254233
DC
473 },
474
475 formulas: {
1580b605 476 canOrder: (get) => !!get('account') && get('domaincount') > 0,
80bd3209 477 editBtnIcon: (get) => 'fa black fa-' + (get('accountEditable') ? 'check' : 'pencil'),
8fc2d938 478 editBtnText: (get) => get('accountEditable') ? gettext('Apply') : gettext('Edit'),
a8b6a80a
TL
479 accountTextHidden: (get) => get('accountEditable') || !get('accountsAvailable'),
480 accountValueHidden: (get) => !get('accountEditable') || !get('accountsAvailable'),
fd254233
DC
481 },
482 },
483
484 controller: {
485 xclass: 'Ext.app.ViewController',
486
a8b6a80a 487 init: function(view) {
a8b6a80a
TL
488 let accountSelector = this.lookup('accountselector');
489 accountSelector.store.on('load', this.onAccountsLoad, this);
490 },
491
492 onAccountsLoad: function(store, records, success) {
80bd3209
DC
493 let me = this;
494 let vm = me.getViewModel();
3071cc5b 495 let configaccount = vm.get('configaccount');
a8b6a80a 496 vm.set('accountsAvailable', records.length > 0);
80bd3209
DC
497 if (me.autoChangeAccount && records.length > 0) {
498 me.changeAccount(records[0].data.name, () => {
31c9edc8 499 vm.set('accountEditable', false);
80bd3209 500 me.reload();
31c9edc8
TL
501 });
502 me.autoChangeAccount = false;
3071cc5b
DC
503 } else if (configaccount) {
504 if (store.findExact('name', configaccount) !== -1) {
505 vm.set('account', configaccount);
506 } else {
507 vm.set('account', null);
508 }
31c9edc8 509 }
a8b6a80a
TL
510 },
511
fd254233
DC
512 addDomain: function() {
513 let me = this;
514 let view = me.getView();
515
516 Ext.create('PVE.node.ACMEDomainEdit', {
517 nodename: view.nodename,
518 nodeconfig: view.nodeconfig,
519 apiCallDone: function() {
520 me.reload();
521 },
522 }).show();
523 },
524
525 editDomain: function() {
526 let me = this;
527 let view = me.getView();
528
529 let selection = view.getSelection();
530 if (selection.length < 1) return;
531
532 Ext.create('PVE.node.ACMEDomainEdit', {
533 nodename: view.nodename,
534 nodeconfig: view.nodeconfig,
535 domain: selection[0].data,
536 apiCallDone: function() {
537 me.reload();
538 },
539 }).show();
540 },
541
542 removeDomain: function() {
543 let me = this;
544 let view = me.getView();
545 let selection = view.getSelection();
546 if (selection.length < 1) return;
547
548 let rec = selection[0].data;
549 let params = {};
550 if (rec.configkey !== 'acme') {
551 params.delete = rec.configkey;
552 } else {
553 let acme = PVE.Parser.parseACME(view.nodeconfig.acme);
554 PVE.Utils.remove_domain_from_acme(acme, rec.domain);
555 params.acme = PVE.Parser.printACME(acme);
556 }
557
558 Proxmox.Utils.API2Request({
559 method: 'PUT',
560 url: `/nodes/${view.nodename}/config`,
561 params,
562 success: function(response, opt) {
563 me.reload();
564 },
565 failure: function(response, opt) {
566 Ext.Msg.alert(gettext('Error'), response.htmlStatus);
567 },
568 });
569 },
570
571 toggleEditAccount: function() {
572 let me = this;
573 let vm = me.getViewModel();
574 let editable = vm.get('accountEditable');
575 if (editable) {
576 me.changeAccount(vm.get('account'), function() {
577 vm.set('accountEditable', false);
578 me.reload();
579 });
580 } else {
581 vm.set('accountEditable', true);
582 }
583 },
584
585 changeAccount: function(account, callback) {
586 let me = this;
587 let view = me.getView();
588 let params = {};
589
590 let acme = PVE.Parser.parseACME(view.nodeconfig.acme);
591 acme.account = account;
592 params.acme = PVE.Parser.printACME(acme);
593
594 Proxmox.Utils.API2Request({
595 method: 'PUT',
596 waitMsgTarget: view,
597 url: `/nodes/${view.nodename}/config`,
598 params,
599 success: function(response, opt) {
600 if (Ext.isFunction(callback)) {
601 callback();
602 }
603 },
604 failure: function(response, opt) {
605 Ext.Msg.alert(gettext('Error'), response.htmlStatus);
606 },
607 });
608 },
609
610 order: function() {
611 let me = this;
612 let view = me.getView();
613
614 Proxmox.Utils.API2Request({
615 method: 'POST',
616 params: {
617 force: 1,
618 },
619 url: `/nodes/${view.nodename}/certificates/acme/certificate`,
620 success: function(response, opt) {
621 Ext.create('Proxmox.window.TaskViewer', {
622 upid: response.result.data,
623 taskDone: function(success) {
624 me.orderFinished(success);
625 },
626 }).show();
627 },
628 failure: function(response, opt) {
629 Ext.Msg.alert(gettext('Error'), response.htmlStatus);
630 },
631 });
632 },
633
634 orderFinished: function(success) {
635 if (!success) return;
72cfb3d4
FS
636 // reload only if the Web UI is open on the same node that the cert was ordered for
637 if (this.getView().nodename !== Proxmox.NodeName) {
638 return;
639 }
fd254233
DC
640 var txt = gettext('pveproxy will be restarted with new certificates, please reload the GUI!');
641 Ext.getBody().mask(txt, ['pve-static-mask']);
642 // reload after 10 seconds automatically
643 Ext.defer(function() {
644 window.location.reload(true);
645 }, 10000);
646 },
647
648 reload: function() {
649 let me = this;
650 let view = me.getView();
651 view.rstore.load();
652 },
653
31c9edc8
TL
654 addAccount: function() {
655 let me = this;
656 Ext.create('PVE.node.ACMEAccountCreate', {
657 autoShow: true,
658 taskDone: function() {
659 me.reload();
660 let accountSelector = me.lookup('accountselector');
661 me.autoChangeAccount = true;
662 accountSelector.store.load();
663 },
664 });
fd254233
DC
665 },
666 },
667
488be4c2
DC
668 tbar: [
669 {
fd254233
DC
670 xtype: 'proxmoxButton',
671 text: gettext('Add'),
672 handler: 'addDomain',
673 selModel: false,
674 },
675 {
676 xtype: 'proxmoxButton',
677 text: gettext('Edit'),
678 disabled: true,
679 handler: 'editDomain',
680 },
681 {
682 xtype: 'proxmoxStdRemoveButton',
683 handler: 'removeDomain',
488be4c2 684 },
fd254233 685 '-',
488be4c2
DC
686 {
687 xtype: 'button',
fd254233 688 reference: 'order',
a8b6a80a 689 text: gettext('Order Certificates Now'),
31c9edc8 690 bind: {
1580b605 691 disabled: '{!canOrder}',
31c9edc8 692 },
fd254233
DC
693 handler: 'order',
694 },
695 '-',
696 {
697 xtype: 'displayfield',
a8b6a80a
TL
698 value: gettext('Using Account') + ':',
699 bind: {
700 hidden: '{!accountsAvailable}',
701 },
fd254233
DC
702 },
703 {
704 xtype: 'displayfield',
705 reference: 'accounttext',
3071cc5b 706 renderer: (val) => val || Proxmox.Utils.NoneText,
fd254233
DC
707 bind: {
708 value: '{account}',
a8b6a80a 709 hidden: '{accountTextHidden}',
fd254233
DC
710 },
711 },
712 {
713 xtype: 'pveACMEAccountSelector',
714 hidden: true,
715 reference: 'accountselector',
716 bind: {
717 value: '{account}',
a8b6a80a 718 hidden: '{accountValueHidden}',
fd254233 719 },
488be4c2
DC
720 },
721 {
722 xtype: 'button',
fd254233 723 iconCls: 'fa black fa-pencil',
fd254233 724 bind: {
a8b6a80a 725 iconCls: '{editBtnIcon}',
8fc2d938 726 text: '{editBtnText}',
a8b6a80a 727 hidden: '{!accountsAvailable}',
fd254233
DC
728 },
729 handler: 'toggleEditAccount',
488be4c2 730 },
a8b6a80a
TL
731 {
732 xtype: 'displayfield',
733 value: gettext('No Account available.'),
734 bind: {
735 hidden: '{accountsAvailable}',
736 },
737 },
488be4c2
DC
738 {
739 xtype: 'button',
fd254233
DC
740 hidden: true,
741 reference: 'accountlink',
31c9edc8 742 text: gettext('Add ACME Account'),
a8b6a80a
TL
743 bind: {
744 hidden: '{accountsAvailable}',
745 },
31c9edc8 746 handler: 'addAccount',
80bd3209 747 },
488be4c2
DC
748 ],
749
fd254233
DC
750 updateStore: function(store, records, success) {
751 let me = this;
752 let data = [];
753 let rec;
754 if (success && records.length > 0) {
755 rec = records[0];
756 } else {
757 rec = {
80bd3209 758 data: {},
fd254233 759 };
488be4c2 760 }
488be4c2 761
fd254233 762 me.nodeconfig = rec.data; // save nodeconfig for updates
488be4c2 763
fd254233 764 let account = 'default';
488be4c2 765
fd254233
DC
766 if (rec.data.acme) {
767 let obj = PVE.Parser.parseACME(rec.data.acme);
768 (obj.domains || []).forEach(domain => {
769 if (domain === '') return;
770 let record = {
771 domain,
772 type: 'standalone',
773 configkey: 'acme',
774 };
775 data.push(record);
776 });
488be4c2 777
fd254233
DC
778 if (obj.account) {
779 account = obj.account;
780 }
781 }
488be4c2 782
fd254233
DC
783 let vm = me.getViewModel();
784 let oldaccount = vm.get('account');
785
786 // account changed, and we do not edit currently, load again to verify
787 if (oldaccount !== account && !vm.get('accountEditable')) {
3071cc5b
DC
788 vm.set('configaccount', account);
789 me.lookup('accountselector').store.load();
fd254233 790 }
488be4c2 791
fd254233
DC
792 for (let i = 0; i < PVE.Utils.acmedomain_count; i++) {
793 let acmedomain = rec.data[`acmedomain${i}`];
794 if (!acmedomain) continue;
488be4c2 795
fd254233
DC
796 let record = PVE.Parser.parsePropertyString(acmedomain, 'domain');
797 record.type = 'dns';
798 record.configkey = `acmedomain${i}`;
799 data.push(record);
800 }
801
1580b605 802 vm.set('domaincount', data.length);
fd254233 803 me.store.loadData(data, false);
488be4c2
DC
804 },
805
806 listeners: {
fd254233 807 itemdblclick: 'editDomain',
488be4c2
DC
808 },
809
fd254233
DC
810 columns: [
811 {
812 dataIndex: 'domain',
3c6b4c80 813 flex: 5,
fd254233
DC
814 text: gettext('Domain'),
815 },
816 {
817 dataIndex: 'type',
3c6b4c80 818 flex: 1,
fd254233
DC
819 text: gettext('Type'),
820 },
821 {
822 dataIndex: 'plugin',
3c6b4c80 823 flex: 1,
fd254233
DC
824 text: gettext('Plugin'),
825 },
826 ],
488be4c2
DC
827
828 initComponent: function() {
829 var me = this;
830
831 if (!me.nodename) {
832 throw "no nodename given";
833 }
834
fd254233 835 me.rstore = Ext.create('Proxmox.data.UpdateStore', {
1b90cfc6 836 interval: 10 * 1000,
fd254233
DC
837 autoStart: true,
838 storeid: `pve-node-domains-${me.nodename}`,
839 proxy: {
840 type: 'proxmox',
841 url: `/api2/json/nodes/${me.nodename}/config`,
842 },
843 });
844
845 me.store = Ext.create('Ext.data.Store', {
846 model: 'pve-acme-domains',
847 sorters: 'domain',
848 });
488be4c2
DC
849
850 me.callParent();
fd254233
DC
851 me.mon(me.rstore, 'load', 'updateStore', me);
852 Proxmox.Utils.monStoreErrors(me, me.rstore);
1f249769 853 me.on('destroy', me.rstore.stopUpdate, me.rstore);
fd254233 854 },
488be4c2 855});