]> git.proxmox.com Git - pve-manager.git/blob - www/manager6/dc/ClusterEdit.js
gui/cluster: fix translation for cluster join button
[pve-manager.git] / www / manager6 / dc / ClusterEdit.js
1 /*jslint confusion: true*/
2 Ext.define('PVE.ClusterCreateWindow', {
3 extend: 'Proxmox.window.Edit',
4 xtype: 'pveClusterCreateWindow',
5
6 title: gettext('Create Cluster'),
7 width: 600,
8
9 method: 'POST',
10 url: '/cluster/config',
11
12 isCreate: true,
13 subject: gettext('Cluster'),
14 showTaskViewer: true,
15
16 onlineHelp: 'pvecm_create_cluster',
17
18 items: {
19 xtype: 'inputpanel',
20 items: [{
21 xtype: 'textfield',
22 fieldLabel: gettext('Cluster Name'),
23 allowBlank: false,
24 maxLength: 15,
25 name: 'clustername'
26 },
27 {
28 xtype: 'proxmoxNetworkSelector',
29 fieldLabel: Ext.String.format(gettext('Link {0}'), 0),
30 emptyText: gettext("Optional, defaults to IP resolved by node's hostname"),
31 name: 'link0',
32 autoSelect: false,
33 valueField: 'address',
34 displayField: 'address',
35 skipEmptyText: true
36 }],
37 advancedItems: [{
38 xtype: 'proxmoxNetworkSelector',
39 fieldLabel: Ext.String.format(gettext('Link {0}'), 1),
40 emptyText: gettext("Optional second link for redundancy"),
41 name: 'link1',
42 autoSelect: false,
43 valueField: 'address',
44 displayField: 'address',
45 skipEmptyText: true
46 }]
47 }
48 });
49
50 Ext.define('PVE.ClusterInfoWindow', {
51 extend: 'Ext.window.Window',
52 xtype: 'pveClusterInfoWindow',
53 mixins: ['Proxmox.Mixin.CBind'],
54
55 width: 800,
56 modal: true,
57 resizable: false,
58 title: gettext('Cluster Join Information'),
59
60 joinInfo: {
61 ipAddress: undefined,
62 fingerprint: undefined,
63 totem: {}
64 },
65
66 items: [
67 {
68 xtype: 'component',
69 border: false,
70 padding: '10 10 10 10',
71 html: gettext("Copy the Join Information here and use it on the node you want to add.")
72 },
73 {
74 xtype: 'container',
75 layout: 'form',
76 border: false,
77 padding: '0 10 10 10',
78 items: [
79 {
80 xtype: 'textfield',
81 fieldLabel: gettext('IP Address'),
82 cbind: { value: '{joinInfo.ipAddress}' },
83 editable: false
84 },
85 {
86 xtype: 'textfield',
87 fieldLabel: gettext('Fingerprint'),
88 cbind: { value: '{joinInfo.fingerprint}' },
89 editable: false
90 },
91 {
92 xtype: 'textarea',
93 inputId: 'pveSerializedClusterInfo',
94 fieldLabel: gettext('Join Information'),
95 grow: true,
96 cbind: { joinInfo: '{joinInfo}' },
97 editable: false,
98 listeners: {
99 afterrender: function(field) {
100 if (!field.joinInfo) {
101 return;
102 }
103 var jsons = Ext.JSON.encode(field.joinInfo);
104 var base64s = Ext.util.Base64.encode(jsons);
105 field.setValue(base64s);
106 }
107 }
108 }
109 ]
110 }
111 ],
112 dockedItems: [{
113 dock: 'bottom',
114 xtype: 'toolbar',
115 items: [{
116 xtype: 'button',
117 handler: function(b) {
118 var el = document.getElementById('pveSerializedClusterInfo');
119 el.select();
120 document.execCommand("copy");
121 },
122 text: gettext('Copy Information')
123 }]
124 }]
125 });
126
127 Ext.define('PVE.ClusterJoinNodeWindow', {
128 extend: 'Proxmox.window.Edit',
129 xtype: 'pveClusterJoinNodeWindow',
130
131 title: gettext('Cluster Join'),
132 width: 800,
133
134 method: 'POST',
135 url: '/cluster/config/join',
136
137 defaultFocus: 'textarea[name=serializedinfo]',
138 isCreate: true,
139 bind: {
140 submitText: '{submittxt}',
141 },
142 showTaskViewer: true,
143
144 onlineHelp: 'pvecm_join_node_to_cluster',
145
146 viewModel: {
147 parent: null,
148 data: {
149 info: {
150 fp: '',
151 ip: '',
152 clusterName: '',
153 ring0Needed: false,
154 ring1Possible: false,
155 ring1Needed: false
156 }
157 },
158 formulas: {
159 ring0EmptyText: function(get) {
160 if (get('info.ring0Needed')) {
161 return gettext("Cannot use default address safely");
162 } else {
163 return gettext("Default: IP resolved by node's hostname");
164 }
165 },
166 submittxt: function(get) {
167 let cn = get('info.clusterName');
168 if (cn) {
169 return Ext.String.format(gettext('Join {0}'), `'${cn}'`);
170 }
171 return gettext('Join');
172 },
173 },
174 },
175
176 controller: {
177 xclass: 'Ext.app.ViewController',
178 control: {
179 '#': {
180 close: function() {
181 delete PVE.Utils.silenceAuthFailures;
182 }
183 },
184 'proxmoxcheckbox[name=assistedEntry]': {
185 change: 'onInputTypeChange'
186 },
187 'textarea[name=serializedinfo]': {
188 change: 'recomputeSerializedInfo',
189 enable: 'resetField'
190 },
191 'proxmoxtextfield[name=ring1_addr]': {
192 enable: 'ring1Needed'
193 },
194 'textfield': {
195 disable: 'resetField'
196 }
197 },
198 resetField: function(field) {
199 field.reset();
200 },
201 ring1Needed: function(f) {
202 var vm = this.getViewModel();
203 f.allowBlank = !vm.get('info.ring1Needed');
204 },
205 onInputTypeChange: function(field, assistedInput) {
206 var vm = this.getViewModel();
207 if (!assistedInput) {
208 vm.set('info.ring1Possible', true);
209 }
210 },
211 recomputeSerializedInfo: function(field, value) {
212 var vm = this.getViewModel();
213 var jsons = Ext.util.Base64.decode(value);
214 var joinInfo = Ext.JSON.decode(jsons, true);
215
216 var info = {
217 fp: '',
218 ring1Needed: false,
219 ring1Possible: false,
220 ip: '',
221 clusterName: ''
222 };
223
224 var totem = {};
225 if (!(joinInfo && joinInfo.totem)) {
226 field.valid = false;
227 } else {
228 var ring0Needed = false;
229 if (joinInfo.ring_addr !== undefined) {
230 ring0Needed = joinInfo.ring_addr[0] !== joinInfo.ipAddress;
231 }
232
233 info = {
234 ip: joinInfo.ipAddress,
235 fp: joinInfo.fingerprint,
236 ring0Needed: ring0Needed,
237 ring1Possible: !!joinInfo.totem['interface']['1'],
238 ring1Needed: !!joinInfo.totem['interface']['1'],
239 clusterName: joinInfo.totem['cluster_name']
240 };
241 totem = joinInfo.totem;
242 field.valid = true;
243 }
244
245 vm.set('info', info);
246 }
247 },
248
249 submit: function() {
250 // joining may produce temporarily auth failures, ignore as long the task runs
251 PVE.Utils.silenceAuthFailures = true;
252 this.callParent();
253 },
254
255 taskDone: function(success) {
256 delete PVE.Utils.silenceAuthFailures;
257 if (success) {
258 // reload always (if user wasn't faster), but wait a bit for pveproxy
259 Ext.defer(function() {
260 window.location.reload(true);
261 }, 5000);
262 var txt = gettext('Cluster join task finished, node certificate may have changed, reload GUI!');
263 // ensure user cannot do harm
264 Ext.getBody().mask(txt, ['pve-static-mask']);
265 // TaskView may hide above mask, so tell him directly
266 Ext.Msg.show({
267 title: gettext('Join Task Finished'),
268 icon: Ext.Msg.INFO,
269 msg: txt
270 });
271 }
272 },
273
274 items: [{
275 xtype: 'proxmoxcheckbox',
276 reference: 'assistedEntry',
277 name: 'assistedEntry',
278 submitValue: false,
279 value: true,
280 autoEl: {
281 tag: 'div',
282 'data-qtip': gettext('Select if join information should be extracted from pasted cluster information, deselect for manual entering')
283 },
284 boxLabel: gettext('Assisted join: Paste encoded cluster join information and enter password.')
285 },
286 {
287 xtype: 'textarea',
288 name: 'serializedinfo',
289 submitValue: false,
290 allowBlank: false,
291 fieldLabel: gettext('Information'),
292 emptyText: gettext('Paste encoded Cluster Information here'),
293 validator: function(val) {
294 return val === '' || this.valid ||
295 gettext('Does not seem like a valid encoded Cluster Information!');
296 },
297 bind: {
298 disabled: '{!assistedEntry.checked}',
299 hidden: '{!assistedEntry.checked}'
300 },
301 value: ''
302 },
303 {
304 xtype: 'inputpanel',
305 column1: [
306 {
307 xtype: 'textfield',
308 fieldLabel: gettext('Peer Address'),
309 allowBlank: false,
310 bind: {
311 value: '{info.ip}',
312 readOnly: '{assistedEntry.checked}'
313 },
314 name: 'hostname'
315 },
316 {
317 xtype: 'textfield',
318 inputType: 'password',
319 emptyText: gettext("Peer's root password"),
320 fieldLabel: gettext('Password'),
321 allowBlank: false,
322 name: 'password'
323 }
324 ],
325 column2: [
326 {
327 xtype: 'proxmoxNetworkSelector',
328 fieldLabel: Ext.String.format(gettext('Link {0}'), 0),
329 bind: {
330 emptyText: '{ring0EmptyText}',
331 allowBlank: '{!info.ring0Needed}'
332 },
333 skipEmptyText: true,
334 autoSelect: false,
335 valueField: 'address',
336 displayField: 'address',
337 name: 'link0'
338 },
339 {
340 xtype: 'proxmoxNetworkSelector',
341 fieldLabel: Ext.String.format(gettext('Link {0}'), 1),
342 skipEmptyText: true,
343 autoSelect: false,
344 valueField: 'address',
345 displayField: 'address',
346 bind: {
347 disabled: '{!info.ring1Possible}',
348 allowBlank: '{!info.ring1Needed}',
349 },
350 name: 'link1'
351 }
352 ],
353 columnB: [
354 {
355 xtype: 'textfield',
356 fieldLabel: gettext('Fingerprint'),
357 allowBlank: false,
358 bind: {
359 value: '{info.fp}',
360 readOnly: '{assistedEntry.checked}'
361 },
362 name: 'fingerprint'
363 }
364 ]
365 }]
366 });