Statistics
| Branch: | Tag: | Revision:

root / ui / templates / networks.html @ 24990e31

History | View | Annotate | Download (43.5 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="network-contents-start-separator"></div>
89
                <div class="machines-list">
90
                <!-- append machines here -->
91
                </div>
92
                <!-- Adding servers to public network is not supported in 0.5
93
                <div class="empty-network-slot" id="machine-template">
94
                    <div class='network-add-machine'>
95
                        <span class="add-icon">+</span>
96
                    </div>
97
                </div>
98
                -->
99
            </div>
100
            <div class="network-contents-end-separator"></div>
101
        </div>
102
        <div class="state">
103
            <div class="status">{% trans "Public Network" %}</div>
104
            <div class="indicators network-indicator">
105
                <div class="indicator1"></div>
106
                <div class="indicator2"></div>
107
                <div class="indicator3"></div>
108
                <div class="indicator4"></div>
109
            </div>
110
        </div>
111
        <div class="actions">
112
             <!-- Adding servers to public network is not supported in 0.5
113
            <a href="#" class="action-add">{% trans "Add Machine" %}</a>
114
            -->
115
        </div>
116
        <div class="confirm_single">
117
            <button class="yes">{% trans "Confirm" %}</button>
118
            <button class="no">{% trans "Cancel" %}</button>
119
        </div>
120
        <div class="action_error" align="center">
121
            {% trans "<span>Error</span> on" %} <span class="action">{% trans "error action" %}</span>
122
            <span class="code"></span>
123
            <span class="message"></span>
124
            <button class="details">{% trans "Details" %}</button>
125
        </div>
126
    </div>
127

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

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

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

    
290
    <!-- the actual structure to be populated -->
291
    <div class="public-networks"></div>
292
    <div class="private-networks" style="display:none;"></div>
293
</div>
294

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

    
322
<a id="add-machines-overlay" href="#" rel="#add-machines-wizard"></a>
323

    
324
<!-- multiple confirmation dialog -->
325
<div class="confirm_multiple">
326
    <p>{% trans "Your actions will affect" %} <span class="actionLen">XX</span> {% trans "networks or machines" %}</p>
327
    <button class="yes">{% trans "Confirm All" %}</button>
328
    <button class="no">{% trans "Cancel All" %}</button>
329
</div>
330

    
331
<script>
332
// add network wizard initialization
333
$(function() {
334
    // create wizard overlay
335
    $("a#networkscreate").overlay({
336
        mask: '#666',
337
        effect: 'default',
338
        top: '10%',
339
        closeOnClick: false,
340
        oneInstance: false,
341
        closeOnEsc: true,
342
        load: false
343
    });
344
});
345

346
// intercept click to create new private network
347
$("#networkscreate").click(function() {
348
    // reset and load wizard
349
    $('#networks-wizard span.help').removeClass('red');
350
    $('#networks-wizard input').val('');
351
    $('#networks-wizard #add-network-create').text('{% trans 'Create Network' %}');
352
    $("#networks-wizard").show();
353
    $('#networks-wizard input').focus();
354
    $("a#networkscreate").data('overlay').load();
355
    // enable submit button
356
    $("#networks-wizard #add-network-create").removeAttr('disabled');
357
    return false;
358
});
359

360
// exit the add machine to network wizard
361
$("#add-network-cancel").live('click', function() {
362
    $("a#networkscreate").overlay().close();
363
});
364

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

383
// toggle component with class network-contents
384
$("#networks-pane div.machines-header").live('click', function() {
385
    if ($('#networks-pane .network-contents .network-machine').length > 0) {
386
        $(this).parent().next("#networks-pane .network-contents").slideToggle(600);
387
    }
388
    return false;
389
});
390

391
// toggle component with class network-contents
392
$("#networks-pane .network-logos").live('click', function() {
393
    $(this).siblings("#networks-pane .network-contents").slideToggle(600);
394
    return false;
395
});
396

397
//initiate network renaming
398
$("#networks-pane .name-div .rename-network, #networks-pane .name-div h5.editable span.name").live('click', function() {
399
    $(this).parent().find('.name').html("<input id=\"txtEdit\" type=\"text\" class=\"nametextbox\" value=\"" +
400
                                        $(this).parent().find('.name').text() +
401
                                        "\" / ><span class=\"oldValue\">" +
402
                                        $(this).parent().find('.name').text() + "</span>");
403
    $(this).parent().find('.rename-network').hide();
404
    $(this).parent().find(".editbuttons").fadeIn();
405
    $(this).parent().find(".nametextbox").focus().select();
406
    $(this).parent().removeClass('editable');
407

408
    //submit wizard by pressing enter on the name textbox
409
    $("#txtEdit").keydown(function (e) {
410
        if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
411
            $(this).parent().parent().find('div.editbuttons span.save').click();
412
            return false;
413
        } else if ((e.which && e.which == 27) || (e.keyCode && e.keyCode == 27)) {
414
            $(this).parent().parent().find('div.editbuttons span.cancel').click();
415
            return true;
416
        }
417
    });
418
    return false;
419
});
420

421
//rename machine
422
$("#networks-pane .name-div .editbuttons .save").live('click', function() {
423
    networkID = $(this).closest('.network').attr("id").split('-').pop();
424
    networkName = $(this).parent().parent().find('.nametextbox').val();
425
    if (networkName.trim() == ''){
426
        return false;
427
    }
428
    $(this).parent().parent().find('.name').html($(this).parent().parent().find('.nametextbox').val());
429
    $(this).parent().parent().find(".editbuttons").fadeOut("fast");
430
    $(this).parent().parent().find(".rename-network").fadeIn("slow");
431
    rename_network(networkID, networkName);
432
    return false;
433
});
434

435
//cancel renaming
436
$("#networks-pane .name-div .editbuttons .cancel").live('click', function() {
437
    $(this).parent().parent().find('.name').html($(this).parent().parent().find('.oldValue').text());
438
    $(this).parent().parent().find(".editbuttons").hide();
439
    $(this).parent().parent().find(".rename-network").fadeIn();
440
    $(this).parent().parent().addClass('editable');
441
    return false;
442
});
443

444
// intercept click to delete network
445
$("#networks-pane .action-network-destroy").live('click', function() {
446
    var networkID = $(this).parent().parent().attr('id').split('-').pop();
447
    var networkName = $(this).parent().parent().find(".name-div span.name").text();
448
    var found = false;
449
    $(this).parent().children('a').removeClass('selected');
450
    $(this).addClass('selected');
451
    $(this).parent().addClass('display')
452
    $(this).parent().parent().find('.action_error').hide();
453
    for (i=0; i < pending_actions.length; i++){ // if there is already a pending action for this network replace it
454
        if (pending_actions[i][0] == delete_network && pending_actions[i][1] == networkID){
455
            pending_actions[i][0] = delete_network;
456
            found = true
457
        }
458
    }
459
    if (!found) {
460
        // no pending action for this network was found, so let's just add it to the list
461
        pending_actions.push([delete_network, networkID, networkName]);
462
    }
463
    update_network_confirmations();
464
    return false;
465
});
466

467
// intercept click to remove machine from network
468
$("#networks-pane .remove-icon").live('click', function() {
469
    $(this).closest('.network-machine').find('.action-disconnect').click();
470
    return false;
471
});
472

473
// intercept click to remove machine from network
474
$("#networks-pane .action-disconnect").live('click', function() {
475
    var serverID = $(this).parent().parent().attr('id').split('-').pop();
476
    var networkID = $(this).closest('.network').attr('id').split('-').pop();
477
    var found = false;
478
    $(this).parent().children('a').removeClass('selected');
479
    $(this).addClass('selected');
480
    $(this).parent().addClass('display')
481
    $(this).parent().parent().find('.action_error').hide();
482
    for (i=0; i < pending_actions.length; i++){
483
        // if there is already a pending action for this network replace it
484
        if (pending_actions[i][0] == remove_server_from_network &&
485
            pending_actions[i][1] == networkID &&
486
            pending_actions[i][2] == serverID) {
487
                pending_actions[i][0] = remove_server_from_network;
488
                found = true
489
        }
490
    }
491
    if (!found) {
492
        // no pending action for this network was found, so let's just add it to the list
493
        pending_actions.push([remove_server_from_network, networkID, serverID]);
494
    }
495
    update_network_confirmations();
496
    return false;
497
});
498

499
$("#networks-pane .action-details").live('click', function() {
500
    var serverID = $(this).parent().parent().attr('id').split('-').pop();
501
    $.cookie('view', '2');
502
    $.cookie('server', serverID);
503
    $('a#machines').click();
504
    return false;
505
});
506

507
// add machines wizard initialization
508
$(function() {
509
    // create wizard overlay
510
    $("a#add-machines-overlay").overlay({
511
        mask: '#666',
512
        effect: 'default',
513
        top: '10%',
514
        closeOnClick: false,
515
        oneInstance: false,
516
        closeOnEsc: true,
517
        load: false
518
    });
519
});
520

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

539
//submit wizard by pressing enter on the name textbox
540
$("#networks-wizard div.name-input input.text").keypress(function (e) {
541
    if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
542
        $('#add-network-create').click();
543
        return false;
544
    } else {
545
        return true;
546
    }
547
});
548

549
// intercept click to bring up the add machine to network wizard
550
$("#networks-pane .add-icon").live('click', function() {
551
    $(this).closest('.network').find('.action-add').click();
552
});
553

554
// get machines in public network and list them in add server to network wizard
555
function list_machines() {
556
    var networkID = $("#add-machines-wizard p").text();
557
    // get the list of servers from the UI
558
    var all_machines = $("#networks-pane .public-networks .network-machine");
559

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

579
// exit the add machine to network wizard
580
$("#add-server-cancel").live('click', function() {
581
    $("a#add-machines-overlay").overlay().close();
582
});
583

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

612
// toggle component with class firewall-contents
613
$("#networks-pane div.firewall-header").live('click', function() {
614
    $(this).parent().next(".firewall-content").slideToggle(600);
615
    return false;
616
});
617

618
//hide firewall content on apply click
619
$("#networks-pane .firewall-apply").live('click', function() {
620
    $(this).parent().slideToggle(600);
621
    return false;
622
});
623

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

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

668
    for (i=0; i < pending_actions.length; i++) { // if there is a pending action for this network remove it
669
        if (pending_actions[i][0] == delete_network && pending_actions[i][1] == networkID) {
670
                pending_actions.splice(i,1);
671
        } else if ( pending_actions[i][0] == remove_server_from_network &&
672
                    pending_actions[i][1] == networkID &&
673
                    pending_actions[i][2] == serverID) {
674
                        pending_actions.splice(i,1);
675
        }
676
    }
677
    $(this).parent().hide();
678
    update_network_confirmations();
679
    return false;
680
});
681

682
// show, single action, error details
683
$("#networks-pane div.action_error .details").live('click', function(){
684
    // remove the action from the pending list
685
    $(this).parent().hide();
686
    ajax_error($(this).parent().children('.code').text(),
687
                 undefined,
688
                 $(this).parent().children('.action').text(),
689
                 $(this).parent().children('.message').text());
690
    return false;
691
});
692

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

715
// cancel all actions
716
$("#networks-pane div.confirm_multiple .no").live('click', function(){
717
    pending_actions = [];
718
    $('#networks-pane .selected').removeClass('selected');
719
    $('#networks-pane .display').removeClass('display');
720
    $('#networks-pane .confirm_single').hide();
721
    update_network_confirmations();
722
    return false;
723
});
724

725
// update the networks list
726
function update_networks_view(servers_data, networks_data){
727
    /*
728
    Go through the input data. Update existing entries, add
729
    new ones to the list
730
    */
731

732
    // check for changes in networks
733
    if (networks_data){
734
        /*
735
        Here we are interested in private networks only
736
        and for servers disconnected from them
737
        */
738

739
        // if we wait for a new network to be created
740
        if ($('#add-network-create').children().length > 0) {
741
            var response_objects = networks_data.networks.values;
742
            // check all objects in the response
743
            for (i=0; i < response_objects.length; i++) {
744
                // if it contains the network we want to create
745
                var networkName = $('#networks-wizard input').val();
746
                if ( response_objects[i]['name'] == networkName) {
747
                    // close the wizard
748
                    $("a#networkscreate").overlay().close();
749
                    // and the network will be inserted in the DOM
750
                    // during this update loop
751
                }
752
            }
753
        }
754

755
        // update private networks
756
        $.each(networks_data.networks.values, function(i,network) {
757
            // search DOM for this network
758
            existing = $('#networks-pane #net-' + network.id);
759

760
            // If in the DOM exist multiple networks with the same id,
761
            // delete all but one.
762
            // Defensive coding - that shouldn't happen normally
763
            while (existing.length > 1) {
764
                existing.remove();
765
            }
766

767
            // If network already exists in DOM, update it
768
            if (existing.length) {
769
                // network was deleted
770
                if (network.status == 'DELETED') {
771
                    existing.remove();
772
                }
773
                // network was renamed
774
                if (existing.find('.name-div span.name').text() != network.name) {
775
                    // set the new name
776
                    existing.find('.name-div span.name').text(network.name);
777
                }
778
                // a server was disconnected
779
                // search DOM for all machines
780
                existing_machines = $('div.private-networks div.network-machine');
781
                // check if the mahcines in the DOM exist in the response
782
                for (i=0; i<existing_machines.length; i++) {
783
                    // get the existing server id
784
                    var serverID = existing_machines[i].id.split('-')[3];
785
                    // if a server exists in DOM, but not in the response it has
786
                    // been disconnected
787
                    if ( network.servers.values.indexOf( parseInt(serverID) ) == -1 ) {
788
                        // so remove it from DOM and reset all spinners
789
                        $("#" + existing_machines[i].id).remove();
790
                        $('#net-' + network.id + '.network div.status').text(NET_STATES['ACTIVE']);
791
                        $('#net-' + network.id + '.network img.spinner').hide();
792
                        //$('#net-' + network.id + '.network img.wave').attr('src','static/icons/indicators/medium/wave.gif').show();
793
                        //setTimeout("$('#net-" + network.id +".network img.wave').attr('src','').hide()", 3000);
794
                    }
795
                }
796
            }
797
            // If network does not exist in DOM, create it, do not take into account public network
798
            else if (network.id != 'public'){
799
                var privNet = $("#networks-pane #private-template").clone().attr("id", "net-" + network.id);
800
                privNet.find(".name-div span.name").text(network.name).fadeIn("slow");
801
                privNet.appendTo("#networks-pane .private-networks");
802
            }
803
        });
804
    }
805

806
    // check for changes in servers
807
    if (servers_data) {
808
        /*
809
        Here we are interested in any server contained
810
        either in a public network or a private one
811
        */
812
        $.each(servers_data.servers.values, function(i,server) {
813
            /*
814
            First update the public network
815
            */
816

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

820
            // get the server's OS icon
821
            var server_image = os_icon(server.metadata);
822
            if (!(server.metadata == undefined)) {
823
                var server_image = os_icon(server.metadata);
824
            } else {
825
                var server_image = "unknown"
826
            }
827

828
            // server was deleted
829
            if (server.status == 'DELETED') {
830
                existing_public.remove();
831
            }
832

833
            // If server already exists in public network, update it
834
            if (existing_public.length){
835
                // server was renamed
836
                if (server.name != existing_public.find('span.name').text()) {
837
                    existing_public.find('span.name').text(server.name);
838
                }
839
                // server has changed state
840
                if (server.status=='BUILD' || server.status=='ACTIVE' ||server.status=='REBOOT') {
841
                    existing_public.find("img.logo").attr("src","static/icons/machines/medium/" + server_image + '-on.png');
842
                } else {
843
                    existing_public.find("img.logo").attr("src","static/icons/machines/medium/" + server_image + '-off.png');
844
                }
845
                // server has new ips
846
                var old_ip4 = existing_public.find('span.ip4').text();
847
                var old_ip6 = existing_public.find('span.ip6').text();
848
                // the following are valid because the public ips always come in this order from the api
849
                var new_ips = get_public_ips(server);
850
                var new_ip4 = new_ips['ip4'];
851
                var new_ip6 = new_ips['ip6'];
852
                if (old_ip4 != new_ip4) {
853
                    if (new_ips['ip4'] == undefined) {
854
                        existing_public.find(".ip4-container").hide();
855
                    } else {
856
                        existing_public.find('span.ip4').text(new_ip4);
857
                    }
858
                }
859
                if (old_ip6 != new_ip6) {
860
                    if (new_ip6 == undefined) {
861
                        existing_public.find(".ip6-container").hide();
862
                    } else {
863
                        existing_public.find('span.ip6').text(new_ip6);
864
                    }
865
                }
866
                //TODO: server has changed OS
867
            }
868
            // If server does not exist in public network, create it
869
            else {
870
                var machine = $("#networks-pane #public-machine-template").clone().attr("id", "net-pub-server-" + server.id).fadeIn("slow");
871
                machine.find('span.name').text(server.name);
872
                // find and display ips
873
                var ips = get_public_ips(server);
874
                if (ips['ip4'] == undefined) {
875
                    machine.find(".ip4-container").hide();
876
                } else {
877
                    machine.find("span.ip4").text(ips['ip4']);
878
                }
879
                if (ips['ip6'] == undefined) {
880
                    machine.find(".ip6-container").hide();
881
                } else {
882
                    machine.find("span.ip6").text(ips['ip6']);
883
                }
884
                // add the proper icon
885
                if (server.status=='BUILD' || server.status=='ACTIVE' ||server.status=='REBOOT') {
886
                    machine.find("img.logo").attr("src","static/icons/machines/medium/" + server_image + '-on.png');
887
                } else {
888
                    machine.find("img.logo").attr("src","static/icons/machines/medium/" + server_image + '-off.png');
889
                }
890
                machine.appendTo("#networks-pane .public-networks .machines-list");
891
            }
892

893
            /*
894
            Now update all private networks, this does NOT check for
895
            disconnetcted servers (see above in updating private networks).
896
            Since one server may belong to more than one private networks,
897
            we follow a different approach.
898
            We check each server and add, update or leave it as it is accordingly
899
            */
900
            try {
901
                $.each(server.addresses.values, function(i,server_net) {
902
                    // find in which private networks it belongs
903
                    if (server_net.id != "public") {
904
                        var existing_private = $("#networks-pane .private-networks #net-" + server_net.id + "-server-" + server.id);
905
                        // add new server
906
                        if (!existing_private.length) {
907
                            var machine = $("#networks-pane #private-machine-template").clone().attr("id", "net-" + server_net.id + "-server-" + server.id).fadeIn("slow");
908
                            machine.find('span.name').text(server.name);
909
                            if (server.status=='BUILD' || server.status=='ACTIVE' ||server.status=='REBOOT') {
910
                                machine.find("img.logo").attr("src","static/icons/machines/medium/" + server_image + '-on.png');
911
                            } else {
912
                                machine.find("img.logo").attr("src","static/icons/machines/medium/" + server_image + '-off.png');
913
                            }
914
                            machine.appendTo("#networks-pane .private-networks #net-" + server_net.id + " .machines-list");
915
                        // hide spinners
916
                        $('#net-' + server_net.id + '.network div.status').text(NET_STATES['ACTIVE']);
917
                        $('#net-' + server_net.id + '.network img.spinner').hide();
918
                        //$('#net-' + server_net.id + '.network img.wave').attr('src','static/icons/indicators/medium/wave.gif').show();
919
                        //setTimeout("$('#net-" + server_net.id +".network img.wave').attr('src','').hide()", 3000);
920
                        }
921
                        // server was deleted
922
                        if (server.status == 'DELETED') {
923
                            existing_private.remove();
924
                        }
925
                        // server was renamed
926
                        if (server.name != existing_private.find('span.name').text()) {
927
                            existing_private.find('span.name').text(server.name);
928
                        }
929
                        // server has changed state
930
                        if (server.status=='BUILD' || server.status=='ACTIVE' ||server.status=='REBOOT') {
931
                            existing_private.find("img.logo").attr("src","static/icons/machines/medium/" + server_image + '-on.png');
932
                        } else {
933
                            existing_private.find("img.logo").attr("src","static/icons/machines/medium/" + server_image + '-off.png');
934
                        }
935
                        //TODO: server has changed OS
936
                    }
937
                });
938
            } catch (err) {
939
                try{console.info('Server ' + server.id + ' has no network addresses')}catch(err){};
940
            }
941
        });
942
    }
943

944
    $("#networks-pane #networks-container > .large-spinner").hide();
945

946
    // show all separators and hide the last one
947
    $("div.private-networks div.network div.separator").show();
948
    $("div.private-networks div.network div.separator:last").hide();
949
    // update the counters of servers in each network
950
    var nets = $('#networks-pane .network');
951
    $.each(nets, function(i,net) {
952
        $(net).find('span.machines-count').text($(net).find('.network-machine').length);
953
    });
954

955
    // the private div shows only when private networks are available
956
    if ($("div.private-networks div.network").length > 0) {
957
        $("div.private-networks").fadeIn("slow");
958
    } else {
959
        $("div.private-networks").fadeOut("slow");
960
    }
961

962
    // tag the first and last seperators for better styling
963
    $("#pub .network-machine").removeClass('first');
964
    $("#pub .network-machine").first().addClass('first');
965
    $("#pub .network-machine").removeClass('last');
966
    $("#pub .network-machine").last().addClass('last');
967
}
968

969
// indicate that the requested action was not completed
970
function display_failure(status, networkID, action, responseText) {
971
    $('#networks-container #net-'+networkID+ ' .spinner').hide();
972
    $('#networks-container #net-'+networkID+ ' .action_error .action').text(action);
973
    $('#networks-container #net-'+networkID+ ' .action_error .code').text(status);
974
    $('#networks-container #net-'+networkID+ ' .action_error .message').text(responseText);
975
    $('#networks-container #net-'+networkID+ ' .action_error').show();
976
}
977

978

979
// reposition multiple confirmation box on window resize
980
$(window).resize(function(){
981
    if (this.innerHeight - 220 < $('#networks-pane #networks-container').height())
982
        $('#networks-pane .confirm_multiple').addClass('fixed');
983
    else
984
        $('#networks-pane .confirm_multiple').removeClass('fixed');
985
});
986

987
// basic functions executed on page load
988
// hide the all of the networks contents
989
$("#networks-pane .network-contents").hide();
990
// hide the all of the firewall contents
991
$("#networks-pane .firewall-content").hide();
992
changes_since = 0; // to reload full list of servers
993
networks_changes_since= 0; // to reload full list of networks
994
// there is alway one public network to render
995
var pubNet = $("#networks-pane #public-template").clone().attr("id", "pub").fadeIn("slow");
996
pubNet.appendTo("#networks-pane .public-networks");
997
update_networks(UPDATE_INTERVAL);
998

999
//fix ie z-index bug by moving the overlays to the bottom
1000
$(document).ready(function() {
1001
    if ($.browser.msie) {
1002
        $("body").append($("#networks-wizard"));
1003
        $("body").append($("#add-machines-wizard"));
1004
    }
1005
});
1006

    
1007
</script>