Statistics
| Branch: | Tag: | Revision:

root / ui / templates / networks.html @ d6872a51

History | View | Annotate | Download (48.7 kB)

1
<!--
2
Copyright 2011 GRNET S.A. All rights reserved.
3

4
Redistribution and use in source and binary forms, with or
5
without modification, are permitted provided that the following
6
conditions are met:
7

8
  1. Redistributions of source code must retain the above
9
     copyright notice, this list of conditions and the following
10
     disclaimer.
11

12
  2. Redistributions in binary form must reproduce the above
13
     copyright notice, this list of conditions and the following
14
     disclaimer in the documentation and/or other materials
15
     provided with the distribution.
16

17
THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
18
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
21
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
24
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28
POSSIBILITY OF SUCH DAMAGE.
29

30
The views and conclusions contained in the software and
31
documentation are those of the authors and should not be
32
interpreted as representing official policies, either expressed
33
or implied, of GRNET S.A.
34
-->
35

    
36
{% load i18n %}
37

    
38
<!-- the create button -->
39
<div id="networks-createcontainer">
40
    <div id="beforecreate"></div>
41
    <a id="networkscreate" rel="#networks-wizard" href="#">{% trans "Create New +" %}</a>
42
</div>
43

    
44
<!-- add new network overlay -->
45
<div>
46
    <div class="modal" id="networks-wizard">
47
        <div class="header">
48
        </div>
49
        <h2>{% trans "Name your network" %}</h2>
50
        <hr class="topruler" />
51
        <div class="container">
52
            <div class="name-input">
53
                <label>{% trans "Name" %}:</label>
54
                <input type="text" class="text" name="machine_name"></input>
55
                <span class="help">{% trans "(* Required field)" %}</span>
56
            </div>
57
        </div>
58
        <hr class="bottomruler" />
59
        <button type="button" id="add-network-cancel" class="cancel">{% trans "Cancel" %}</button>
60
        <button type="button" id="add-network-create" class="create">{% trans "Create Network" %}</button>
61
        <hr class="separator-end"></hr>
62
    </div>
63
</div>
64

    
65
<!-- networks list -->
66
<div id="networks-container">
67
    <!-- spinner while loading list -->
68
    <div class = "large-spinner"></div>
69

    
70
    <!-- public network template -->
71
    <div class="network" id="public-template">
72
        <img class="network-logos" src="static/internet.png" />
73
        <div href="#" class="name-div">
74
            <h5 class="namecontainer">
75
                <span class="name">{% trans "Internet" %}</span>
76
            </h5>
77
        </div>
78
        <div class="network-machines">
79
            <div class="machines-header">
80
                <div class="machines-label">{% trans "machines" %}
81
                    (<span class="machines-count">0</span>)
82
                </div>
83
                <div class="toggler down"></div>
84
            </div>
85
        </div>
86
        <div class="network-contents">
87
            <div class="network-placeholder">
88
                <div class="machines-list">
89
                <!-- append machines here -->
90
                </div>
91
                <!-- Adding servers to public network is not supported in 0.5
92
                <div class="empty-network-slot" id="machine-template">
93
                    <div class='network-add-machine'>
94
                        <span class="add-icon">+</span>
95
                    </div>
96
                </div>
97
                -->
98
            </div>
99
        </div>
100
        <div class="state">
101
            <div class="status">{% trans "Public Network" %}</div>
102
            <div class="indicators network-indicator">
103
                <div class="indicator1"></div>
104
                <div class="indicator2"></div>
105
                <div class="indicator3"></div>
106
                <div class="indicator4"></div>
107
            </div>
108
        </div>
109
        <div class="actions">
110
             <!-- Adding servers to public network is not supported in 0.5
111
            <a href="#" class="action-add">{% trans "Add Machine" %}</a>
112
            -->
113
        </div>
114
        <div class="confirm_single">
115
            <button class="yes">{% trans "Confirm" %}</button>
116
            <button class="no">{% trans "Cancel" %}</button>
117
        </div>
118
        <div class="action_error" align="center">
119
            {% trans "<span>Error</span> on" %} <span class="action">{% trans "error action" %}</span>
120
            <span class="code"></span>
121
            <span class="message"></span>
122
            <button class="details">{% trans "Details" %}</button>
123
        </div>
124
    </div>
125

    
126
    <!-- template for machines in public network -->
127
    <div class="network-machine" id="public-machine-template">
128
        <div class="network-cable"></div>
129
        <div class="machine-actions">
130
            <a href="#" class="action-details">{% trans "Details" %}</a>
131
        </div>
132
        <div class="confirm_single">
133
            <button class="yes">{% trans "Confirm" %}</button>
134
            <button class="no">{% trans "Cancel" %}</button>
135
        </div>
136
        <div class="action_error" align="center">
137
            {% trans "<span>Error</span> on" %} <span class="action">{% trans "error action" %}</span>
138
            <span class="code"></span>
139
            <span class="message"></span>
140
            <button class="details">{% trans "Details" %}</button>
141
        </div>
142
        <div class="ips">
143
            <div class="ip4-container status">
144
                {% trans "IPv4" %}:
145
                <span class="ip4">192.94.73.15</span>
146
            </div>
147
            <div class="ip6-container status">
148
                {% trans "IPv6" %}:
149
                <span class="ip6">vv</span>
150
            </div>
151
        </div>
152
        <img class="logo" src="static/icons/machines/medium/debian-on.png" />
153
        <div class='network-remove-machine'>
154
            <!-- Removing servers from public network is not supported in 0.5
155
            <span class="remove-icon">X</span>
156
            -->
157
            <span>&nbsp;</span>
158
        </div>
159
        <div href="#" class="machine-name-div">
160
            <h5 class="namecontainer">
161
                <span class="name">my desktop1</span>
162
            </h5>
163
        </div>
164
        <div class="firewall">
165
            <div class="firewall-header">
166
                <div class="firewall-label">{% trans "Firewall" %}
167
                    (<span class="firewall-off">{% trans "Off" %}</span>)
168
                </div>
169
                <div class="toggler down"></div>
170
            </div>
171
        </div>
172
        <div class="firewall-content">
173
            <div class="firewall-cable"></div>
174
            <input type="radio" class="checkboxes" value="DISABLED" name="firewall" />
175
            <span class="checkbox-legends">{% trans "Unprotected mode (Firewall off)" %}</span>
176
            <br />
177
            <input type="radio" class="checkboxes" value="ENABLED" name="firewall" />
178
            <span class="checkbox-legends">{% trans "Fully protected mode (Firewall on)" %}</span>
179
            <br />
180
            <input type="radio" class="checkboxes" value="PROTECTED" name="firewall" />
181
            <span class="checkbox-legends">{% trans "Basically protected mode (Firewall on)" %}</span>
182
            <button type="submit" class="firewall-apply">{% trans "Apply" %}</button>
183
        </div>
184
        <div class="network-separator machines"></div>
185
    </div>
186

    
187
    <!-- private network template -->
188
    <div class="network" id="private-template">
189
        <div class="actions">
190
            <a href="#" class="action-add">{% trans "Add Machine" %}</a>
191
            <a href="#" class="action-network-destroy">{% trans "Destroy" %}</a>
192
        </div>
193
        <div class="action_error" align="center">
194
            {% trans "<span>Error</span> on" %} <span class="action">{% trans "error action" %}</span>
195
            <span class="code"></span>
196
            <span class="message"></span>
197
            <button class="details">{% trans "Details" %}</button>
198
        </div>
199
        <div class="confirm_single">
200
            <button class="yes">{% trans "Confirm" %}</button>
201
            <button class="no">X</button>
202
        </div>
203
        <div class="action_error" align="center">
204
            {% trans "<span>Error</span> on" %} <span class="action">{% trans "error action" %}</span>
205
            <span class="code"></span>
206
            <span class="message"></span>
207
            <button class="details">{% trans "Details" %}</button>
208
        </div>
209
        <div class="state">
210
            <div class="status">{% trans "Private Network" %}</div>
211
            <div class="indicators network-indicator">
212
                <div class="indicator1"></div>
213
                <div class="indicator2"></div>
214
                <div class="indicator3"></div>
215
                <div class="indicator4"></div>
216
            </div>
217
            <img class="spinner" style="display:none" src="static/icons/indicators/medium/progress.gif" />
218
            <img class="wave" style="display:none" src="static/icons/indicators/medium/wave.gif" />
219
        </div>
220
        <img class="network-logos" src="static/network.png" />
221
        <div href="#" class="name-div">
222
            <h5 class="namecontainer editable">
223
                <span class="name">{% trans "My Network 1" %}</span>
224
                <span class="rename-network"></span>
225
                <div class="editbuttons" style="display:none">
226
                    <span class="save"></span>
227
                    <span class="cancel"></span>
228
                </div>
229
            </h5>
230
        </div>
231
        <div class="network-machines">
232
            <div class="machines-header">
233
                <div class="machines-label">{% trans "machines" %}
234
                    (<span class="machines-count">0</span>)
235
                </div>
236
                <div class="toggler down"></div>
237
            </div>
238
        </div>
239
        <div class="network-contents">
240
            <div class="network-placeholder">
241
                <div class="machines-list">
242
                <!-- append machines here -->
243
                </div>
244
                <div class="empty-network-slot" id="machine-template">
245
                    <div class='network-add-machine'><div class="add-icon">+</div></div>
246
                </div>
247
            </div>
248
        </div>
249
        <div class="separator"></div>
250
    </div>
251

    
252
    <!-- template for machines in private network -->
253
    <div class="network-machine" id="private-machine-template">
254
        <div class="machine-actions">
255
            <a href="#" class="action-disconnect">{% trans "Disconnect" %}</a>
256
            <a href="#" class="action-details">{% trans "Details" %}</a>
257
        </div>
258
        <div class="confirm_single">
259
            <button class="yes">{% trans "Confirm" %}</button>
260
            <button class="no">X</button>
261
        </div>
262
        <div class="action_error" align="center">
263
            {% trans "<span>Error</span> on" %} <span class="action">{% trans "error action" %}</span>
264
            <span class="code"></span>
265
            <span class="message"></span>
266
            <button class="details">{% trans "Details" %}</button>
267
        </div>
268
        <img class="logo" src="static/icons/machines/medium/debian-on.png" />
269
        <div class='network-remove-machine'><span class="remove-icon">X</span></div>
270
        <div href="#" class="machine-name-div">
271
            <h5 class="namecontainer editable">
272
                <span class="name">my desktop1</span>
273
            </h5>
274
        </div>
275
        <h5 class='machine-connect'>
276
            <span>{% trans "Connect" %}</span> {% trans "to manage private IPs" %}
277
        </h5>
278
        <div class="network-separator machines"></div>
279
    </div>
280

    
281
    <!-- the actual structure to be populated -->
282
    <div class="public-networks"></div>
283
    <div class="private-networks" style="display:none;"></div>
284
</div>
285

    
286
<!-- add servers to network overlay -->
287
<div>
288
    <div id="add-machines-wizard" class="modal">
289
        <h3 class="popup-header">{% trans "Add machine" %}</h3>
290
        <p style='display:none;'>hidden network id</p>
291
        <div class="popup-body">
292
            <div class="popup-body-inner">
293
                <div class="popup-title">{% trans "Select machines to add to:" %}</div>
294
                <div class="network-name"></div>
295
                <div class="popup-separator"></div>
296
                <div class="machines-container">
297
                    <div class="large-spinner"></div>
298
                    <div id='machine-entry-template' style="display:none;">
299
                        <input type="checkbox" />
300
                        <img class=list-logo src="static/icons/machines/small/debian-on.png" title="debian"></img>
301
                        <span class="machine-name">kati</span>
302
                    </div>
303
                </div>
304
            </div>
305
        </div>
306
        <div class="buttons">
307
            <button type="button" class="cancel" id="add-server-cancel">{% trans "Cancel" %}</button>
308
            <button type="button" class="add" id="add-server-add">{% trans "Add" %}</button>
309
        </div>
310
    </div>
311
</div>
312

    
313
<a id="add-machines-overlay" href="#" rel="#add-machines-wizard"></a>
314

    
315
<!-- reboot dialog -->
316
<div class="reboot-dialog">
317
    <p>{% trans "For the network changes to take effect you need to reboot all affected machines:" %}</p>
318
    <button class="reboot-all">{% trans "Reboot All" %}</button>
319
    <div id="reboot-machine-template" class='reboot-machine-entry'>
320
        <div class="name">my debian server</div>
321
        <button class="reboot-single">{% trans "Reboot" %}</button>
322
        <div class="reboot-error">
323
            <div class="code"></div>
324
            <div class="action"></div>
325
            <div class="message"></div>
326
            <button class="details">{% trans "Error!" %}</button>
327
        </div>
328
    </div>
329
    <div class="reboot-list"></div>
330
</div>
331

    
332
<!-- multiple confirmation dialog -->
333
<div class="confirm_multiple">
334
    <p>{% trans "Your actions will affect" %} <span class="actionLen">XX</span> {% trans "networks or machines" %}</p>
335
    <button class="yes">{% trans "Confirm All" %}</button>
336
    <button class="no">{% trans "Cancel All" %}</button>
337
</div>
338

    
339
<script>
340
// add network wizard initialization
341
$(function() {
342
    // create wizard overlay
343
    $("a#networkscreate").overlay({
344
        mask: '#666',
345
        effect: 'default',
346
        top: '10%',
347
        closeOnClick: false,
348
        oneInstance: false,
349
        closeOnEsc: true,
350
        load: false
351
    });
352
});
353

354
// intercept click to create new private network
355
$("#networkscreate").click(function() {
356
    // reset and load wizard
357
    $('#networks-wizard span.help').removeClass('red');
358
    $('#networks-wizard input').val('');
359
    $('#networks-wizard #add-network-create').text('{% trans 'Create Network' %}');
360
    $("#networks-wizard").show();
361
    $('#networks-wizard input').focus();
362
    $("a#networkscreate").data('overlay').load();
363
    // enable submit button
364
    $("#networks-wizard #add-network-create").removeAttr('disabled');
365
    return false;
366
});
367

368
// exit the add machine to network wizard
369
$("#add-network-cancel").live('click', function() {
370
    $("a#networkscreate").overlay().close();
371
});
372

373
// add selected machines to network
374
$("#add-network-create").live('click', function() {
375
    if ($('#networks-wizard input').val() == '') {
376
        $('#networks-wizard input').focus();
377
        $('#networks-wizard span.help').addClass('red');
378
    } else {
379
        // disable submit button to prevent multiple calls
380
        $(this).attr("disabled", true);
381
        // load progress bar
382
        $(this).text('');
383
        $(this).html('<img src="static/icons/indicators/medium/horizontal-progress.gif"></img>');
384
        // make the call
385
        networkName = $('#networks-wizard input').val();
386
        create_network(networkName);
387
    }
388
    return false;
389
});
390

391
// toggle component with class network-contents
392
$("#networks-pane div.machines-header").live('click', function() {
393
    if ($(this).find('.toggler').hasClass('up')) {
394
        $(this).find('.toggler').removeClass('up');
395
        $(this).find('.toggler').addClass('down');
396
        $(this).find('.machines-label').removeClass('darker');
397
        $(this).closest('div.network').removeClass('light-background');
398
    } else {
399
        $(this).find('.toggler').removeClass('down');
400
        $(this).find('.toggler').addClass('up');
401
        $(this).find('.machines-label').addClass('darker');
402
        $(this).closest('div.network').addClass('light-background');
403
    }
404
    $(this).parent().next("#networks-pane .network-contents").slideToggle(600);
405
    return false;
406
});
407

408
// toggle component with class network-contents
409
$("#networks-pane .network-logos").live('click', function() {
410
    $(this).closest('div.network').find('div.machines-header').click();
411
    return false;
412
});
413

414
//initiate network renaming
415
$("#networks-pane .name-div .rename-network, #networks-pane .name-div h5.editable span.name").live('click', function() {
416
    $(this).parent().find('.name').html("<input id=\"txtEdit\" type=\"text\" class=\"nametextbox\" value=\"" +
417
                                        $(this).parent().find('.name').text() +
418
                                        "\" / ><span class=\"oldValue\">" +
419
                                        $(this).parent().find('.name').text() + "</span>");
420
    $(this).parent().find('.rename-network').hide();
421
    $(this).parent().find(".editbuttons").fadeIn();
422
    $(this).parent().find(".nametextbox").focus().select();
423
    $(this).parent().removeClass('editable');
424

425
    //submit wizard by pressing enter on the name textbox
426
    $("#txtEdit").keydown(function (e) {
427
        if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
428
            $(this).parent().parent().find('div.editbuttons span.save').click();
429
            return false;
430
        } else if ((e.which && e.which == 27) || (e.keyCode && e.keyCode == 27)) {
431
            $(this).parent().parent().find('div.editbuttons span.cancel').click();
432
            return true;
433
        }
434
    });
435
    return false;
436
});
437

438
//rename machine
439
$("#networks-pane .name-div .editbuttons .save").live('click', function() {
440
    networkID = $(this).closest('.network').attr("id").split('-').pop();
441
    networkName = $(this).parent().parent().find('.nametextbox').val();
442
    if (networkName.trim() == ''){
443
        return false;
444
    }
445
    $(this).parent().parent().find('.name').html($(this).parent().parent().find('.nametextbox').val());
446
    $(this).parent().parent().find(".editbuttons").fadeOut("fast");
447
    $(this).parent().parent().find(".rename-network").fadeIn("slow");
448
    rename_network(networkID, networkName);
449
    return false;
450
});
451

452
//cancel renaming
453
$("#networks-pane .name-div .editbuttons .cancel").live('click', function() {
454
    $(this).parent().parent().find('.name').html($(this).parent().parent().find('.oldValue').text());
455
    $(this).parent().parent().find(".editbuttons").hide();
456
    $(this).parent().parent().find(".rename-network").fadeIn();
457
    $(this).parent().parent().addClass('editable');
458
    return false;
459
});
460

461
// intercept click to delete network
462
$("#networks-pane .action-network-destroy").live('click', function() {
463
    var networkID = $(this).parent().parent().attr('id').split('-').pop();
464
    var networkName = $(this).parent().parent().find(".name-div span.name").text();
465
    var found = false;
466
    $(this).parent().children('a').removeClass('selected');
467
    $(this).addClass('selected');
468
    $(this).parent().addClass('display')
469
    $(this).parent().parent().find('.action_error').hide();
470
    for (i=0; i < pending_actions.length; i++){ // if there is already a pending action for this network replace it
471
        if (pending_actions[i][0] == delete_network && pending_actions[i][1] == networkID){
472
            pending_actions[i][0] = delete_network;
473
            found = true
474
        }
475
    }
476
    if (!found) {
477
        // no pending action for this network was found, so let's just add it to the list
478
        pending_actions.push([delete_network, networkID, networkName]);
479
    }
480
    update_network_confirmations();
481
    return false;
482
});
483

484
// intercept click to remove machine from network
485
$("#networks-pane .remove-icon").live('click', function() {
486
    $(this).closest('.network-machine').find('.action-disconnect').click();
487
    return false;
488
});
489

490
// intercept click to remove machine from network
491
$("#networks-pane .action-disconnect").live('click', function() {
492
    var serverID = $(this).parent().parent().attr('id').split('-').pop();
493
    var serverName = $(this).closest('.network-machine').find('span.name').text();
494
    var networkID = $(this).closest('.network').attr('id').split('-').pop();
495
    var serverState = $(this).closest('.network-machine').find('img.logo').attr('src').split('-')[1];
496
    serverState = serverState.split('.')[0];
497
    var found = false;
498
    $(this).parent().children('a').removeClass('selected');
499
    $(this).addClass('selected');
500
    $(this).parent().addClass('display')
501
    $(this).parent().parent().find('.action_error').hide();
502
    for (i=0; i < pending_actions.length; i++){
503
        // if there is already a pending action for this network replace it
504
        if (pending_actions[i][0] == remove_server_from_network &&
505
            pending_actions[i][1] == networkID &&
506
            pending_actions[i][2] == serverID) {
507
                pending_actions[i][0] = remove_server_from_network;
508
                found = true
509
        }
510
    }
511
    if (!found) {
512
        // no pending action for this network was found, so let's just add it to the list
513
        pending_actions.push([remove_server_from_network, networkID, serverID, serverName, serverState]);
514
    }
515
    update_network_confirmations();
516
    return false;
517
});
518

519
$("#networks-pane .action-details").live('click', function() {
520
    var serverID = $(this).parent().parent().attr('id').split('-').pop();
521
    $.cookie('view', '2');
522
    $.cookie('server', serverID);
523
    $('a#machines').click();
524
    return false;
525
});
526

527
// add machines wizard initialization
528
$(function() {
529
    // create wizard overlay
530
    $("a#add-machines-overlay").overlay({
531
        mask: '#666',
532
        effect: 'default',
533
        top: '10%',
534
        closeOnClick: false,
535
        oneInstance: false,
536
        closeOnEsc: true,
537
        load: false
538
    });
539
});
540

541
// intercept click to add machine to  network
542
$("#networks-pane .action-add").live('click', function() {
543
    // reset pre-existing values
544
    $('#add-server-add').text('{% trans 'Add' %}');
545
    $("#add-machines-wizard .network-name").text($(this).closest('.network').find('.name-div span.name').text());
546
    $("#add-machines-wizard p").text($(this).closest('.network').attr('id').split('-').pop());
547
    $("#add-machines-wizard .large-spinner").show();
548
    $('[id^="list-entry-server-"]').remove();
549
    // list new values
550
    list_machines();
551
    // load wizard
552
    $("#add-machines-wizard").show();
553
    $("a#add-machines-overlay").data('overlay').load();
554
    // enable submit button
555
    $("#add-machines-wizard #add-server-add").removeAttr('disabled');
556
    return false;
557
});
558

559
//submit wizard by pressing enter on the name textbox
560
$("#networks-wizard div.name-input input.text").keypress(function (e) {
561
    if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
562
        $('#add-network-create').click();
563
        return false;
564
    } else {
565
        return true;
566
    }
567
});
568

569
// intercept click to bring up the add machine to network wizard
570
$("#networks-pane .add-icon").live('click', function() {
571
    $(this).closest('.network').find('.action-add').click();
572
});
573

574
// get machines in public network and list them in add server to network wizard
575
function list_machines() {
576
    var networkID = $("#add-machines-wizard p").text();
577
    // get the list of servers from the UI
578
    var all_machines = $("#networks-pane .public-networks .network-machine");
579

580
    $.each(all_machines, function(i, machine) {
581
        var currentID = machine.id.split('-').pop();
582
        // if machine already exists in private network
583
        if ( $('#net-' + networkID + '-server-' + currentID).length > 0 ) {
584
            // do nothing
585
        } else {
586
            // put it in the list
587
            var entry = $("#add-machines-wizard #machine-entry-template").clone().attr("id", "list-entry-server-" + currentID);
588
            entry.find('input').attr("name", currentID);
589
            entry.find('img').attr('src', 'static/icons/machines/small/' + $(machine).find('img.logo').attr('src').split('/').pop());
590
            entry.find('.machine-name').text($(machine).find('span.name').text());
591
            entry.appendTo("#add-machines-wizard .machines-container");
592
        }
593
    });
594
    $("#add-machines-wizard .large-spinner").hide();
595
    $('[id^="list-entry-server-"]').fadeIn("slow");
596
    return false;
597
}
598

599
// exit the add machine to network wizard
600
$("#add-server-cancel").live('click', function() {
601
    $("a#add-machines-overlay").overlay().close();
602
});
603

604
// add selected machines to network
605
$("#add-server-add").live('click', function() {
606
    var selections = $("#add-machines-wizard :checkbox:checked");
607
    // if there are no selections simply close the wizard
608
    if (selections.length == 0 ) {
609
        $("a#add-machines-overlay").overlay().close();
610
    }
611
    // if there are servers selected make the proper call
612
    else {
613
        var networkID = $("#add-machines-wizard p").text();
614
        var serverIDs = [];
615
        var serverNames = [];
616
        var serverState = [];
617
        var serverStates = [];
618
        $.each(selections, function(i, selection) {
619
            serverIDs.push(selection.name);
620
            serverNames.push($("#list-entry-server-" + selection.name + " span.machine-name").text());
621
            serverState = $("#list-entry-server-" + selection.name + " img.list-logo").attr('src').split('-')[1];
622
            serverState = serverState.split('.')[0];
623
            serverStates.push(serverState);
624
        });
625
        // disable submit button to prevent multiple calls
626
        $(this).attr("disabled", true);
627
        // load progress bar
628
        $(this).text('');
629
        $(this).html('<img src="static/icons/indicators/medium/horizontal-progress.gif"></img>');
630
        // show the proper spinner
631
        $('#net-' + networkID + '.network div.status').text(NET_STATES['Connecting']);
632
        $('#net-' + networkID + '.network img.spinner').show();
633
        // make the calls
634
        add_server_to_network(networkID, serverIDs, serverNames, serverStates);
635
    }
636
    return false;
637
});
638

639
// toggle component with class firewall-contents
640
$("#networks-pane div.firewall-header").live('click', function() {
641
    if ($(this).find('.toggler').hasClass('up')) {
642
        $(this).find('.toggler').removeClass('up');
643
        $(this).find('.toggler').addClass('down');
644
        $(this).find('.firewall-label').removeClass('darker');
645
    } else {
646
        $(this).find('.toggler').removeClass('down');
647
        $(this).find('.toggler').addClass('up');
648
        $(this).find('.firewall-label').addClass('darker');
649
    }
650
    $(this).parent().next(".firewall-content").slideToggle(600);
651
    return false;
652
});
653

654
//hide firewall content on apply click
655
$("#networks-pane .firewall-apply").live('click', function() {
656
    var serverID = $(this).closest('.network-machine').attr("id").split('-').pop();
657
    var networkID = $(this).closest('.network-machine').attr("id").split('-')[1];
658
    var profile = $(this).parent().find('input:checked').attr('value');
659
    if (profile != undefined) {
660
        set_firewall(networkID, serverID, profile);
661
        $(this).attr("disabled", true);
662
        $(this).html('<img src="static/icons/indicators/medium/horizontal-progress.gif"></img>');
663
    }
664
    return false;
665
});
666

667
function display_reboot_dialog(networkID, serverID, serverName, serverState) {
668
    // check if the server already exists in the list
669
    var existing_reboot = $("div.reboot-list div#server-" + serverID);
670
    if ( !existing_reboot.length && serverState != 'off') {
671
        $('div.reboot-dialog').fadeIn("slow");
672
        var reboot_entry = $('div#reboot-machine-template').clone().attr("id", "server-" + serverID);
673
        reboot_entry.find('div.name').text(serverName);
674
        reboot_entry.appendTo('div.reboot-list').show();
675
    }
676
    return false;
677
}
678

679
// intercept single reboot click
680
$("div.reboot-dialog button.reboot-single").live('click', function() {
681
    var serverID = $(this).parent().attr('id').split('-')[1];
682
    reboot([serverID]);
683
    // load progress bar
684
    $(this).text('');
685
    $(this).html('<img src="static/icons/indicators/medium/horizontal-progress.gif"></img>');
686
    // disable submit button to prevent multiple calls
687
    $(this).attr("disabled", true);
688
    return false;
689
});
690

691
// intercept multiple reboot click
692
$("div.reboot-dialog button.reboot-all").live('click', function() {
693
    $(this).parent().find('div.reboot-list button.reboot-single').click();
694
    // load progress bar for all buttons
695
    $(this).parent().find('button').text('');
696
    $(this).parent().find('button').html('<img src="static/icons/indicators/medium/horizontal-progress.gif"></img>');
697
    // disable submit button to prevent multiple calls
698
    $(this).attr("disabled", true);
699
    return false;
700
});
701

702
// intercept error on reboot click
703
$("div.reboot-dialog button.details").live('click', function() {
704
    $(this).closest('.reboot-machine-entry').remove();
705
    ajax_error( $(this).parent().children('.code').text(),
706
                undefined,
707
                $(this).parent().children('.action').text(),
708
                $(this).parent().children('.message').text());
709
    if ( !$('div.reboot-list').children().length ) {
710
        $('div.reboot-dialog').hide();
711
    }
712
    return false;
713
});
714

715
// after reboot success
716
function display_reboot_success(serverID) {
717
    // remove server from the list
718
    $('div.reboot-list #server-' + serverID).remove();
719
    // if there are no other servers on the list, hide the reboot dialog
720
    if ( !$('div.reboot-list').children().length ) {
721
        $('div.reboot-dialog').hide();
722
        // reset all buttons
723
        $("div.reboot-dialog button.reboot-all").html('');
724
        $("div.reboot-dialog button.reboot-all").text('{% trans 'Reboot All' %}');
725
        $("div.reboot-dialog button.reboot-single").html('');
726
        $("div.reboot-dialog button.reboot-single").text('{% trans 'Reboot' %}');
727
        // enable submit button
728
        $("#div.reboot-dialog button.reboot-all").removeAttr('disabled');
729
    }
730
    return false;
731
}
732

733
// after reboot error
734
function display_reboot_failure(status, serverID, responseText) {
735
    $('div.reboot-list #server-' + serverID + ' button.reboot-single').hide();
736
    $('div.reboot-list #server-' + serverID + ' div.code').text(status);
737
    $('div.reboot-list #server-' + serverID + ' div.action').text('Reboot');
738
    $('div.reboot-list #server-' + serverID + ' div.message').text(responseText);
739
    $('div.reboot-list #server-' + serverID + ' button.details').show();
740
    return false;
741
}
742

743
// confirm single action
744
$("#networks-pane div.confirm_single .yes").live('click', function() {
745
    // this works both for server and network actions
746
    var serverID = [];
747
    if ($(this).closest('.network-machine').attr('id')) {
748
        serverID = $(this).closest('.network-machine').attr('id').split('-').pop();
749
    }
750
    var networkID = $(this).closest('.network').attr("id").split('-').pop();
751
    // execute actions
752
    for (i=0;i<pending_actions.length;i++){
753
        // if there is a pending action for this server execute it
754
        if (pending_actions[i][0] == delete_network &&
755
            pending_actions[i][1] == networkID) {
756
                action = pending_actions.splice(i,1)[0];
757
                $(this).closest('div.network').find('div.status').text(NET_STATES['Destroying']);
758
                $(this).closest('div.network').find('img.spinner').show();
759
                action[0]([action[1]]); // execute action
760
        } else if ( pending_actions[i][0] == remove_server_from_network &&
761
                    pending_actions[i][1] == networkID ) {
762
                        $(this).closest('div.network').find('div.status').text(NET_STATES['Disconnecting']);
763
                        $(this).closest('div.network').find('img.spinner').show();
764
                        action = pending_actions.splice(i,1)[0];
765
                        action[0]([action[1]], [action[2]], [action[3]], [action[4]]); // execute action
766
        } // for adding servers to a network look in $("#add-server-add").live('click', function() {...});
767
    }
768
    $(this).parent().hide();
769
    $(this).closest("div.network").find('a.selected').removeClass('selected');
770
    $(this).closest("div.network").children('div.actions').removeClass('display');
771
    update_network_confirmations();
772
    return false;
773
});
774

775
// cancel single action
776
$("#networks-pane div.confirm_single .no").live('click', function(){
777
    // this works both for server and network actions
778
    var serverID = [];
779
    if ($(this).closest('.network-machine').attr('id')) {
780
        serverID = $(this).closest('.network-machine').attr('id').split('-').pop();
781
    }
782
    var networkID = $(this).closest('.network').attr("id").split('-').pop();
783
    // remove the action from the pending list
784
    $(this).parent().parent().children('div.machine-actions').children('a').removeClass('selected');
785
    $(this).parent().parent().children('div.machine-actions').removeClass('display');
786

787
    for (i=0; i < pending_actions.length; i++) { // if there is a pending action for this network remove it
788
        if (pending_actions[i][0] == delete_network && pending_actions[i][1] == networkID) {
789
                pending_actions.splice(i,1);
790
        } else if ( pending_actions[i][0] == remove_server_from_network &&
791
                    pending_actions[i][1] == networkID &&
792
                    pending_actions[i][2] == serverID) {
793
                        pending_actions.splice(i,1);
794
        }
795
    }
796
    $(this).parent().hide();
797
    update_network_confirmations();
798
    return false;
799
});
800

801
// after single action call error
802
function display_net_failure(status, networkID, action, responseText) {
803
    return false;
804
}
805

806
// show, single action, error details
807
$("#networks-pane div.action_error .details").live('click', function(){
808
    $(this).parent().hide();
809
    ajax_error($(this).parent().children('.code').text(),
810
                 undefined,
811
                 $(this).parent().children('.action').text(),
812
                 $(this).parent().children('.message').text());
813
    return false;
814
});
815

816
// confirm all actions
817
$("#networks-pane div.confirm_multiple .yes").live('click', function(){
818
    while(pending_actions.length > 0){ // if there is a pending action for this network execute it
819
        action = pending_actions.pop(); // extract action
820
        var networkID = action[1];
821
        $('#networks-pane .selected').removeClass('selected');
822
        $('#networks-pane .display').removeClass('display');
823
        $('#networks-pane .confirm_single').hide();
824
        if (action[0] == delete_network) {
825
            $('#networks-pane #net-' + networkID + ' .status').text(NET_STATES['Destroying']);
826
            $('#networks-pane #net-' + networkID + ' .spinner').show();
827
            action[0]([networkID]); // execute action
828
        } else if (action[0] == remove_server_from_network) {
829
            $('div.network#net-'+networkID).find('div.status').text(NET_STATES['Disconnecting']);
830
            $('div.network#net-'+networkID).find('img.spinner').show();
831
            action[0]([action[1]], [action[2]], [action[3]], [action[4]]); // execute action
832
        }
833
    }
834
    update_network_confirmations();
835
    return false;
836
});
837

838
// cancel all actions
839
$("#networks-pane div.confirm_multiple .no").live('click', function(){
840
    pending_actions = [];
841
    $('#networks-pane .selected').removeClass('selected');
842
    $('#networks-pane .display').removeClass('display');
843
    $('#networks-pane .confirm_single').hide();
844
    update_network_confirmations();
845
    return false;
846
});
847

848
// update the networks list
849
function update_networks_view(servers_data, networks_data){
850
    /*
851
    Go through the input data. Update existing entries, add
852
    new ones to the list
853
    */
854

855
    // check for changes in networks
856
    if (networks_data){
857
        /*
858
        Here we are interested in private networks only
859
        and for servers disconnected from them
860
        */
861

862
        // if we wait for a new network to be created
863
        if ($('#add-network-create').children().length > 0) {
864
            var response_objects = networks_data.networks.values;
865
            // check all objects in the response
866
            for (i=0; i < response_objects.length; i++) {
867
                // if it contains the network we want to create
868
                var networkName = $('#networks-wizard input').val();
869
                if ( response_objects[i]['name'] == networkName) {
870
                    // close the wizard
871
                    $("a#networkscreate").overlay().close();
872
                    // and the network will be inserted in the DOM
873
                    // during this update loop
874
                }
875
            }
876
        }
877

878
        // update private networks
879
        $.each(networks_data.networks.values, function(i,network) {
880
            // search DOM for this network
881
            existing = $('#networks-pane #net-' + network.id);
882

883
            // If in the DOM exist multiple networks with the same id,
884
            // delete all but one.
885
            // Defensive coding - that shouldn't happen normally
886
            while (existing.length > 1) {
887
                existing.remove();
888
            }
889

890
            // If network already exists in DOM, update it
891
            if (existing.length) {
892
                // network was deleted
893
                if (network.status == 'DELETED') {
894
                    existing.remove();
895
                }
896
                // network was renamed
897
                if (existing.find('.name-div span.name').text() != network.name) {
898
                    // set the new name
899
                    existing.find('.name-div span.name').text(network.name);
900
                }
901
                // a server was disconnected
902
                // search DOM for all machines
903
                existing_machines = $('div.private-networks div.network-machine');
904
                // check if the machines in the DOM exist in the response
905
                for (i=0; i<existing_machines.length; i++) {
906
                    // get the existing server id
907
                    var serverID = existing_machines[i].id.split('-')[3];
908
                    // if a server exists in DOM, but not in the response it has
909
                    // been disconnected
910
                    if ( network.servers.values.indexOf( parseInt(serverID) ) == -1 ) {
911
                        // remove it from DOM and reset all spinners
912
                        $('#' + existing_machines[i].id).remove();
913
                        $('#net-' + network.id + '.network div.status').text(NET_STATES['ACTIVE']);
914
                        $('#net-' + network.id + '.network img.spinner').hide();
915
                    }
916
                }
917
            }
918
            // If network does not exist in DOM, create it, do not take into account public network
919
            else if (network.id != 'public'){
920
                var privNet = $("#networks-pane #private-template").clone().attr("id", "net-" + network.id);
921
                privNet.find(".name-div span.name").text(network.name).fadeIn("slow");
922
                privNet.appendTo("#networks-pane .private-networks");
923
            }
924
        });
925
    }
926

927
    // check for changes in servers
928
    if (servers_data) {
929
        /*
930
        Here we are interested in any server contained
931
        either in a public network or a private one
932
        */
933
        $.each(servers_data.servers.values, function(i,server) {
934
            /*
935
            First update the public network
936
            */
937

938
            // search public network's DOM for this server
939
            existing_public = $('#networks-pane #net-pub-server-' + server.id);
940

941
            // get the server's OS icon
942
            var server_image = os_icon(server.metadata);
943
            if (!(server.metadata == undefined)) {
944
                var server_image = os_icon(server.metadata);
945
            } else {
946
                var server_image = "unknown"
947
            }
948

949
            // server was deleted
950
            if (server.status == 'DELETED') {
951
                existing_public.remove();
952
            }
953

954
            // If server already exists in public network, update it
955
            if (existing_public.length){
956
                // server was renamed
957
                if (server.name != existing_public.find('span.name').text()) {
958
                    existing_public.find('span.name').text(server.name.substring(0,30));
959
                }
960
                // server has changed state
961
                if (server.status=='BUILD' || server.status=='ACTIVE' ||server.status=='REBOOT') {
962
                    existing_public.find("img.logo").attr("src","static/icons/machines/medium/" + server_image + '-on.png');
963
                } else {
964
                    existing_public.find("img.logo").attr("src","static/icons/machines/medium/" + server_image + '-off.png');
965
                }
966
                // server has new ips
967
                var old_ip4 = existing_public.find('span.ip4').text();
968
                var old_ip6 = existing_public.find('span.ip6').text();
969
                var new_ips = get_public_ips(server);
970
                var new_ip4 = new_ips['ip4'];
971
                var new_ip6 = new_ips['ip6'];
972
                if (old_ip4 != new_ip4) {
973
                    if (new_ips['ip4'] == undefined) {
974
                        existing_public.find(".ip4-container").hide();
975
                    } else {
976
                        existing_public.find('span.ip4').text(new_ip4);
977
                    }
978
                }
979
                if (old_ip6 != new_ip6) {
980
                    if (new_ip6 == undefined) {
981
                        existing_public.find(".ip6-container").hide();
982
                    } else {
983
                        existing_public.find('span.ip6').text(new_ip6);
984
                    }
985
                }
986
                //TODO: server has changed OS
987
            }
988
            // If server does not exist in public network, create it
989
            else {
990
                var machine = $("#networks-pane #public-machine-template").clone().attr("id", "net-pub-server-" + server.id).fadeIn("slow");
991
                machine.find('span.name').text(server.name.substring(0,30));
992
                // find and display ips
993
                var ips = get_public_ips(server);
994
                if (ips['ip4'] == undefined) {
995
                    machine.find(".ip4-container").hide();
996
                } else {
997
                    machine.find("span.ip4").text(ips['ip4']);
998
                }
999
                if (ips['ip6'] == undefined) {
1000
                    machine.find(".ip6-container").hide();
1001
                } else {
1002
                    machine.find("span.ip6").text(ips['ip6']);
1003
                }
1004
                // add the proper icon
1005
                if (server.status=='BUILD' || server.status=='ACTIVE' ||server.status=='REBOOT') {
1006
                    machine.find("img.logo").attr("src","static/icons/machines/medium/" + server_image + '-on.png');
1007
                } else {
1008
                    machine.find("img.logo").attr("src","static/icons/machines/medium/" + server_image + '-off.png');
1009
                }
1010
                machine.appendTo("#networks-pane .public-networks .machines-list");
1011
            }
1012

1013
            /*
1014
            Now update all private networks, this does NOT check for
1015
            disconnected servers (see above in updating private networks).
1016
            Since one server may belong to more than one private networks,
1017
            we follow a different approach.
1018
            We check each server and add, update or leave it as it is accordingly
1019
            */
1020
            try {
1021
                $.each(server.addresses.values, function(i,server_net) {
1022
                    // find in which private networks it belongs
1023
                    if (server_net.id != "public") {
1024
                        var existing_private = $("#networks-pane .private-networks #net-" + server_net.id + "-server-" + server.id);
1025
                        // add new server
1026
                        if (!existing_private.length) {
1027
                            var machine = $("#networks-pane #private-machine-template").clone().attr("id", "net-" + server_net.id + "-server-" + server.id).fadeIn("slow");
1028
                            machine.find('span.name').text(server.name.substring(0,30));
1029
                            if (server.status=='BUILD' || server.status=='ACTIVE' ||server.status=='REBOOT') {
1030
                                machine.find("img.logo").attr("src","static/icons/machines/medium/" + server_image + '-on.png');
1031
                            } else {
1032
                                machine.find("img.logo").attr("src","static/icons/machines/medium/" + server_image + '-off.png');
1033
                            }
1034
                            machine.appendTo("#networks-pane .private-networks #net-" + server_net.id + " .machines-list");
1035
                        // hide spinners
1036
                        $('#net-' + server_net.id + '.network div.status').text(NET_STATES['ACTIVE']);
1037
                        $('#net-' + server_net.id + '.network img.spinner').hide();
1038
                        }
1039
                        // server was deleted
1040
                        if (server.status == 'DELETED') {
1041
                            existing_private.remove();
1042
                        }
1043
                        // server was renamed
1044
                        if (server.name != existing_private.find('span.name').text()) {
1045
                            existing_private.find('span.name').text(server.name.substring(0,30));
1046
                        }
1047
                        // server has changed state
1048
                        if (server.status=='BUILD' || server.status=='ACTIVE' ||server.status=='REBOOT') {
1049
                            existing_private.find("img.logo").attr("src","static/icons/machines/medium/" + server_image + '-on.png');
1050
                        } else {
1051
                            existing_private.find("img.logo").attr("src","static/icons/machines/medium/" + server_image + '-off.png');
1052
                        }
1053
                        //TODO: server has changed OS
1054
                    }
1055
                });
1056
            } catch (err) {
1057
                try{console.info('Server ' + server.id + ' has no network addresses')}catch(err){};
1058
            }
1059
        });
1060
    }
1061

1062
    $("#networks-pane #networks-container > .large-spinner").hide();
1063

1064
    // show all separators and hide the last one
1065
    $("div.private-networks div.network div.separator").show();
1066
    $("div.private-networks div.network div.separator:last").hide();
1067
    // update the counters of servers in each network
1068
    var nets = $('#networks-pane .network');
1069
    $.each(nets, function(i,net) {
1070
        $(net).find('span.machines-count').text($(net).find('.network-machine').length);
1071
    });
1072

1073
    // the private div shows only when private networks are available
1074
    if ($("div.private-networks div.network").length > 0) {
1075
        $("div.private-networks").fadeIn("slow");
1076
    } else {
1077
        $("div.private-networks").fadeOut("slow");
1078
    }
1079

1080
    // tag the first and last seperators for better styling
1081
    $("#pub .network-machine").removeClass('first');
1082
    $("#pub .network-machine").first().addClass('first');
1083
    $("#pub .network-machine").removeClass('last');
1084
    $("#pub .network-machine").last().addClass('last');
1085

1086
    if ($("div.public-networks div.network-machine").length == 1) {
1087
        $("div.public-networks div.network-machine div.network-cable").css('height','60px');
1088
    }
1089

1090
    //remove top margin from the first machine of each private network
1091
    $(".private-networks").find(".network-contents .network-machine:first-child").css("margin-top","0");
1092
}
1093

1094
// indicate that the requested action was not completed
1095
function display_failure(status, networkID, action, responseText) {
1096
    $('#networks-container #net-'+networkID+ ' .spinner').hide();
1097
    $('#networks-container #net-'+networkID+ ' .action_error .action').text(action);
1098
    $('#networks-container #net-'+networkID+ ' .action_error .code').text(status);
1099
    $('#networks-container #net-'+networkID+ ' .action_error .message').text(responseText);
1100
    $('#networks-container #net-'+networkID+ ' .action_error').show();
1101
}
1102

1103
// reposition multiple confirmation box on window resize
1104
$(window).resize(function(){
1105
    if (this.innerHeight - 220 < $('#networks-pane #networks-container').height()) {
1106
        $('#networks-pane .confirm_multiple').addClass('fixed');
1107
        $('div.reboot-dialog').addClass('fixed');
1108
    } else {
1109
        $('#networks-pane .confirm_multiple').removeClass('fixed');
1110
        $('div.reboot-dialog').removeClass('fixed');
1111
    }
1112
});
1113

1114
// basic functions executed on page load
1115
// hide the all of the networks contents
1116
$("#networks-pane .network-contents").hide();
1117
// hide the all of the firewall contents
1118
$("#networks-pane .firewall-content").hide();
1119
changes_since = 0; // to reload full list of servers
1120
networks_changes_since= 0; // to reload full list of networks
1121
// there is always one public network to render
1122
var pubNet = $("#networks-pane #public-template").clone().attr("id", "pub").fadeIn("slow");
1123
pubNet.appendTo("#networks-pane .public-networks");
1124
update_networks(UPDATE_INTERVAL);
1125

1126
//fix ie z-index bug by moving the overlays to the bottom
1127
$(document).ready(function() {
1128
    if ($.browser.msie) {
1129
        $("body").append($("#networks-wizard"));
1130
        $("body").append($("#add-machines-wizard"));
1131
    }
1132
});
1133

    
1134
</script>