1
|
define([
|
2
|
"dojo/_base/array",
|
3
|
"dojo/_base/connect",
|
4
|
"stabile/grid",
|
5
|
"steam2/user",
|
6
|
"steam2/models/Server",
|
7
|
"dojox/grid/cells/_base"
|
8
|
],function(arrayUtil, connect, grid, user, Server){
|
9
|
|
10
|
var networks = {
|
11
|
|
12
|
grid: {},
|
13
|
|
14
|
_searchQuery: "name:*",
|
15
|
_statusQuery: "status:all",
|
16
|
_inited: false,
|
17
|
storeQuery: "name:*",
|
18
|
model : function(args){
|
19
|
return dojo.mixin({
|
20
|
uuid: Math.uuid().toLowerCase(),
|
21
|
name: "",
|
22
|
id: "",
|
23
|
internalip: "",
|
24
|
externalip: "",
|
25
|
ports:"",
|
26
|
domainnames: "",
|
27
|
type: "internalip",
|
28
|
status: "new"
|
29
|
}, args || {});
|
30
|
},
|
31
|
|
32
|
/** object name - for reflective lookup */
|
33
|
name : "networks",
|
34
|
|
35
|
sortInfo: ((user.is_admin)?-4:-3),
|
36
|
|
37
|
structure : [
|
38
|
{
|
39
|
field : 'id',
|
40
|
name : "ID",
|
41
|
width : "36px",
|
42
|
hidden: true
|
43
|
},
|
44
|
{
|
45
|
field : 'type',
|
46
|
name : 'Type',
|
47
|
width : "70px"
|
48
|
},
|
49
|
{
|
50
|
field : 'name',
|
51
|
name : 'Name',
|
52
|
width : "auto"
|
53
|
},
|
54
|
{
|
55
|
field : 'status',
|
56
|
name : 'Status' //,
|
57
|
//formatter : function(val, rowIdx, cell){
|
58
|
// var t = '<div class="${cssclass}">${status}</div>';
|
59
|
// var cssclass = "";
|
60
|
// if(status == "down"){
|
61
|
// status = "";
|
62
|
// cssclass = "status_indicator down_icon";
|
63
|
// }
|
64
|
// if(status == "up"){
|
65
|
// status = "";
|
66
|
// cssclass = "status_indicator up_icon";
|
67
|
// }
|
68
|
// if(status == "nat"){
|
69
|
// status = "";
|
70
|
// cssclass = "status_indicator break_icon";
|
71
|
// }
|
72
|
// return dojo.string.substitute(t, { cssclass : cssclass, status :status });
|
73
|
|
74
|
/// var item = this.grid.getItem(rowIdx);
|
75
|
/// if (item.type == "gateway" && val == "nat") return "up";
|
76
|
/// else return val;
|
77
|
//}
|
78
|
},
|
79
|
{
|
80
|
field : 'domainnames',
|
81
|
name : 'Used by',
|
82
|
width : "auto",
|
83
|
formatter : function(val, rowIdx, cell) {
|
84
|
var item = this.grid.getItem(rowIdx);
|
85
|
console.log("net item", item);
|
86
|
if (val && val!='--') {
|
87
|
return val;
|
88
|
} else if (item.systemnames && item.systemnames!='--') {
|
89
|
return '<i>' + item.systemnames + '</i>';
|
90
|
} else {
|
91
|
return '--';
|
92
|
}
|
93
|
}
|
94
|
},
|
95
|
{
|
96
|
field : 'internalip',
|
97
|
name : 'Internal IP',
|
98
|
width : "100px"
|
99
|
},
|
100
|
{
|
101
|
field : 'externalip',
|
102
|
name : 'External IP',
|
103
|
width : "100px"
|
104
|
},
|
105
|
{ field : 'action', name : 'Action', width : 'auto',
|
106
|
formatter : function(val, rowIdx, cell) {
|
107
|
var item = this.grid.getItem(rowIdx);
|
108
|
return networks.getActionButtons(item);
|
109
|
},
|
110
|
hidden: user.is_readonly
|
111
|
}
|
112
|
],
|
113
|
|
114
|
dialogStructure : [
|
115
|
{ field : "name", name : "<span style='width:115px; display:inline-block;'>Name</span>", type : "dijit.form.TextBox"},
|
116
|
{ field : "type", name : "Type", type: "dijit.form.Select",
|
117
|
attrs:{ store: "stores.networkTypes", searchAttr:"type", onChange: "networks.updateIPFields(this.value);"}},
|
118
|
{ field : 'id', name : "ID", type : "dijit.form.TextBox", width : "50px", restricted: true,
|
119
|
attrs:{ onChange: "networks.updateIPPrefix(this.value);"}},
|
120
|
{
|
121
|
field: "uuid",
|
122
|
name: "UUID",
|
123
|
type: "dijit.form.TextBox",
|
124
|
attrs: {readonly:"readonly"}
|
125
|
},
|
126
|
{ field : "status", name : "Status", type : "dijit.form.TextBox", attrs : {readonly :"readonly"}},
|
127
|
{ field : 'internalip', type : "dijit.form.ValidationTextBox",
|
128
|
name : 'Internal IP <span id="internalipprefix" style="color:gray;"></span>',
|
129
|
width : "150px",
|
130
|
attrs : {
|
131
|
regExp : "--|25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?",
|
132
|
invalidMessage : "Invalid ip."
|
133
|
}
|
134
|
},
|
135
|
{
|
136
|
field : 'externalip',
|
137
|
type : "dijit.form.TextBox",
|
138
|
name : 'External IP',
|
139
|
width : "50px",
|
140
|
attrs : {readonly :"readonly"}
|
141
|
},
|
142
|
{
|
143
|
field : 'ports',
|
144
|
type : "dijit.form.TextBox",
|
145
|
name : 'Allowed ports',
|
146
|
help: "networks/ports"
|
147
|
},
|
148
|
{
|
149
|
formatter: function(network){
|
150
|
// summary: links to server dialog for each server.
|
151
|
if(network.status == 'new'){
|
152
|
return '';
|
153
|
}
|
154
|
if(network.domains != '--'){
|
155
|
var domainnames = network.domainnames.split(/,\s|,/);
|
156
|
var uuids = network.domains.split(/,\s|,/);
|
157
|
var domains = [];
|
158
|
// create a new array that we can sort by name
|
159
|
arrayUtil.forEach(uuids, function(d, i){
|
160
|
domains.push({uuid: d, name: domainnames[i]});
|
161
|
});
|
162
|
// sort the servers
|
163
|
domains = domains.sort(function(a,b){
|
164
|
if(a.name == b.name){ return 0;}
|
165
|
if(a.name > b.name){ return 1;}
|
166
|
return -1;
|
167
|
});
|
168
|
var html = [];
|
169
|
arrayUtil.forEach(domains, function(d, i){
|
170
|
var serverEditLink = '<a onclick="servers.grid.dialog.show(stores.servers.fetchItemByIdentity({identity: \'' + d.uuid + '\'}));">' + d.name + '</a>';
|
171
|
html.push('<li>' + serverEditLink + '</li>');
|
172
|
});
|
173
|
return '<td valign="top" style="width:60px">Servers</td><td><ul style="list-style:none;padding:0;margin:0;">' + html.join('') + '</ul></td>';
|
174
|
} else if (network.systems != '--') {
|
175
|
// var systemEditLink = '<a onclick="systems.grid.dialog.show(stores.systems.fetchItemByIdentity({identity: \'' + d.uuid + '\'}));">' + d.name + '</a>';
|
176
|
var syshtml = network.systemnames;
|
177
|
return '<td valign="top" style="width:60px">Stacks</td><td><ul style="list-style:none;padding:0;margin:0;">' + syshtml + '</ul></td>';
|
178
|
}
|
179
|
return '';
|
180
|
}
|
181
|
}
|
182
|
],
|
183
|
|
184
|
store : null,
|
185
|
|
186
|
getActionButtons : function(item, include_save){
|
187
|
if (user.is_readonly) return "";
|
188
|
|
189
|
var name = item.name;
|
190
|
var type = this.name;
|
191
|
function actionButton(args){
|
192
|
args.name = name;
|
193
|
args.type = type;
|
194
|
return grid.actionButton(args);
|
195
|
}
|
196
|
|
197
|
// var store = stores.networks;
|
198
|
// var id = store.getValue(item, 'uuid');
|
199
|
// var status = store.getValue(item, 'status');
|
200
|
|
201
|
var id = item.uuid;
|
202
|
var status = item.status;
|
203
|
|
204
|
var up = actionButton({'action' :"activate", 'id' :id});
|
205
|
var down = actionButton({'action' :"stop", 'id' :id, 'confirm':true});
|
206
|
var _delete = actionButton({'action' :"delete", 'id' :id, 'confirm' :true});
|
207
|
var _break = actionButton({'action' :"deactivate", 'id' :id});
|
208
|
var save = include_save ? grid.saveButton(type) : "";
|
209
|
|
210
|
if (id == 0 || id == 1) {return "";}
|
211
|
else if(status == "down"){
|
212
|
return ((item.domains=="--" && item.systems=="--")?_delete + (item.type=="gateway"?up:""):up) + save;
|
213
|
}
|
214
|
else if(status == "up"){
|
215
|
return (item.type=="gateway"?down:(item.type=="internalip" && item.systems!="--"?_delete:'')) + save + _break;
|
216
|
}
|
217
|
else if(status == "new"){
|
218
|
return save;
|
219
|
}
|
220
|
else if(status == "--"){
|
221
|
return up + ((item.domains=="--" && item.systems=="--")?_delete:"");
|
222
|
}
|
223
|
else if(status == "nat"){
|
224
|
if ((item.internalip!="--" || item.externalip!="--") && item.domains!="--") return up + (item.type=="gateway"?down:"") + save;
|
225
|
else if ((item.internalip!="--" || item.externalip!="--") && item.systems!="--") return up + save + _delete;
|
226
|
else return (item.type=="gateway"?down:"") + save + ((item.domains=="--" && item.systems=="--")?_delete:"");
|
227
|
}
|
228
|
console.error("WTF? unknown status : ", status);
|
229
|
},
|
230
|
|
231
|
onBeforeDialog : function(item){
|
232
|
stores.networkTypes.close();
|
233
|
},
|
234
|
|
235
|
updateIPFields : function(type) {
|
236
|
|
237
|
function showRow(inputId){
|
238
|
dojo.query('#' + inputId).closest('tr').style('display', '');
|
239
|
}
|
240
|
function hideRow(inputId){
|
241
|
dojo.query('#' + inputId).closest('tr').style('display', 'none');
|
242
|
}
|
243
|
|
244
|
var internalip = dijit.byId("internalip");
|
245
|
var externalip = dijit.byId("externalip");
|
246
|
var namefield = dijit.byId("name");
|
247
|
var typefield = dijit.byId("type");
|
248
|
var ports = dijit.byId("ports");
|
249
|
var status = dijit.byId("status").value;
|
250
|
var uuid = dijit.byId('uuid').value;
|
251
|
|
252
|
if (user.is_readonly) {
|
253
|
namefield.disabled = true;
|
254
|
}
|
255
|
if (status== "new" || uuid == "0" || uuid == "1") {
|
256
|
hideRow('uuid');
|
257
|
}
|
258
|
if (type == "gateway") {
|
259
|
hideRow('externalip');
|
260
|
hideRow('internalip');
|
261
|
hideRow('ports');
|
262
|
|
263
|
internalip.set('value', '--');
|
264
|
externalip.set('value', '--');
|
265
|
} else if (type == "internalip") {
|
266
|
showRow('internalip');
|
267
|
hideRow('externalip');
|
268
|
hideRow('ports');
|
269
|
externalip.set('value', '--');
|
270
|
var id = dijit.byId('id').value;
|
271
|
networks.updateIPPrefix(id);
|
272
|
} else if (type == "ipmapping") {
|
273
|
showRow('internalip');
|
274
|
showRow('externalip');
|
275
|
showRow('ports');
|
276
|
var id = dijit.byId('id').value;
|
277
|
networks.updateIPPrefix(id);
|
278
|
} else if (type == "externalip") {
|
279
|
hideRow('internalip');
|
280
|
showRow('externalip');
|
281
|
showRow('ports');
|
282
|
var id = dijit.byId('id').value;
|
283
|
networks.updateIPPrefix(id);
|
284
|
}
|
285
|
if (status == "up" || user.is_readonly) {
|
286
|
ports.disabled = true;
|
287
|
internalip.disabled = true;
|
288
|
}
|
289
|
},
|
290
|
|
291
|
updateIPPrefix : function(id) {
|
292
|
if(!id || ((id==="1" || id==="0") && !user.is_admin)){return;}
|
293
|
if (dijit.byId('type')) { // If dialog has been closed, just return
|
294
|
var type = dijit.byId('type').value;
|
295
|
if (type == "ipmapping" || type == "internalip") {
|
296
|
var first_three_ip_octets = networks.getFirstThreeOctetsbyVlan(id);
|
297
|
dojo.byId('internalipprefix').innerHTML = first_three_ip_octets + '.';
|
298
|
}
|
299
|
}
|
300
|
},
|
301
|
|
302
|
getFirstThreeOctetsbyVlan : function(vlanid){
|
303
|
vlanid += '';
|
304
|
if(vlanid.length > 2){
|
305
|
vlanid = Number(vlanid.substr(0, vlanid.length-2)) + '.' + Number(vlanid.substr(vlanid.length-2));
|
306
|
}
|
307
|
else{
|
308
|
vlanid = "0." + vlanid;
|
309
|
}
|
310
|
return "10." + vlanid;
|
311
|
},
|
312
|
|
313
|
getOctetFour : function(ip){
|
314
|
if(ip == "--"){return "--";}
|
315
|
return ip.split('.')[3];
|
316
|
},
|
317
|
|
318
|
onDialogButtons : function(item){
|
319
|
//var status = this.store.getValue(item, 'status');
|
320
|
var internalip_field = dijit.byId('internalip');
|
321
|
var status = item.status;
|
322
|
var disable = function(dijitId){
|
323
|
var elm = dijit.byId(dijitId);
|
324
|
elm && elm.set('disabled', true);
|
325
|
return elm;
|
326
|
};
|
327
|
var enable = function(dijitId){
|
328
|
var elm = dijit.byId(dijitId);
|
329
|
elm && elm.set('disabled', false);
|
330
|
return elm;
|
331
|
};
|
332
|
|
333
|
if(status == 'new'){
|
334
|
//dijit.byId('internalip').set('disabled', true);
|
335
|
} else {
|
336
|
var id = this.store.getValue(item, 'id');
|
337
|
networks.updateIPPrefix(id);
|
338
|
var internalip = this.store.getValue(item, 'internalip');
|
339
|
if (internalip_field) internalip_field.set('value', networks.getOctetFour(internalip));
|
340
|
var domains = this.store.getValue(item, 'domains');
|
341
|
if (id<2 || (domains && domains.indexOf(",")!=-1) || item.status == 'up' || user.is_readonly) {
|
342
|
if (dijit.byId("type")) disable('type');
|
343
|
} else {
|
344
|
if (dijit.byId("type")) enable('type');
|
345
|
}
|
346
|
if(dijit.byId('id')) disable('id');
|
347
|
}
|
348
|
},
|
349
|
|
350
|
onBeforeSave : function(item){
|
351
|
var vlanid = stores.networks.getValue(item, "id");
|
352
|
if(vlanid){
|
353
|
var ip_octet_four = stores.networks.getValue(item, "internalip");
|
354
|
|
355
|
var isIPSet = function(){
|
356
|
return ip_octet_four === '--' ? false : true;
|
357
|
};
|
358
|
var internalip;
|
359
|
if(isIPSet()) {
|
360
|
internalip = networks.getFirstThreeOctetsbyVlan(vlanid) + '.' + ip_octet_four;
|
361
|
}
|
362
|
else{
|
363
|
internalip = '--';
|
364
|
}
|
365
|
stores.networks.setValue(item, "internalip", internalip);
|
366
|
}
|
367
|
var ports = dijit.byId("ports");
|
368
|
if (ports && ports.value=="") stores.networks.setValue(item, "ports", "--");
|
369
|
}
|
370
|
};
|
371
|
|
372
|
networks.init = function(){
|
373
|
if (networks._inited === true) return "OK";
|
374
|
else networks._inited = true;
|
375
|
|
376
|
connect.connect(dijit.byId('networks_status_filter_select'), 'onChange', this, this.onStatusFilterChange);
|
377
|
connect.connect(dijit.byId('networks_search_query'), 'onChange', this, this.onSearchQueryChange);
|
378
|
|
379
|
this.store = stores.networks;
|
380
|
this.domnode = "networks-grid";
|
381
|
this.grid = grid.create(this);
|
382
|
if (!user.is_readonly) {
|
383
|
if (dijit.byId("networksNewButton")) dijit.byId("networksNewButton").set("style", "display:inline");
|
384
|
}
|
385
|
|
386
|
connect.connect(this.grid, '_onFetchComplete', this, function(rows){
|
387
|
this.updateSums(rows);
|
388
|
if (!user.is_readonly) $("#networksNewButton").show();
|
389
|
});
|
390
|
|
391
|
this.grid.startup();
|
392
|
|
393
|
dojo.subscribe("networks:update", function(task){
|
394
|
if (task.uuid) networks.grid.refreshRow(task);
|
395
|
else networks.grid.refresh();
|
396
|
});
|
397
|
this.onShowItem();
|
398
|
};
|
399
|
|
400
|
networks.onShowItem = function() {
|
401
|
if (home.networksOnShowItem != null && networks.grid.dialog) {
|
402
|
networks.grid.dialog.show(home.networksOnShowItem);
|
403
|
home.networksOnShowItem = null;
|
404
|
}
|
405
|
};
|
406
|
|
407
|
networks.updateFilter = function(){
|
408
|
var query = this._searchQuery + " AND " + this._statusQuery;
|
409
|
this.grid.store.query = query;
|
410
|
this.grid.filter(query, /*rerender*/true);
|
411
|
};
|
412
|
|
413
|
networks.onSearchQueryChange = function(v){
|
414
|
if(v){
|
415
|
/*this._searchQuery = "name: '*" + v + "*'" +
|
416
|
" OR status: '" + v + "*'" +
|
417
|
" OR type: '" + v + "*'" +
|
418
|
" OR internalip: '" + v + "*'" +
|
419
|
" OR externalip: '" + v + "*'";*/
|
420
|
this._searchQuery = "name:" +v + "*";
|
421
|
}
|
422
|
else{
|
423
|
//this._searchQuery = "name: *";
|
424
|
this._searchQuery = "name:*";
|
425
|
}
|
426
|
this.updateFilter();
|
427
|
};
|
428
|
|
429
|
networks.onStatusFilterChange = function(value){
|
430
|
switch(value){
|
431
|
case "all":
|
432
|
//this._statusQuery = "uuid:*";
|
433
|
this._statusQuery = "status:all";
|
434
|
break;
|
435
|
default:
|
436
|
//this._statusQuery = "status:*" + value + '*';
|
437
|
this._statusQuery = "status:" + value;
|
438
|
}
|
439
|
this.updateFilter();
|
440
|
};
|
441
|
|
442
|
networks.updateSums = function(rows) {
|
443
|
var totalIntIPs = 0;
|
444
|
var totalExtIPs = 0;
|
445
|
var rx = 0;
|
446
|
var tx = 0;
|
447
|
var item;
|
448
|
if (!rows) {
|
449
|
for(var i = 0; i < networks.grid.rowCount; i++){
|
450
|
sumit(networks.grid.getItem(i));
|
451
|
}
|
452
|
} else {
|
453
|
for(var i in rows){
|
454
|
sumit(rows[i]);
|
455
|
}
|
456
|
}
|
457
|
|
458
|
function sumit(item) {
|
459
|
if (item && item.type) {
|
460
|
if (item.type=="internalip") {
|
461
|
totalIntIPs += 1;
|
462
|
} else if (item.type=="externalip") {
|
463
|
totalExtIPs += 1;
|
464
|
} else if (item.type=="ipmapping") {
|
465
|
totalIntIPs += 1;
|
466
|
totalExtIPs += 1;
|
467
|
}
|
468
|
if (item.rx) rx = Math.round(item.rx / 1024 / 1024);
|
469
|
if (item.tx) tx = Math.round(item.tx / 1024 / 1024);
|
470
|
}
|
471
|
}
|
472
|
|
473
|
var rxq = (user.rxquota===0)?'∞':Math.round(user.rxquota/1024/1024);
|
474
|
var txq = (user.txquota===0)?'∞':Math.round(user.txquota/1024/1024);
|
475
|
var exq = (user.externalipquota===0)?'∞' : user.externalipquota;
|
476
|
document.getElementById("ips_sum").innerHTML =
|
477
|
'<span title="Quotas: ' + exq + ' external IP\'s, ' + rxq + "/" + txq + ' GB RX/TX">' +
|
478
|
"Total external IP's: " + totalExtIPs +
|
479
|
" Total internal IP's: " + totalIntIPs +
|
480
|
" Total RX/TX: " + Math.round(rx/1024) + "/" + Math.round(tx/1024) + " GB" +
|
481
|
"</span>";
|
482
|
};
|
483
|
|
484
|
window.networks = networks;
|
485
|
return networks;
|
486
|
});
|
487
|
|