Statistics
| Branch: | Tag: | Revision:

root / ui / templates / networks.html @ c0045740

History | View | Annotate | Download (41.6 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
        <h5 class="network-machines">
79
            {% trans "Show:" %} <span class="show-machines">{% trans "machines" %}</span>
80
            (<span class="machines-count">0</span>)
81
        </h5>
82
        <div class="network-contents">
83
            <div class="network-placeholder">
84
                <div class="network-contents-start-separator"></div>
85
                <div class="machines-list">
86
                <!-- append machines here -->
87
                </div>
88
                <div class="empty-network-slot" id="machine-template">
89
                    <div class='network-add-machine'>
90
                        {# Replace the following with the comment below for full public network functionality #}
91
                        {# <span class="add-icon">+</span> #}
92
                        <span>&nbsp;</span>
93
                    </div>
94
                </div>
95
            </div>
96
            <div class="network-contents-end-separator"></div>
97
        </div>
98
        <div class="state">
99
            <div class="status">{% trans "Public Network" %}</div>
100
            <div class="indicators network-indicator">
101
                <div class="indicator1"></div>
102
                <div class="indicator2"></div>
103
                <div class="indicator3"></div>
104
                <div class="indicator4"></div>
105
            </div>
106
        </div>
107
        <div class="actions">
108
            {# Commented out the following until there is full public network support #}
109
            {# <a href="#" class="action-add">{% trans "Add Machine" %}</a> #}
110
        </div>
111
        <div class="confirm_single">
112
            <button class="yes">{% trans "Confirm" %}</button>
113
            <button class="no">{% trans "Cancel" %}</button>
114
        </div>
115
        <div class="action_error" align="center">
116
            {% trans "<span>Error</span> on" %} <span class="action">{% trans "error action" %}</span>
117
            <span class="code"></span>
118
            <span class="message"></span>
119
            <button class="details">{% trans "Details" %}</button>
120
        </div>
121
    </div>
122

    
123
    <!-- template for machines in public network -->
124
    <div class="network-machine" id="public-machine-template">
125
        <div class="machine-actions">
126
            <a href="#" class="action-details">{% trans "Details" %}</a>
127
        </div>
128
        <div class="confirm_single">
129
            <button class="yes">{% trans "Confirm" %}</button>
130
            <button class="no">{% trans "Cancel" %}</button>
131
        </div>
132
        <div class="action_error" align="center">
133
            {% trans "<span>Error</span> on" %} <span class="action">{% trans "error action" %}</span>
134
            <span class="code"></span>
135
            <span class="message"></span>
136
            <button class="details">{% trans "Details" %}</button>
137
        </div>
138
        <div class="ips">
139
            <div class="ip4-container status">
140
                <span class="discreet">{% trans "IPv4" %}: </span>
141
                <span class="ip4">192.94.73.15</span>
142
            </div>
143
            <div class="ip6-container status">
144
                <span class="discreet">{% trans "IPv6" %}: </span>
145
                <span class="ip6">vv</span>
146
            </div>
147
        </div>
148
        <img class="logo" src="static/icons/machines/medium/debian-on.png" />
149
        <div class='network-remove-machine'>
150
            {# Replace the following with the comment below for full public network functionality #}
151
            {# <span class="remove-icon">X</span> #}
152
            <span>&nbsp;</span>
153
        </div>
154
        <div href="#" class="machine-name-div">
155
            <h5 class="namecontainer">
156
                <span class="name">my desktop1</span>
157
            </h5>
158
        </div>
159
        <h5 class="machine-settings">
160
            <span class="ip">{% trans "IPs" %}</span> |
161
            <span class="show-firewall">{% trans "Firewall" %}</span>
162
            (<span class="firewall-off">{% trans "Off" %}</span>)
163
        </h5>
164
        <div class="firewall-content">
165
            <div class="firewall-contents-start-separator"></div>
166
            <input type="radio" class="checkboxes" name="image-id1" />
167
            <span class="checkbox-legends">{% trans "Unprotected mode (Firewall off)" %}</span>
168
            <br />
169
            <input type="radio" class="checkboxes" name="image-id1" />
170
            <span class="checkbox-legends">{% trans "Fully protected mode (Firewall on)" %}</span>
171
            <br />
172
            <input type="radio" class="checkboxes" name="image-id1" />
173
            <span class="checkbox-legends">{% trans "Basically protected mode (Firewall on)" %}</span>
174
            <br />
175
            <input type="radio" class="checkboxes" name="image-id1" />
176
            <span class="checkbox-legends">{% trans "Custom protection" %} <a href="#" class="firewall-settings">{% trans "settings" %}</a> {% trans "(Advanced users only)" %}</span>
177
            <button type="submit" class="firewall-apply">{% trans "Apply" %}</button>
178
            <div class="firewall-contents-end-separator"></div>
179
        </div>
180
        <div class="network-separator machines"></div>
181
    </div>
182

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

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

    
275
    <!-- the actual structure to be populated -->
276
    <div class="public-networks"></div>
277
    <div class="private-networks" style="display:none;"></div>
278
</div>
279

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

    
307
<a id="add-machines-overlay" href="#" rel="#add-machines-wizard"></a>
308

    
309
<!-- multiple confirmation dialog -->
310
<div class="confirm_multiple">
311
    <p>{% trans "Your actions will affect" %} <span class="actionLen">XX</span> {% trans "networks" %}</p>
312
    <button class="yes">{% trans "Confirm All" %}</button>
313
    <button class="no">{% trans "Cancel All" %}</button>
314
</div>
315

    
316
<script>
317
// add network wizard initialization
318
$(function() {
319
    // create wizard overlay
320
    $("a#networkscreate").overlay({
321
        mask: '#000',
322
        effect: 'default',
323
        top: '10%',
324
        closeOnClick: false,
325
        oneInstance: false,
326
        closeOnEsc: true,
327
        load: false
328
    });
329
});
330

331
// intercept click to create new private network
332
$("#networkscreate").click(function() {
333
    // reset and load wizard
334
    $('#networks-wizard span.help').removeClass('red');
335
    $('#networks-wizard input').val('');
336
    $('#networks-wizard #add-network-create').text('{% trans 'Create Network' %}');
337
    $("#networks-wizard").show();
338
    $('#networks-wizard input').focus();
339
    $("a#networkscreate").data('overlay').load();
340
    // enable submit button
341
    $("#networks-wizard #add-network-create").removeAttr('disabled');
342
    return false;
343
});
344

345
// exit the add machine to network wizard
346
$("#add-network-cancel").live('click', function() {
347
    $("a#networkscreate").overlay().close();
348
});
349

350
// add selected machines to network
351
$("#add-network-create").live('click', function() {
352
    if ($('#networks-wizard input').val() == '') {
353
        $('#networks-wizard input').focus();
354
        $('#networks-wizard span.help').addClass('red');
355
    } else {
356
        // disable submit button to prevent multiple calls
357
        $(this).attr("disabled", true);
358
        // load progress bar
359
        $(this).text('');
360
        $(this).html('<img src="static/icons/indicators/medium/horizontal-progress.gif"></img>');
361
        // make the call
362
        networkName = $('#networks-wizard input').val();
363
        create_network(networkName);
364
    }
365
    return false;
366
});
367

368
// toggle component with class network-contents
369
$("#networks-pane .show-machines").live('click', function() {
370
    if ($('#networks-pane .network-contents .network-machine').length > 0) {
371
        $(this).parent().next("#networks-pane .network-contents").slideToggle(600);
372
    }
373
    return false;
374
});
375

376
// toggle component with class network-contents
377
$("#networks-pane .network-logos").live('click', function() {
378
    $(this).siblings("#networks-pane .network-contents").slideToggle(600);
379
    return false;
380
});
381

382
//initiate network renaming
383
$("#networks-pane .name-div .rename-network, #networks-pane .name-div h5.editable span.name").live('click', function() {
384
    $(this).parent().find('.name').html("<input id=\"txtEdit\" type=\"text\" class=\"nametextbox\" value=\"" +
385
                                        $(this).parent().find('.name').text() +
386
                                        "\" / ><span class=\"oldValue\">" +
387
                                        $(this).parent().find('.name').text() + "</span>");
388
    $(this).parent().find('.rename-network').hide();
389
    $(this).parent().find(".editbuttons").fadeIn();
390
    $(this).parent().find(".nametextbox").focus().select();
391
    $(this).parent().removeClass('editable');
392

393
    //submit wizard by pressing enter on the name textbox
394
    $("#txtEdit").keydown(function (e) {
395
        if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
396
            $(this).parent().parent().find('div.editbuttons span.save').click();
397
            return false;
398
        } else if ((e.which && e.which == 27) || (e.keyCode && e.keyCode == 27)) {
399
            $(this).parent().parent().find('div.editbuttons span.cancel').click();
400
            return true;
401
        }
402
    });
403
    return false;
404
});
405

406
//rename machine
407
$("#networks-pane .name-div .editbuttons .save").live('click', function() {
408
    networkID = $(this).closest('.network').attr("id").split('-').pop();
409
    networkName = $(this).parent().parent().find('.nametextbox').val();
410
    if (networkName.trim() == ''){
411
        return false;
412
    }
413
    $(this).parent().parent().find('.name').html($(this).parent().parent().find('.nametextbox').val());
414
    $(this).parent().parent().find(".editbuttons").fadeOut("fast");
415
    $(this).parent().parent().find(".rename-network").fadeIn("slow");
416
    rename_network(networkID, networkName);
417
    return false;
418
});
419

420
//cancel renaming
421
$("#networks-pane .name-div .editbuttons .cancel").live('click', function() {
422
    $(this).parent().parent().find('.name').html($(this).parent().parent().find('.oldValue').text());
423
    $(this).parent().parent().find(".editbuttons").hide();
424
    $(this).parent().parent().find(".rename-network").fadeIn();
425
    $(this).parent().parent().addClass('editable');
426
    return false;
427
});
428

429
// intercept click to delete network
430
$("#networks-pane .action-network-destroy").live('click', function() {
431
    var networkID = $(this).parent().parent().attr('id').split('-').pop();
432
    var networkName = $(this).parent().parent().find(".name-div span.name").text();
433
    var found = false;
434
    $(this).parent().children('a').removeClass('selected');
435
    $(this).addClass('selected');
436
    $(this).parent().addClass('display')
437
    $(this).parent().parent().find('.action_error').hide();
438
    for (i=0; i < pending_actions.length; i++){ // if there is already a pending action for this network replace it
439
        if (pending_actions[i][0] == delete_network && pending_actions[i][1] == networkID){
440
            pending_actions[i][0] = delete_network;
441
            found = true
442
        }
443
    }
444
    if (!found) {
445
        // no pending action for this network was found, so let's just add it to the list
446
        pending_actions.push([delete_network, networkID, networkName]);
447
    }
448
    update_network_confirmations();
449
    return false;
450
});
451

452
// intercept click to remove machine from network
453
$("#networks-pane .remove-icon").live('click', function() {
454
    $(this).closest('.network-machine').find('.action-disconnect').click();
455
    return false;
456
});
457

458
// intercept click to remove machine from network
459
$("#networks-pane .action-disconnect").live('click', function() {
460
    var serverID = $(this).parent().parent().attr('id').split('-').pop();
461
    var networkID = $(this).closest('.network').attr('id').split('-').pop();
462
    var found = false;
463
    $(this).parent().children('a').removeClass('selected');
464
    $(this).addClass('selected');
465
    $(this).parent().addClass('display')
466
    $(this).parent().parent().find('.action_error').hide();
467
    for (i=0; i < pending_actions.length; i++){
468
        // if there is already a pending action for this network replace it
469
        if (pending_actions[i][0] == remove_server_from_network &&
470
            pending_actions[i][1] == networkID &&
471
            pending_actions[i][2] == serverID) {
472
                pending_actions[i][0] = remove_server_from_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([remove_server_from_network, networkID, serverID]);
479
    }
480
    update_network_confirmations();
481
    return false;
482
});
483

484
$("#networks-pane .action-details").live('click', function() {
485
    var serverID = $(this).parent().parent().attr('id').split('-').pop();
486
    $.cookie('view', '2');
487
    $.cookie('server', serverID);
488
    $('a#machines').click();
489
    return false
490
});
491

492
// add machines wizard initialization
493
$(function() {
494
    // create wizard overlay
495
    $("a#add-machines-overlay").overlay({
496
        mask: '#000',
497
        effect: 'default',
498
        top: '10%',
499
        closeOnClick: false,
500
        oneInstance: false,
501
        closeOnEsc: true,
502
        load: false,
503
        onClose: function() {
504
            // hide the proper spinner and show the wave
505
            networkID = $("#add-machines-wizard p").text();
506
            $('#net-' + networkID + '.network div.status').text(NET_STATES['default']);
507
            $('#net-' + networkID + '.network img.spinner').hide();
508
            $('#net-' + networkID + '.network img.wave').attr('src','static/icons/indicators/medium/wave.gif').show();
509
            setTimeout("$('#net-" + networkID +".network img.wave').attr('src','').hide()", 3000);
510
        }
511
    });
512
});
513

514
// intercept click to add machine to  network
515
$("#networks-pane .action-add").live('click', function() {
516
    // reset pre-existing values
517
    $('#add-server-add').text('{% trans 'Add' %}');
518
    $("#add-machines-wizard .network-name").text($(this).closest('.network').find('.name-div span.name').text());
519
    $("#add-machines-wizard p").text($(this).closest('.network').attr('id').split('-').pop());
520
    $("#add-machines-wizard .large-spinner").show();
521
    $('[id^="list-entry-server-"]').remove();
522
    // list new values
523
    list_machines();
524
    // load wizard
525
    $("#add-machines-wizard").show();
526
    $("a#add-machines-overlay").data('overlay').load();
527
    // enable submit button
528
    $("#add-machines-wizard #add-server-add").removeAttr('disabled');
529
    return false;
530
});
531

532
//submit wizard by pressing enter on the name textbox
533
$("#networks-wizard div.name-input input.text").keypress(function (e) {
534
    if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
535
        $('#add-network-create').click();
536
        return false;
537
    } else {
538
        return true;
539
    }
540
});
541

542
// intercept click to bring up the add machine to network wizard
543
$("#networks-pane .add-icon").live('click', function() {
544
    $(this).closest('.network').find('.action-add').click();
545
});
546

547
// get machines in public network and list them in add server to network wizard
548
function list_machines() {
549
    var networkID = $("#add-machines-wizard p").text();
550
    // get the list of servers from the UI
551
    var all_machines = $("#networks-pane .public-networks .network-machine");
552

553
    $.each(all_machines, function(i, machine) {
554
        var currentID = machine.id.split('-').pop();
555
        // if machine already exists in private network
556
        if ( $('#net-' + networkID + '-server-' + currentID).length > 0 ) {
557
            // do nothing
558
        } else {
559
            // put it in the list
560
            var entry = $("#add-machines-wizard #machine-entry-template").clone().attr("id", "list-entry-server-" + currentID);
561
            entry.find('input').attr("name", currentID);
562
            entry.find('img').attr('src', 'static/icons/machines/small/' + $(machine).find('img.logo').attr('src').split('/').pop());
563
            entry.find('.machine-name').text($(machine).find('span.name').text());
564
            entry.appendTo("#add-machines-wizard .machines-container");
565
        }
566
    });
567
    $("#add-machines-wizard .large-spinner").hide();
568
    $('[id^="list-entry-server-"]').fadeIn("slow");
569
    return false;
570
}
571

572
// exit the add machine to network wizard
573
$("#add-server-cancel").live('click', function() {
574
    $("a#add-machines-overlay").overlay().close();
575
});
576

577
// add selected machines to network
578
$("#add-server-add").live('click', function() {
579
    var selections = $("#add-machines-wizard :checkbox:checked");
580
    // if there are no selections simply close the wizard
581
    if (selections.length == 0 ) {
582
        $("a#add-machines-overlay").overlay().close();
583
    }
584
    // if there are servers selected make the proper call
585
    else {
586
        var networkID = $("#add-machines-wizard p").text();
587
        var serverIDs = [];
588
        $.each(selections, function(i, selection) {
589
            serverIDs.push(selection.name);
590
        });
591
        // disable submit button to prevent multiple calls
592
        $(this).attr("disabled", true);
593
        // load progress bar
594
        $(this).text('');
595
        $(this).html('<img src="static/icons/indicators/medium/horizontal-progress.gif"></img>');
596
        // show the proper spinner
597
        $('#net-' + networkID + '.network div.status').text(NET_STATES['Connecting']);
598
        $('#net-' + networkID + '.network img.spinner').show();
599
        // make the calls
600
        add_server_to_network(networkID, serverIDs);
601
    }
602
    return false;
603
});
604

605
// toggle component with class firewall-contents
606
$("#networks-pane .show-firewall").live('click', function() {
607
    $(this).parent().next(".firewall-content").slideToggle(600);
608
    return false;
609
});
610

611
//hide firewall content on apply click
612
$("#networks-pane .firewall-apply").live('click', function() {
613
    $(this).parent().slideToggle(600);
614
    return false;
615
});
616

617
// confirm single action
618
$("#networks-pane div.confirm_single .yes").live('click', function() {
619
    // this works both for server and network actions
620
    var serverID = [];
621
    if ($(this).closest('.network-machine').attr('id')) {
622
        serverID = $(this).closest('.network-machine').attr('id').split('-').pop();
623
    }
624
    var networkID = $(this).closest('.network').attr("id").split('-').pop();
625
    // execute actions
626
    for (i=0;i<pending_actions.length;i++){
627
        // if there is a pending action for this server execute it
628
        if (pending_actions[i][0] == delete_network &&
629
            pending_actions[i][1] == networkID){
630
                action = pending_actions.splice(i,1)[0];
631
                $(this).closest('div.network').find('div.status').text(NET_STATES['Destroying']);
632
                $(this).closest('div.network').find('img.spinner').show();
633
                action[0]([action[1]]); // execute action
634
        } else if ( pending_actions[i][0] == remove_server_from_network &&
635
                    pending_actions[i][1] == networkID ) {
636
                        $(this).closest('div.network').find('div.status').text(NET_STATES['Disconnecting']);
637
                        $(this).closest('div.network').find('img.spinner').show();
638
                        action = pending_actions.splice(i,1)[0];
639
                        action[0]([action[1]], [action[2]]); // execute action
640
        } // for adding servers to a network look in $("#add-server-add").live('click', function() {...});
641
    }
642
    $(this).parent().hide();
643
    $(this).closest("div.network").find('a.selected').removeClass('selected');
644
    $(this).closest("div.network").children('div.actions').removeClass('display');
645
    update_network_confirmations();
646
    return false;
647
});
648

649
// cancel single action
650
$("#networks-pane div.confirm_single .no").live('click', function(){
651
    // this works both for server and network actions
652
    var serverID = [];
653
    if ($(this).closest('.network-machine').attr('id')) {
654
        serverID = $(this).closest('.network-machine').attr('id').split('-').pop();
655
    }
656
    var networkID = $(this).closest('.network').attr("id").split('-').pop();
657
    // remove the action from the pending list
658
    $(this).parent().parent().children('div.actions').children('a').removeClass('selected');
659
    $(this).parent().parent().children('div.actions').removeClass('display');
660

661
    for (i=0; i < pending_actions.length; i++) { // if there is a pending action for this network remove it
662
        if (pending_actions[i][0] == delete_network && pending_actions[i][1] == networkID) {
663
                pending_actions.splice(i,1);
664
        } else if ( pending_actions[i][0] == remove_server_from_network &&
665
                    pending_actions[i][1] == networkID &&
666
                    pending_actions[i][2] == serverID) {
667
                        pending_actions.splice(i,1);
668
        }
669
    }
670
    $(this).parent().hide();
671
    update_network_confirmations();
672
    return false;
673
});
674

675
// show, single action, error details
676
$("#networks-pane div.action_error .details").live('click', function(){
677
    // remove the action from the pending list
678
    $(this).parent().hide();
679
    ajax_error($(this).parent().children('.code').text(),
680
                 undefined,
681
                 $(this).parent().children('.action').text(),
682
                 $(this).parent().children('.message').text());
683
    return false;
684
});
685

686
// confirm all actions
687
$("#networks-pane div.confirm_multiple .yes").live('click', function(){
688
    while(pending_actions.length > 0){ // if there is a pending action for this network execute it
689
        action = pending_actions.pop(); // extract action
690
        var networkID = action[1];
691
        $('#networks-pane .selected').removeClass('selected');
692
        $('#networks-pane .display').removeClass('display');
693
        $('#networks-pane .confirm_single').hide();
694
        if (action[0] == delete_network) {
695
            $('#networks-pane #net-' + networkID + ' .status').text(NET_STATES['Destroying']);
696
            $('#networks-pane #net-' + networkID + ' .spinner').show();
697
            action[0]([networkID]); // execute action
698
        } else if (action[0] == remove_server_from_network) {
699
            action[0]([action[1]], [action[2]]); // execute action
700
        }
701
    }
702
    update_network_confirmations();
703
    return false;
704
});
705

706
// cancel all actions
707
$("#networks-pane div.confirm_multiple .no").live('click', function(){
708
    pending_actions = [];
709
    $('#networks-pane .selected').removeClass('selected');
710
    $('#networks-pane .display').removeClass('display');
711
    $('#networks-pane .confirm_single').hide();
712
    update_network_confirmations();
713
    return false;
714
});
715

716
// update the networks list
717
function update_networks_view(servers_data, networks_data){
718
    /*
719
    Go through the input data. Update existing entries, add
720
    new ones to the list
721
    */
722

723
    // check for changes in networks
724
    if (networks_data){
725
        /*
726
        Here we are interested in private networks only
727
        and not for any server they might contain
728
        */
729

730
        // if we wait for a new network to be created
731
        if ($('#add-network-create').children().length > 0) {
732
            var response_objects = networks_data.networks.values;
733
            // check all objects in the response
734
            for (i=0; i < response_objects.length; i++) {
735
                // if it contains the network we want to create
736
                var networkName = $('#networks-wizard input').val();
737
                if ( response_objects[i]['name'] == networkName) {
738
                    // close the wizard
739
                    $("a#networkscreate").overlay().close();
740
                    // and the network will be inserted in the DOM
741
                    // during the coming update loop
742
                }
743
            }
744
        }
745

746
        // update private networks
747
        $.each(networks_data.networks.values, function(i,network) {
748
            // search DOM for this network
749
            existing = $('#networks-pane #net-' + network.id);
750

751
            // if in the DOM exist multiple networks with the same id,
752
            // delete all but one.
753
            // Defensive coding - that shouldn't happen normally
754
            while (existing.length > 1) {
755
                existing.remove();
756
            }
757
            // If network already exists in DOM, update it
758
            if (existing.length){
759
                // network was deleted
760
                if (network.status == 'DELETED') {
761
                    existing.remove();
762
                }
763

764
                // network was renamed
765
                if (existing.find('.name-div span.name').text() != network.name) {
766
                    // set the new name
767
                    existing.find('.name-div span.name').text(network.name);
768
                }
769
            }
770
            // If network does not exist in DOM, create it, do not take into account public network
771
            else if (network.id != 'public'){
772
                var privNet = $("#networks-pane #private-template").clone().attr("id", "net-" + network.id);
773
                privNet.find(".name-div span.name").text(network.name).fadeIn("slow");
774
                privNet.appendTo("#networks-pane .private-networks");
775
            }
776
        });
777
    }
778

779
    // check for changes in servers
780
    if (servers_data) {
781
        /*
782
        Here we are interested in any server contained
783
        either in a public network or a private one
784
        */
785
        $.each(servers_data.servers.values, function(i,server) {
786
            /*
787
            First update the public network
788
            */
789

790
            // search public network's DOM for this server
791
            existing_public = $('#networks-pane #net-pub-server-' + server.id);
792
            // get the server's OS icon
793
            var server_image = os_icon(server.metadata);
794
            if (!(server.metadata == undefined)) {
795
                var server_image = os_icon(server.metadata);
796
            } else {
797
                var server_image = "unknown"
798
            }
799

800
            // server was deleted
801
            if (server.status == 'DELETED') {
802
                existing_public.remove();
803
            }
804

805
            // If server already exists in public network, update it
806
            if (existing_public.length){
807
                // server was renamed
808
                if (server.name != existing_public.find('span.name').text()) {
809
                    existing_public.find('span.name').text(server.name);
810
                }
811
                // server has changed state
812
                if (server.status=='BUILD' || server.status=='ACTIVE' ||server.status=='REBOOT') {
813
                    existing_public.find("img.logo").attr("src","static/icons/machines/medium/" + server_image + '-on.png');
814
                } else {
815
                    existing_public.find("img.logo").attr("src","static/icons/machines/medium/" + server_image + '-off.png');
816
                }
817
                // server has new ips
818
                var old_ip4 = existing_public.find('span.ip4').text();
819
                var old_ip6 = existing_public.find('span.ip6').text();
820
                // the following are valid because the public ips always come in this order from the api
821
                var new_ips = get_public_ips(server);
822
                var new_ip4 = new_ips['ip4'];
823
                var new_ip6 = new_ips['ip6'];
824
                if (old_ip4 != new_ip4) {
825
                    if (new_ips['ip4'] == undefined) {
826
                        existing_public.find(".ip4-container").hide();
827
                    } else {
828
                        existing_public.find('span.ip4').text(new_ip4);
829
                    }
830
                }
831
                if (old_ip6 != new_ip6) {
832
                    if (new_ip6 == undefined) {
833
                        existing_public.find(".ip6-container").hide();
834
                    } else {
835
                        existing_public.find('span.ip6').text(new_ip6);
836
                    }
837
                }
838
                //TODO: server has changed OS
839
            }
840
            // If server does not exist in public network, create it
841
            else {
842
                var machine = $("#networks-pane #public-machine-template").clone().attr("id", "net-pub-server-" + server.id).fadeIn("slow");
843
                machine.find('span.name').text(server.name);
844
                // find and display ips
845
                var ips = get_public_ips(server);
846
                if (ips['ip4'] == undefined) {
847
                    machine.find(".ip4-container").hide();
848
                } else {
849
                    machine.find("span.ip4").text(ips['ip4']);
850
                }
851
                if (ips['ip6'] == undefined) {
852
                    machine.find(".ip6-container").hide();
853
                } else {
854
                    machine.find("span.ip6").text(ips['ip6']);
855
                }
856
                // add the proper icon
857
                if (server.status=='BUILD' || server.status=='ACTIVE' ||server.status=='REBOOT') {
858
                    machine.find("img.logo").attr("src","static/icons/machines/medium/" + server_image + '-on.png');
859
                } else {
860
                    machine.find("img.logo").attr("src","static/icons/machines/medium/" + server_image + '-off.png');
861
                }
862
                machine.appendTo("#networks-pane .public-networks .machines-list");
863
            }
864

865
            /*
866
            Now update all private networks
867
            Since one server may belong to more than one private networks,
868
            we follow a different approach.
869
            We check each server and add, update or leave it as it is accordingly
870
            */
871
            try {
872
                $.each(server.addresses.values, function(i,server_net) {
873
                    // find in which private networks it belongs
874
                    if (server_net.id != "public") {
875
                        var existing_private = $("#networks-pane .private-networks #net-" + server_net.id + "-server-" + server.id);
876
                        // add new server
877
                        if (!existing_private.length) {
878
                            var machine = $("#networks-pane #private-machine-template").clone().attr("id", "net-" + server_net.id + "-server-" + server.id).fadeIn("slow");
879
                            machine.find('span.name').text(server.name);
880
                            if (server.status=='BUILD' || server.status=='ACTIVE' ||server.status=='REBOOT') {
881
                                machine.find("img.logo").attr("src","static/icons/machines/medium/" + server_image + '-on.png');
882
                            } else {
883
                                machine.find("img.logo").attr("src","static/icons/machines/medium/" + server_image + '-off.png');
884
                            }
885
                            machine.appendTo("#networks-pane .private-networks #net-" + server_net.id + " .machines-list");
886
                        }
887
                        // server was deleted
888
                        if (server.status == 'DELETED') {
889
                            existing_private.remove();
890
                        }
891
                        // server was renamed
892
                        if (server.name != existing_private.find('span.name').text()) {
893
                            existing_private.find('span.name').text(server.name);
894
                        }
895
                        // server has changed state
896
                        if (server.status=='BUILD' || server.status=='ACTIVE' ||server.status=='REBOOT') {
897
                            existing_private.find("img.logo").attr("src","static/icons/machines/medium/" + server_image + '-on.png');
898
                        } else {
899
                            existing_private.find("img.logo").attr("src","static/icons/machines/medium/" + server_image + '-off.png');
900
                        }
901
                        //TODO: server has changed OS
902
                    }
903
                });
904
            } catch (err) {
905
                try{console.info('Server ' + server.id + ' has no network addresses')}catch(err){};
906
            }
907
        });
908
    }
909

910
    $("#networks-pane #networks-container > .large-spinner").hide();
911

912
    // show all separators and hide the last one
913
    $("div.private-networks div.network div.separator").show();
914
    $("div.private-networks div.network div.separator:last").hide();
915
    // update the counters of servers in each network
916
    var nets = $('#networks-pane .network');
917
    $.each(nets, function(i,net) {
918
        $(net).find('span.machines-count').text($(net).find('.network-machine').length);
919
    });
920

921
    // the private div shows only when private networks are available
922
    if ($("div.private-networks div.network").length > 0) {
923
        $("div.private-networks").fadeIn("slow");
924
    } else {
925
        $("div.private-networks").fadeOut("slow");
926
    }
927

928
    // tag the last seperator for better styling
929
    $("#pub .network-machine").removeClass('last');
930
    $("#pub .network-machine").last().addClass('last');
931
}
932

933
// indicate that the requested action was not completed
934
function display_failure(status, networkID, action, responseText) {
935
    $('#networks-container #net-'+networkID+ ' .spinner').hide();
936
    $('#networks-container #net-'+networkID+ ' .action_error .action').text(action);
937
    $('#networks-container #net-'+networkID+ ' .action_error .code').text(status);
938
    $('#networks-container #net-'+networkID+ ' .action_error .message').text(responseText);
939
    $('#networks-container #net-'+networkID+ ' .action_error').show();
940
}
941

942

943
// reposition multiple confirmation box on window resize
944
$(window).resize(function(){
945
    if (this.innerHeight - 220 < $('#networks-pane #networks-container').height())
946
        $('#networks-pane .confirm_multiple').addClass('fixed');
947
    else
948
        $('#networks-pane .confirm_multiple').removeClass('fixed');
949
});
950

951
// basic functions executed on page load
952
// hide the all of the networks contents
953
$("#networks-pane .network-contents").hide();
954
// hide the all of the firewall contents
955
$("#networks-pane .firewall-content").hide();
956
changes_since = 0; // to reload full list of servers
957
networks_changes_since= 0; // to reload full list of networks
958
// there is alway one public network to render
959
var pubNet = $("#networks-pane #public-template").clone().attr("id", "pub").fadeIn("slow");
960
pubNet.appendTo("#networks-pane .public-networks");
961
update_networks(UPDATE_INTERVAL);
962

963
//fix ie z-index bug by moving the overlays to the bottom
964
$(document).ready(function() {
965
    if ($.browser.msie) {
966
        $("body").append($("#networks-wizard"));
967
        $("body").append($("#add-machines-wizard"));
968
    }
969
});
970

    
971
</script>