]> git.proxmox.com Git - proxmox-widget-toolkit.git/blob - node/NetworkEdit.js
f925e0d14bb220e8aaee4f4c794dfa03a6bcfe93
[proxmox-widget-toolkit.git] / node / NetworkEdit.js
1 Ext.define('Proxmox.node.NetworkEdit', {
2 extend: 'Proxmox.window.Edit',
3 alias: ['widget.proxmoxNodeNetworkEdit'],
4
5 initComponent : function() {
6 var me = this;
7
8 if (!me.nodename) {
9 throw "no node name specified";
10 }
11
12 if (!me.iftype) {
13 throw "no network device type specified";
14 }
15
16 me.create = !me.iface;
17
18 var iface_vtype;
19
20 if (me.iftype === 'bridge') {
21 iface_vtype = 'BridgeName';
22 } else if (me.iftype === 'bond') {
23 iface_vtype = 'BondName';
24 } else if (me.iftype === 'eth' && !me.create) {
25 iface_vtype = 'InterfaceName';
26 } else if (me.iftype === 'vlan' && !me.create) {
27 iface_vtype = 'InterfaceName';
28 } else if (me.iftype === 'OVSBridge') {
29 iface_vtype = 'BridgeName';
30 } else if (me.iftype === 'OVSBond') {
31 iface_vtype = 'BondName';
32 } else if (me.iftype === 'OVSIntPort') {
33 iface_vtype = 'InterfaceName';
34 } else if (me.iftype === 'OVSPort') {
35 iface_vtype = 'InterfaceName';
36 } else {
37 console.log(me.iftype);
38 throw "unknown network device type specified";
39 }
40
41 me.subject = Proxmox.Utils.render_network_iface_type(me.iftype);
42
43 var column2 = [];
44
45 if (!(me.iftype === 'OVSIntPort' || me.iftype === 'OVSPort' ||
46 me.iftype === 'OVSBond')) {
47 column2.push({
48 xtype: 'pvecheckbox',
49 fieldLabel: gettext('Autostart'),
50 name: 'autostart',
51 uncheckedValue: 0,
52 checked: me.create ? true : undefined
53 });
54 }
55
56 if (me.iftype === 'bridge') {
57 column2.push({
58 xtype: 'pvecheckbox',
59 fieldLabel: gettext('VLAN aware'),
60 name: 'bridge_vlan_aware',
61 deleteEmpty: !me.create
62 });
63 column2.push({
64 xtype: 'textfield',
65 fieldLabel: gettext('Bridge ports'),
66 name: 'bridge_ports'
67 });
68 } else if (me.iftype === 'OVSBridge') {
69 column2.push({
70 xtype: 'textfield',
71 fieldLabel: gettext('Bridge ports'),
72 name: 'ovs_ports'
73 });
74 column2.push({
75 xtype: 'textfield',
76 fieldLabel: gettext('OVS options'),
77 name: 'ovs_options'
78 });
79 } else if (me.iftype === 'OVSPort' || me.iftype === 'OVSIntPort') {
80 column2.push({
81 xtype: me.create ? 'PVE.form.BridgeSelector' : 'displayfield',
82 fieldLabel: Proxmox.Utils.render_network_iface_type('OVSBridge'),
83 allowBlank: false,
84 nodename: me.nodename,
85 bridgeType: 'OVSBridge',
86 name: 'ovs_bridge'
87 });
88 column2.push({
89 xtype: 'pveVlanField',
90 deleteEmpty: !me.create,
91 name: 'ovs_tag',
92 value: ''
93 });
94 column2.push({
95 xtype: 'textfield',
96 fieldLabel: gettext('OVS options'),
97 name: 'ovs_options'
98 });
99 } else if (me.iftype === 'bond') {
100 column2.push({
101 xtype: 'textfield',
102 fieldLabel: gettext('Slaves'),
103 name: 'slaves'
104 });
105
106 var policySelector = Ext.createWidget('bondPolicySelector', {
107 fieldLabel: gettext('Hash policy'),
108 name: 'bond_xmit_hash_policy',
109 deleteEmpty: !me.create,
110 disabled: true
111 });
112
113 column2.push({
114 xtype: 'bondModeSelector',
115 fieldLabel: gettext('Mode'),
116 name: 'bond_mode',
117 value: me.create ? 'balance-rr' : undefined,
118 listeners: {
119 change: function(f, value) {
120 if (value === 'balance-xor' ||
121 value === '802.3ad') {
122 policySelector.setDisabled(false);
123 } else {
124 policySelector.setDisabled(true);
125 policySelector.setValue('');
126 }
127 }
128 },
129 allowBlank: false
130 });
131
132 column2.push(policySelector);
133
134 } else if (me.iftype === 'OVSBond') {
135 column2.push({
136 xtype: me.create ? 'PVE.form.BridgeSelector' : 'displayfield',
137 fieldLabel: Proxmox.Utils.render_network_iface_type('OVSBridge'),
138 allowBlank: false,
139 nodename: me.nodename,
140 bridgeType: 'OVSBridge',
141 name: 'ovs_bridge'
142 });
143 column2.push({
144 xtype: 'pveVlanField',
145 deleteEmpty: !me.create,
146 name: 'ovs_tag',
147 value: ''
148 });
149 column2.push({
150 xtype: 'textfield',
151 fieldLabel: gettext('OVS options'),
152 name: 'ovs_options'
153 });
154 }
155
156 column2.push({
157 xtype: 'textfield',
158 fieldLabel: gettext('Comment'),
159 allowBlank: true,
160 nodename: me.nodename,
161 name: 'comments'
162 });
163
164 var url;
165 var method;
166
167 if (me.create) {
168 url = "/api2/extjs/nodes/" + me.nodename + "/network";
169 method = 'POST';
170 } else {
171 url = "/api2/extjs/nodes/" + me.nodename + "/network/" + me.iface;
172 method = 'PUT';
173 }
174
175 var column1 = [
176 {
177 xtype: 'hiddenfield',
178 name: 'type',
179 value: me.iftype
180 },
181 {
182 xtype: me.create ? 'textfield' : 'displayfield',
183 fieldLabel: gettext('Name'),
184 name: 'iface',
185 value: me.iface,
186 vtype: iface_vtype,
187 allowBlank: false
188 }
189 ];
190
191 if (me.iftype === 'OVSBond') {
192 column1.push(
193 {
194 xtype: 'bondModeSelector',
195 fieldLabel: gettext('Mode'),
196 name: 'bond_mode',
197 openvswitch: true,
198 value: me.create ? 'active-backup' : undefined,
199 allowBlank: false
200 },
201 {
202 xtype: 'textfield',
203 fieldLabel: gettext('Slaves'),
204 name: 'ovs_bonds'
205 }
206 );
207 } else {
208
209 column1.push(
210 {
211 xtype: 'proxmoxtextfield',
212 deleteEmpty: !me.create,
213 fieldLabel: gettext('IP address'),
214 vtype: 'IPAddress',
215 name: 'address'
216 },
217 {
218 xtype: 'proxmoxtextfield',
219 deleteEmpty: !me.create,
220 fieldLabel: gettext('Subnet mask'),
221 vtype: 'IPAddress',
222 name: 'netmask',
223 validator: function(value) {
224 /*jslint confusion: true */
225 if (!me.items) {
226 return true;
227 }
228 var address = me.down('field[name=address]').getValue();
229 if (value !== '') {
230 if (address === '') {
231 return "Subnet mask requires option 'IP address'";
232 }
233 } else {
234 if (address !== '') {
235 return "Option 'IP address' requires a subnet mask";
236 }
237 }
238
239 return true;
240 }
241 },
242 {
243 xtype: 'proxmoxtextfield',
244 deleteEmpty: !me.create,
245 fieldLabel: gettext('Gateway'),
246 vtype: 'IPAddress',
247 name: 'gateway'
248 },
249 {
250 xtype: 'proxmoxtextfield',
251 deleteEmpty: !me.create,
252 fieldLabel: gettext('IPv6 address'),
253 vtype: 'IP6Address',
254 name: 'address6'
255 },
256 {
257 xtype: 'proxmoxtextfield',
258 deleteEmpty: !me.create,
259 fieldLabel: gettext('Prefix length'),
260 vtype: 'IP6PrefixLength',
261 name: 'netmask6',
262 value: '',
263 allowBlank: true,
264 validator: function(value) {
265 /*jslint confusion: true */
266 if (!me.items) {
267 return true;
268 }
269 var address = me.down('field[name=address6]').getValue();
270 if (value !== '') {
271 if (address === '') {
272 return "IPv6 prefix length requires option 'IPv6 address'";
273 }
274 } else {
275 if (address !== '') {
276 return "Option 'IPv6 address' requires an IPv6 prefix length";
277 }
278 }
279
280 return true;
281 }
282 },
283 {
284 xtype: 'proxmoxtextfield',
285 deleteEmpty: !me.create,
286 fieldLabel: gettext('Gateway'),
287 vtype: 'IP6Address',
288 name: 'gateway6'
289 }
290 );
291 }
292
293 Ext.applyIf(me, {
294 url: url,
295 method: method,
296 items: {
297 xtype: 'inputpanel',
298 column1: column1,
299 column2: column2
300 }
301 });
302
303 me.callParent();
304
305 if (me.create) {
306 me.down('field[name=iface]').setValue(me.iface_default);
307 } else {
308 me.load({
309 success: function(response, options) {
310 var data = response.result.data;
311 if (data.type !== me.iftype) {
312 var msg = "Got unexpected device type";
313 Ext.Msg.alert(gettext('Error'), msg, function() {
314 me.close();
315 });
316 return;
317 }
318 me.setValues(data);
319 me.isValid(); // trigger validation
320 }
321 });
322 }
323 }
324 });