Statistics
| Branch: | Tag: | Revision:

root / ui / static / synnefo.js @ e996a0af

History | View | Annotate | Download (53 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
var API_URL = "/api/v1.1";
36
var changes_since = 0, deferred = 0, update_request = false, load_request = false, pending_actions = [];
37
var flavors = [], images = [], servers = [], disks = [], cpus = [], ram = [];
38
var networks = [], networks_changes_since = 0;
39

    
40

    
41
//FIXME: authentication
42
//if cookie with value X-Auth-Token exists, set the value on the headers.
43
    $.ajaxSetup({
44
        'beforeSend': function(xhr) {
45
            //if ($.cookie("X-Auth-Token") != null) {
46
              xhr.setRequestHeader("X-Auth-Token", $.cookie("X-Auth-Token"));
47
            //} else {
48
            //    $.cookie("X-Auth-Token", "46e427d657b20defe352804f0eb6f8a2"); // set X-Auth-Token cookie
49
            //}
50
        }
51
    });
52

    
53
function ISODateString(d){
54
    //return a date in an ISO 8601 format using UTC.
55
    //do not include time zone info (Z) at the end
56
    //taken from the Mozilla Developer Center
57
    function pad(n){ return n<10 ? '0'+n : n }
58
    return  d.getUTCFullYear()+ '-' +
59
            pad(d.getUTCMonth()+1) + '-' +
60
            pad(d.getUTCDate()) + 'T' +
61
            pad(d.getUTCHours()) + ':' +
62
            pad(d.getUTCMinutes()) + ':' +
63
            pad(d.getUTCSeconds()) +'Z'
64
}
65

    
66
function parse_error(responseText, errorCode){
67
    var errors = [];
68
    try {
69
        responseObj = JSON.parse(responseText);
70
    }
71
    catch(err) {
72
        errors[0] = {'code': errorCode};
73
        return errors;
74
    }
75
    for (var err in responseObj){
76
        errors[errors.length] = responseObj[err];
77
    }
78
    return errors;
79
}
80

    
81
// indexOf prototype for IE
82
if (!Array.prototype.indexOf) {
83
  Array.prototype.indexOf = function(elt /*, from*/) {
84
    var len = this.length;
85
    var from = Number(arguments[1]) || 0;
86
    from = (from < 0)
87
         ? Math.ceil(from)
88
         : Math.floor(from);
89
    if (from < 0)
90
      from += len;
91

    
92
    for (; from < len; from++) {
93
      if (from in this &&
94
          this[from] === elt)
95
        return from;
96
    }
97
    return -1;
98
  };
99
}
100

    
101
// trim prototype for IE
102
if(typeof String.prototype.trim !== 'function') {
103
    String.prototype.trim = function() {
104
        return this.replace(/^\s+|\s+$/g, '');
105
    }
106
}
107

    
108
function update_confirmations() {
109
    // hide all confirm boxes to begin with
110
    $('#machines-pane div.confirm_single').hide();
111
    $('#machines-pane div.confirm_multiple').hide();
112
    var action_type = [];
113
    // standard view or single view
114
    if ($.cookie("view") == '0' || $.cookie("view") == '2') {
115
        for (var i=0; i<pending_actions.length; i++) {
116
            // show single confirms
117
            if (pending_actions[i][0] == reboot) {
118
                action_type = "reboot";
119
            } else if (pending_actions[i][0] == shutdown) {
120
                action_type = "shutdown";
121
            } else if (pending_actions[i][0] == start) {
122
                action_type = "start";
123
            } else if (pending_actions[i][0] == open_console) {
124
                action_type = "console";
125
            } else {
126
                action_type = "destroy";
127
            }
128
            $("#machines-pane #" + pending_actions[i][1] +
129
            " div.action-container." + action_type + " div.confirm_single").show();
130
        }
131
    }
132
    // if more than one pending action show multiple confirm box
133
    if (pending_actions.length>1 || $.cookie("view") == '1' && pending_actions.length == 1){
134
        $('#machines-pane div.confirm_multiple span.actionLen').text(pending_actions.length);
135
        $('#machines-pane div.confirm_multiple').show();
136
    }
137
}
138

    
139
function update_network_confirmations(){
140
    // hide all confirm boxes to begin with
141
    $('#networks-pane div.confirm_multiple').hide();
142

    
143
    for (var i=0;i<pending_actions.length;i++){
144
        // show single confirms depending on the action
145
        if (pending_actions[i][0] == delete_network) {
146
            $("#networks-pane div.network#net-"+pending_actions[i][1]).children('.confirm_single').show();
147
        } else if (pending_actions[i][0] == remove_server_from_network) {
148
            $("#networks-pane div.network #net-"+pending_actions[i][1]+"-server-"+pending_actions[i][2]).children('.confirm_single').show();
149
        } // else {}
150
    }
151

    
152
    // if more than one pending action show multiple confirm box
153
    if (pending_actions.length > 1){
154
        $('#networks-pane div.confirm_multiple span.actionLen').text(pending_actions.length);
155
        $('#networks-pane div.confirm_multiple').show();
156
    }
157
}
158

    
159
function list_view() {
160
    changes_since = 0; // to reload full list
161
    pending_actions = []; // clear pending actions
162
    update_confirmations();
163
    clearTimeout(deferred);    // clear old deferred calls
164
    try {
165
        update_request.abort(); // cancel pending ajax updates
166
        load_request.abort();
167
    }catch(err){}
168
    $.cookie("view", '1'); // set list cookie
169
    uri = $("a#list").attr("href");
170
    load_request = $.ajax({
171
        url: uri,
172
        type: "GET",
173
        timeout: TIMEOUT,
174
        dataType: "html",
175
        error: function(jqXHR, textStatus, errorThrown) {
176
            return false;
177
        },
178
        success: function(data, textStatus, jqXHR) {
179
            $("a#list")[0].className += ' activelink';
180
            $("a#standard")[0].className = '';
181
            $("a#single")[0].className = '';
182
            $("div#machinesview").html(data);
183
        }
184
    });
185
    return false;
186
}
187

    
188
function single_view() {
189
    changes_since = 0; // to reload full list
190
    pending_actions = []; // clear pending actions
191
    update_confirmations();
192
    clearTimeout(deferred);    // clear old deferred calls
193
    try {
194
        update_request.abort(); // cancel pending ajax updates
195
        load_request.abort();
196
    }catch(err){}
197
    $.cookie("view", '2'); // set list cookie
198
    uri = $("a#single").attr("href");
199
    load_request = $.ajax({
200
        url: uri,
201
        type: "GET",
202
        timeout: TIMEOUT,
203
        dataType: "html",
204
        error: function(jqXHR, textStatus, errorThrown) {
205
            return false;
206
        },
207
        success: function(data, textStatus, jqXHR) {
208
            $("a#single")[0].className += ' activelink';
209
            $("a#standard")[0].className = '';
210
            $("a#list")[0].className = '';
211
            $("div#machinesview").html(data);
212
        }
213
    });
214
    return false;
215
}
216

    
217
function standard_view() {
218
    changes_since = 0; // to reload full list
219
    pending_actions = []; // clear pending actions
220
    update_confirmations();
221
    clearTimeout(deferred);    // clear old deferred calls
222
    try {
223
        update_request.abort() // cancel pending ajax updates
224
        load_request.abort();
225
    }catch(err){}
226
    $.cookie("view", '0');
227
    uri = $("a#standard").attr("href");
228
    load_request = $.ajax({
229
        url: uri,
230
        type: "GET",
231
        timeout: TIMEOUT,
232
        dataType: "html",
233
        error: function(jqXHR, textStatus, errorThrown) {
234
            return false;
235
        },
236
        success: function(data, textStatus, jqXHR) {
237
            $("a#standard")[0].className += ' activelink';
238
            $("a#list")[0].className = '';
239
            $("a#single")[0].className = '';
240
            $("div#machinesview").html(data);
241
        }
242
    });
243
    return false;
244
}
245

    
246
function choose_view() {
247
    if ($.cookie("view")=='1') {
248
        list_view();
249
    } else if ($.cookie("view")=='2'){
250
        single_view();
251
    } else {
252
        standard_view();
253
    }
254
}
255

    
256
// return value from metadata key "OS", if it exists
257
function os_icon(metadata) {
258
    if (!metadata) {
259
        return 'unknown';
260
    }
261
    if (metadata.values.OS == undefined || metadata.values.OS == '') {
262
        return 'unknown';
263
    } else {
264
        if (os_icons.indexOf(metadata.values.OS) == -1) {
265
            return 'unknown';
266
        } else {
267
            return metadata.values.OS;
268
        }
269
    }
270
}
271

    
272
function os_icon_from_value(metadata) {
273
    if (!metadata) {
274
        return 'unknown';
275
    }
276
if (metadata == undefined || metadata == '') {
277
        return 'unknown';
278
    } else {
279
        if (os_icons.indexOf(metadata) == -1) {
280
            return 'unknown';
281
        } else {
282
            return metadata;
283
        }
284
    }
285
}
286

    
287
// get and show a list of running and terminated machines
288
function update_vms(interval) {
289
    try{ console.info('updating machines'); } catch(err){}
290
    var uri= API_URL + '/servers/detail';
291

    
292
    if (changes_since != 0)
293
        uri+='?changes-since='+changes_since
294

    
295
    update_request = $.ajax({
296
        cache: false,
297
        url: uri,
298
        type: "GET",
299
        timeout: TIMEOUT,
300
        dataType: "json",
301
        error: function(jqXHR, textStatus, errorThrown) {
302
            // don't forget to try again later
303
            if (interval) {
304
                clearTimeout(deferred);    // clear old deferred calls
305
                deferred = setTimeout(function() {update_vms(interval);},interval,interval);
306
            }
307
            // as for now, just show an error message
308
            try { console.info('update_vms errback:' + jqXHR.status ) } catch(err) {}
309
            try {
310
                ajax_error(jqXHR.status, undefined, 'Update VMs', jqXHR.responseText);
311
            } catch(err) {
312
                ajax_error(0, undefined, 'Update VMs', jqXHR.responseText);
313
            }
314
            return false;
315
            },
316
        success: function(data, textStatus, jqXHR) {
317
            // create changes_since string if necessary
318
            if (jqXHR.getResponseHeader('Date') != null){
319
                changes_since_date = new Date(jqXHR.getResponseHeader('Date'));
320
                changes_since = ISODateString(changes_since_date);
321
            }
322

    
323
            if (interval) {
324
                clearTimeout(deferred);    // clear old deferred calls
325
                deferred = setTimeout(function() {update_vms(interval);},interval,interval);
326
            }
327

    
328
            if (jqXHR.status == 200 || jqXHR.status == 203) {
329
                try {
330
                    servers = data.servers.values;
331
                    jQuery.parseJSON(data);
332
                    update_machines_view(data);
333
                } catch(err) { ajax_error('400', undefined, 'Update VMs', jqXHR.responseText);}
334
            } else if (jqXHR.status != 304){
335
                try { console.info('update_vms callback:' + jqXHR.status ) } catch(err) {}
336
                /*
337
                FIXME:  Here it should return the error, however Opera does not support 304.
338
                        Instead 304 it returns 0. To dealt with this we treat 0 as an
339
                        304, which should be corrected (Bug #317).
340
                */
341
                //ajax_error(jqXHR.status, undefined, 'Update VMs', jqXHR.responseText);
342
            }
343
            return false;
344
        }
345
    });
346
    return false;
347
}
348

    
349
// get a list of running and terminated machines, used in network view
350
function update_networks(interval) {
351
    try{ console.info('updating networks'); } catch(err){}
352
    var uri= API_URL + '/servers/detail';
353

    
354
    if (changes_since != 0)
355
        uri+='?changes-since='+changes_since
356

    
357
    update_request = $.ajax({
358
        cache: false,
359
        url: uri,
360
        type: "GET",
361
        timeout: TIMEOUT,
362
        dataType: "json",
363
        error: function(jqXHR, textStatus, errorThrown) {
364
            // don't forget to try again later
365
            if (interval) {
366
                clearTimeout(deferred);    // clear old deferred calls
367
                deferred = setTimeout(function() {update_networks(interval);},interval,interval);
368
            }
369
            // as for now, just show an error message
370
            try { console.info('update_networks errback:' + jqXHR.status ) } catch(err) {}
371
            try {
372
                ajax_error(jqXHR.status, undefined, 'Update networks', jqXHR.responseText);
373
            } catch(err) {
374
                ajax_error(0, undefined, 'Update networks', jqXHR.responseText);
375
            }
376
            return false;
377
            },
378
        success: function(data, textStatus, jqXHR) {
379
            // create changes_since string if necessary
380
            if (jqXHR.getResponseHeader('Date') != null){
381
                changes_since_date = new Date(jqXHR.getResponseHeader('Date'));
382
                changes_since = ISODateString(changes_since_date);
383
            }
384

    
385
            if (interval) {
386
                clearTimeout(deferred);    // clear old deferred calls
387
                deferred = setTimeout(function() {update_networks(interval);},interval,interval);
388
            }
389

    
390
            if (jqXHR.status == 200 || jqXHR.status == 203) {
391
                try {
392
                    servers = data.servers.values;
393
                    jQuery.parseJSON(data);
394
                    update_network_names(data);
395
                } catch(err) { ajax_error('400', undefined, 'Update networks', jqXHR.responseText);}
396
            } else if (jqXHR.status == 304) {
397
                update_network_names();
398
            }
399
            else {
400
                try { console.info('update_networks callback:' + jqXHR.status ) } catch(err) {}
401
                /*
402
                FIXME:  Here it should return the error, however Opera does not support 304.
403
                        Instead 304 it returns 0. To dealt with this we treat 0 as an
404
                        304, which should be corrected (Bug #317).
405
                */
406
                //ajax_error(jqXHR.status, undefined, 'Update networks', jqXHR.responseText);
407
                update_network_names();
408
            }
409
            return false;
410
        }
411
    });
412
    return false;
413
}
414

    
415
// get and show a list of public and private networks
416
function update_network_names(servers_data) {
417
    try{ console.info('updating network names'); } catch(err){}
418
    var uri= API_URL + '/networks/detail';
419

    
420
    if (networks_changes_since != 0)
421
        //FIXME: Comment out the following, until metadata do not 304 when changed
422
        uri+='?changes-since=' + networks_changes_since
423

    
424
    update_request = $.ajax({
425
        cache: false,
426
        url: uri,
427
        type: "GET",
428
        timeout: TIMEOUT,
429
        dataType: "json",
430
        error: function(jqXHR, textStatus, errorThrown) {
431
            // as for now, just show an error message
432
            try {
433
                console.info('update_network names errback:' + jqXHR.status )
434
            } catch(err) {}
435
            try {
436
                ajax_error(jqXHR.status, undefined, 'Update network names', jqXHR.responseText);
437
            } catch(err) {
438
                ajax_error(0, undefined, 'Update network names', jqXHR.responseText);
439
            }
440
            return false;
441
            },
442
        success: function(data, textStatus, jqXHR) {
443
            // create changes_since string if necessary
444
            if (jqXHR.getResponseHeader('Date') != null){
445
                changes_since_date = new Date(jqXHR.getResponseHeader('Date'));
446
                networks_changes_since = ISODateString(changes_since_date);
447
            }
448

    
449
            if (jqXHR.status == 200 || jqXHR.status == 203) {
450
                try {
451
                    networks = data.networks.values;
452
                    jQuery.parseJSON(data);
453
                    update_networks_view(servers_data, data);
454
                } catch(err) {
455
                    ajax_error('400', undefined, 'Update network names', jqXHR.responseText);
456
                }
457
            } else if (jqXHR.status == 304) {
458
                update_networks_view(servers_data);
459
            } else if (jqXHR.status != 304){
460
                try { console.info('update_network_names callback:' + jqXHR.status ) } catch(err) {}
461
                /*
462
                FIXME:  Here it should return the error, however Opera does not support 304.
463
                        Instead 304 it returns 0. To dealt with this we treat 0 as an
464
                        304, which should be corrected (Bug #317).
465
                */
466
                //ajax_error(jqXHR.status, undefined, 'Update network names', jqXHR.responseText);
467
                update_networks_view(servers_data);
468
            }
469
            return false;
470
        }
471
    });
472
    return false;
473
}
474

    
475
// get and show a list of available standard and custom images
476
function update_images() {
477
    $.ajax({
478
        url: API_URL + '/images/detail',
479
        type: "GET",
480
        //async: false,
481
        dataType: "json",
482
        timeout: TIMEOUT,
483
        error: function(jqXHR, textStatus, errorThrown) {
484
                    try {
485
                        ajax_error(jqXHR.status, undefined, 'Update Images', jqXHR.responseText);
486
                    } catch(err) {
487
                        ajax_error(0, undefined, 'Update Images', jqXHR.responseText);
488
                    }
489
                },
490
        success: function(data, textStatus, jqXHR) {
491
            try {
492
                images = data.images.values;
493
                jQuery.parseJSON(data);
494
                update_wizard_images();
495
            } catch(err){
496
                ajax_error("NO_IMAGES");
497
            }
498
        }
499
    });
500
    return false;
501
}
502

    
503
function update_wizard_images() {
504
    if ($("ul#standard-images li").toArray().length + $("ul#custom-images li").toArray().length == 0) {
505
        $.each(images, function(i,image){
506
            var img = $('#image-template').clone().attr("id","img-"+image.id).fadeIn("slow");
507
            img.find("label").attr('for',"img-radio-" + image.id);
508
            img.find(".image-title").text(image.name);
509
            if (image.metadata) {
510
                if (image.metadata.values.description != undefined) {
511
                    img.find(".description").text(image.metadata.values.description);
512
                }
513
                if (image.metadata.values.size != undefined) {
514
                    img.find("#size").text(image.metadata.values.size);
515
                }
516
            }
517
            img.find("input.radio").attr('id',"img-radio-" + image.id);
518
            if (i==0) img.find("input.radio").attr("checked","checked");
519
            var image_logo = os_icon(image.metadata);
520
            img.find("img.image-logo").attr('src','static/icons/os/'+image_logo+'.png');
521
            if (image.metadata) {
522
                if (image.metadata.values.serverId != undefined) {
523
                    img.appendTo("ul#custom-images");
524
                } else {
525
                    img.appendTo("ul#standard-images");
526
                }
527
            } else {
528
                img.appendTo("ul#standard-images");
529
            }
530
        });
531
    }
532
}
533

    
534
function update_wizard_flavors(){
535
    // sliders for selecting VM flavor
536
    $("#cpu:range").rangeinput({min:0,
537
                               value:0,
538
                               step:1,
539
                               progress: true,
540
                               max:cpus.length-1});
541

    
542
    $("#storage:range").rangeinput({min:0,
543
                               value:0,
544
                               step:1,
545
                               progress: true,
546
                               max:disks.length-1});
547

    
548
    $("#ram:range").rangeinput({min:0,
549
                               value:0,
550
                               step:1,
551
                               progress: true,
552
                               max:ram.length-1});
553
    $("#small").click();
554

    
555
    // update the indicators when sliding
556
    $("#cpu:range").data().rangeinput.onSlide(function(event,value){
557
        $("#cpu-indicator")[0].value = cpus[Number(value)];
558
        $("#cpu-indicator").addClass('selectedrange');
559
    });
560
    $("#cpu:range").data().rangeinput.change(function(event,value){
561
        $("#cpu-indicator")[0].value = cpus[Number(value)];
562
        $("#custom").click();
563
        $("#cpu-indicator").removeClass('selectedrange');
564
    });
565
    $("#ram:range").data().rangeinput.onSlide(function(event,value){
566
        $("#ram-indicator")[0].value = ram[Number(value)];
567
        $("#ram-indicator").addClass('selectedrange');
568
    });
569
    $("#ram:range").data().rangeinput.change(function(event,value){
570
        $("#ram-indicator")[0].value = ram[Number(value)];
571
        $("#custom").click();
572
        $("#ram-indicator").removeClass('selectedrange');
573
    });
574
    $("#storage:range").data().rangeinput.onSlide(function(event,value){
575
        $("#storage-indicator")[0].value = disks[Number(value)];
576
        $("#storage-indicator").addClass('selectedrange');
577
    });
578
    $("#storage:range").data().rangeinput.change(function(event,value){
579
        $("#storage-indicator")[0].value = disks[Number(value)];
580
        $("#custom").click();
581
        $("#storage-indicator").removeClass('selectedrange');
582
    });
583
}
584

    
585
Array.prototype.unique = function () {
586
    var r = new Array();
587
    o:for(var i = 0, n = this.length; i < n; i++)
588
    {
589
        for(var x = 0, y = r.length; x < y; x++)
590
        {
591
            if(r[x]==this[i])
592
            {
593
                continue o;
594
            }
595
        }
596
        r[r.length] = this[i];
597
    }
598
    return r;
599
}
600

    
601
// get and configure flavor selection
602
function update_flavors() {
603
    $.ajax({
604
        url: API_URL + '/flavors/detail',
605
        type: "GET",
606
        //async: false,
607
        dataType: "json",
608
        timeout: TIMEOUT,
609
        error: function(jqXHR, textStatus, errorThrown) {
610
            try {
611
                ajax_error(jqXHR.status, undefined, 'Update Flavors', jqXHR.responseText);
612
            } catch (err) {
613
                ajax_error(err);
614
            }
615
            // start updating vm list
616
            update_vms(UPDATE_INTERVAL);
617
        },
618
        success: function(data, textStatus, jqXHR) {
619

    
620
            try {
621
                flavors = data.flavors.values;
622
                jQuery.parseJSON(data);
623
                $.each(flavors, function(i, flavor) {
624
                    cpus[i] = flavor['cpu'];
625
                    disks[i] = flavor['disk'];
626
                    ram[i] = flavor['ram'];
627
                });
628
                cpus = cpus.unique();
629
                disks = disks.unique();
630
                ram = ram.unique();
631
                update_wizard_flavors();
632
            } catch(err){
633
                ajax_error("NO_FLAVORS");
634
            }
635
            // start updating vm list
636
            update_vms(UPDATE_INTERVAL);
637
        }
638
    });
639
    return false;
640
}
641

    
642
// return flavorRef from cpu, disk, ram values
643
function identify_flavor(cpu, disk, ram){
644
    for (i=0;i<flavors.length;i++){
645
        if (flavors[i]['cpu'] == cpu && flavors[i]['disk']==disk && flavors[i]['ram']==ram) {
646
            return flavors[i]['id']
647
        }
648
    }
649
    return 0;
650
}
651

    
652
// return image entry from imageRef
653
function get_image(imageRef) {
654
    for (i=0;i<images.length;i++){
655
        if (images[i]['id'] == imageRef) {
656
            return images[i];
657
        }
658
    }
659
    return 0;
660
}
661

    
662
// return machine entry from serverID
663
function get_machine(serverID) {
664
    for (i=0;i<servers.length;i++){
665
        if (servers[i]['id'] == serverID) {
666
            return servers[i];
667
        }
668
    }
669
    return 0;
670
}
671

    
672
// update the actions in icon view, per server
673
function update_iconview_actions(serverID, server_status) {
674
    if ($.cookie("view")=='2') {
675
        // remove .disable from all actions to begin with
676
        $('#machinesview-single #' + serverID + ' div.single-action').show();
677
        // decide which actions should be disabled
678
        for (current_action in actions) {
679
            if (actions[current_action].indexOf(server_status) == -1 ) {
680
                $('#machinesview-single #' + serverID + ' div.action-' + current_action).hide();
681
            }
682
        }
683
    } else {
684
        // remove .disable from all actions to begin with
685
        $('#machinesview-icon.standard #' + serverID + ' div.actions').find('a').removeClass('disabled');
686
        // decide which actions should be disabled
687
        for (current_action in actions) {
688
            if (actions[current_action].indexOf(server_status) == -1 ) {
689
                $('#machinesview-icon.standard #' + serverID + ' a.action-' + current_action).addClass('disabled');
690
            }
691
        }
692
    }
693
}
694

    
695
// update the actions in list view
696
function update_listview_actions() {
697
    var states = [];
698
    var on = [];
699
    var checked = $("table.list-machines tbody input[type='checkbox']:checked");
700
    // disable all actions to begin with
701
    $('#machinesview .list div.actions').children().removeClass('enabled');
702

    
703
    // are there multiple machines selected?
704
    if (checked.length>1)
705
        states[0] = 'multiple';
706

    
707
    // check the states of selected machines
708
    checked.each(function(i,checkbox) {
709
        states[states.length] = checkbox.className;
710
        var ip = $("#" + checkbox.id.replace('input-','') + ".ip span.public").text();
711
        if (ip.replace('undefined','').length)
712
            states[states.length] = 'network';
713
    });
714

    
715
    // decide which actions should be enabled
716
    for (a in actions) {
717
        var enabled = false;
718
        for (var s =0; s<states.length; s++) {
719
            if (actions[a].indexOf(states[s]) != -1 ) {
720
                enabled = true;
721
            } else {
722
                enabled = false;
723
                break;
724
            }
725
        }
726
        if (enabled)
727
            on[on.length]=a;
728
    }
729
    // enable those actions
730
    for (action in on) {
731
        $("#action-" + on[action]).addClass('enabled');
732
    }
733
}
734

    
735
//create server action
736
function create_vm(machineName, imageRef, flavorRef){
737
    var image_logo = os_icon(get_image(imageRef).metadata);
738
    var uri = API_URL + '/servers';
739
    var payload = {
740
        "server": {
741
            "name": machineName,
742
            "imageRef": imageRef,
743
            "flavorRef" : flavorRef,
744
            "metadata" : {
745
                "OS" : image_logo
746
            }
747
        }
748
    };
749

    
750
    $.ajax({
751
    url: uri,
752
    type: "POST",
753
    contentType: "application/json",
754
    dataType: "json",
755
    data: JSON.stringify(payload),
756
    timeout: TIMEOUT,
757
    error: function(jqXHR, textStatus, errorThrown) {
758
                // close wizard and show error box
759
                $('#machines-pane a#create').data('overlay').close();
760
                    try {
761
                        display_failure(jqXHR.status, serverID, 'Create VM', jqXHR.responseText);
762
                    } catch(err) {
763
                        display_failure(0, serverID, 'Create VM', jqXHR.responseText);
764
                    }
765
           },
766
    success: function(data, textStatus, jqXHR) {
767
                if ( jqXHR.status == '202') {
768
                    ajax_success("CREATE_VM_SUCCESS", data.server.adminPass);
769
                } else {
770
                    // close wizard and show error box
771
                    $('#machines-pane a#create').data('overlay').close();
772
                    ajax_error(jqXHR.status, undefined, 'Create VM', jqXHR.responseText);
773
                }
774
            }
775
    });
776
}
777

    
778
// reboot action
779
function reboot(serverIDs){
780
    if (!serverIDs.length){
781
        //ajax_success('DEFAULT');
782
        return false;
783
    }
784
    // ajax post reboot call
785
    var payload = {
786
        "reboot": {"type" : "HARD"}
787
    };
788

    
789
    var serverID = serverIDs.pop();
790

    
791
    $.ajax({
792
        url: API_URL + '/servers/' + serverID + '/action',
793
        type: "POST",
794
        contentType: "application/json",
795
        dataType: "json",
796
        data: JSON.stringify(payload),
797
        timeout: TIMEOUT,
798
        error: function(jqXHR, textStatus, errorThrown) {
799
                    // in machine views
800
                    if ( $.cookie("pane") == 0) {
801
                        try {
802
                            display_failure(jqXHR.status, serverID, 'Reboot', jqXHR.responseText);
803
                        } catch (err) {
804
                            display_failure(0, serverID, 'Reboot', jqXHR.responseText);
805
                        }
806
                    }
807
                    // in network view
808
                    else {
809
                        try {
810
                            display_reboot_failure(jqXHR.status, serverID, jqXHR.responseText);
811
                        } catch (err) {
812
                            display_reboot_failure(0, serverID, jqXHR.responseText);
813
                        }
814
                    }
815
                },
816
        success: function(data, textStatus, jqXHR) {
817
                    if ( jqXHR.status == '202') {
818
                        try {
819
                            console.info('rebooted ' + serverID);
820
                        } catch(err) {}
821
                        // indicate that the action succeeded
822
                        // in machine views
823
                        if ( $.cookie("pane") == 0) {
824
                            display_success(serverID);
825
                        }
826
                        // in network view
827
                        else {
828
                            display_reboot_success(serverID);
829
                        }
830
                        // continue with the rest of the servers
831
                        reboot(serverIDs);
832
                    } else {
833
                        ajax_error(jqXHR.status, serverID, 'Reboot', jqXHR.responseText);
834
                    }
835
                }
836
    });
837
    return false;
838
}
839

    
840
// shutdown action
841
function shutdown(serverIDs) {
842
    if (!serverIDs.length){
843
        //ajax_success('DEFAULT');
844
        return false;
845
    }
846
    // ajax post shutdown call
847
    var payload = {
848
        "shutdown": {}
849
    };
850

    
851
    var serverID = serverIDs.pop();
852

    
853
    $.ajax({
854
        url: API_URL + '/servers/' + serverID + '/action',
855
        type: "POST",
856
        contentType: "application/json",
857
        dataType: "json",
858
        data: JSON.stringify(payload),
859
        timeout: TIMEOUT,
860
        error: function(jqXHR, textStatus, errorThrown) {
861
                    try {
862
                        display_failure(jqXHR.status, serverID, 'Shutdown', jqXHR.responseText);
863
                    } catch(err) {
864
                        display_failure(0, serverID, 'Shutdown', jqXHR.responseText);
865
                    }
866
                },
867
        success: function(data, textStatus, jqXHR) {
868
                    if ( jqXHR.status == '202') {
869
                        try {
870
                            console.info('suspended ' + serverID);
871
                        } catch(err) {}
872
                        // indicate that the action succeeded
873
                        display_success(serverID);
874
                        // continue with the rest of the servers
875
                        shutdown(serverIDs);
876
                    } else {
877
                        ajax_error(jqXHR.status, serverID, 'Shutdown', jqXHR.responseText);
878
                    }
879
                }
880
    });
881
    return false;
882
}
883

    
884
// destroy action
885
function destroy(serverIDs) {
886
    if (!serverIDs.length){
887
        //ajax_success('DEFAULT');
888
        return false;
889
    }
890
    // ajax post destroy call can have an empty request body
891
    var payload = {};
892

    
893
    var serverID = serverIDs.pop();
894

    
895
    $.ajax({
896
        url: API_URL + '/servers/' + serverID,
897
        type: "DELETE",
898
        contentType: "application/json",
899
        dataType: "json",
900
        data: JSON.stringify(payload),
901
        timeout: TIMEOUT,
902
        error: function(jqXHR, textStatus, errorThrown) {
903
                    try {
904
                        display_failure(jqXHR.status, serverID, 'Destroy', jqXHR.responseText);
905
                    } catch(err) {
906
                        display_failure(0, serverID, 'Destroy', jqXHR.responseText);
907
                    }
908
                },
909
        success: function(data, textStatus, jqXHR) {
910
                    if ( jqXHR.status == '204') {
911
                        try {
912
                            console.info('destroyed ' + serverID);
913
                        } catch (err) {}
914
                        // indicate that the action succeeded
915
                        display_success(serverID);
916
                        // continue with the rest of the servers
917
                        destroy(serverIDs);
918
                    } else {
919
                        ajax_error(jqXHR.status, serverID, 'Destroy', jqXHR.responseText);
920
                    }
921
                }
922
    });
923
    return false;
924
}
925

    
926
// start action
927
function start(serverIDs){
928
    if (!serverIDs.length){
929
        //ajax_success('DEFAULT');
930
        return false;
931
    }
932
    // ajax post start call
933
    var payload = {
934
        "start": {}
935
    };
936

    
937
    var serverID = serverIDs.pop();
938

    
939
    $.ajax({
940
        url: API_URL + '/servers/' + serverID + '/action',
941
        type: "POST",
942
        contentType: "application/json",
943
        dataType: "json",
944
        data: JSON.stringify(payload),
945
        timeout: TIMEOUT,
946
        error: function(jqXHR, textStatus, errorThrown) {
947
                    try {
948
                        display_failure(jqXHR.status, serverID, 'Start', jqXHR.responseText);
949
                    } catch(err) {
950
                        display_failure(0, serverID, 'Start', jqXHR.responseText);
951
                    }
952
                },
953
        success: function(data, textStatus, jqXHR) {
954
                    if ( jqXHR.status == '202') {
955
                        try {
956
                            console.info('started ' + serverID);
957
                        } catch(err) {}
958
                        // indicate that the action succeeded
959
                        display_success(serverID);
960
                        // continue with the rest of the servers
961
                        start(serverIDs);
962
                    } else {
963
                        ajax_error(jqXHR.status, serverID, 'Start', jqXHR.responseText);
964
                    }
965
                }
966
    });
967
    return false;
968
}
969

    
970
// Show VNC console
971
function vnc_attachment(host, port, password) {
972
    // FIXME: Must be made into parameters, in settings.py
973
    //vnc = open("", "displayWindow",
974
    //    "status=yes,toolbar=yes,menubar=yes");
975
    vd = document.open("application/x-vnc");
976

    
977
    vd.writeln("[connection]");
978
    vd.writeln("host=" + host);
979
    vd.writeln("port=" + port);
980
    vd.writeln("password=" + password);
981

    
982
    vd.close();
983
}
984

    
985
// Show VNC console
986
function show_vnc_console(serverID, serverName, serverIP, host, port, password) {
987
    var params_url = '?machine=' + serverName + '&host_ip=' + serverIP + '&host=' + host + '&port=' + port + '&password=' + password;
988
    var params_window = 'scrollbars=no,' +
989
                        'menubar=no,' +
990
                        'toolbar=no,' +
991
                        'status=no,' +
992
                        'top=0,' +
993
                        'left=0,' +
994
                        'height=' + screen.height + ',' +
995
                        'width=' + screen.width + ',' +
996
                        'fullscreen=yes';
997

    
998
    window.open('machines/console' + params_url, 'formresult' + serverID, params_window);
999

    
1000
    // Restore os icon in list view
1001
    osIcon = $('#'+serverID).parent().parent().find('.list-logo');
1002
    osIcon.attr('src',osIcon.attr('os'));
1003
    return false;
1004
}
1005

    
1006
// console action
1007
function open_console(serverIDs){
1008
    if (!serverIDs.length){
1009
        //ajax_success('DEFAULT');
1010
        return false;
1011
    }
1012
    // ajax post start call
1013
    var payload = {
1014
        "console": {"type": "vnc"}
1015
    };
1016

    
1017
    var serverID = serverIDs.pop();
1018

    
1019
    var machine = get_machine(serverID);
1020
    var serverName = machine.name;
1021
    var serverIP = machine.addresses.values[0].values[0].addr;
1022

    
1023
    $.ajax({
1024
        url: API_URL + '/servers/' + serverID + '/action',
1025
        type: "POST",
1026
        contentType: "application/json",
1027
        dataType: "json",
1028
        data: JSON.stringify(payload),
1029
        timeout: TIMEOUT,
1030
        error: function(jqXHR, textStatus, errorThrown) {
1031
                    try {
1032
                        display_failure(jqXHR.status, serverID, 'Console', jqXHR.responseText);
1033
                    } catch(err) {
1034
                        display_failure(0, serverID, 'Console', jqXHR.responseText);
1035
                    }
1036
                },
1037
        success: function(data, textStatus, jqXHR) {
1038
                    if ( jqXHR.status == '200') {
1039
                        try {
1040
                            console.info('got_console ' + serverID);
1041
                        } catch(err) {}
1042
                        // indicate that the action succeeded
1043
                        // show_vnc_console(serverID, serverName, serverIP,
1044
                        // data.console.host,data.console.port,data.console.password);
1045
                        show_vnc_console(serverID, serverName, serverIP,
1046
                                         data.console.host,data.console.port,data.console.password);
1047
                        display_success(serverID);
1048
                        // hide spinner
1049
                        $('#' + serverID + ' .spinner').hide();
1050
                        // continue with the rest of the servers
1051
                        open_console(serverIDs);
1052
                    } else {
1053
                        ajax_error(jqXHR.status, serverID, 'Console', jqXHR.responseText);
1054
                    }
1055
                }
1056
    });
1057
    return false;
1058
}
1059

    
1060
// rename server
1061
function rename(serverID, serverName){
1062
    if (!serverID.length){
1063
        //ajax_success('DEFAULT');
1064
        return false;
1065
    }
1066
    // ajax post rename call
1067
    var payload = {
1068
        "server": {"name": serverName}
1069
    };
1070

    
1071
    $.ajax({
1072
        url: API_URL + '/servers/' + serverID,
1073
        type: "PUT",
1074
        contentType: "application/json",
1075
        dataType: "json",
1076
        data: JSON.stringify(payload),
1077
        timeout: TIMEOUT,
1078
        error: function(jqXHR, textStatus, errorThrown) {
1079
                    try {
1080
                        display_failure(jqXHR.status, serverID, 'Rename', jqXHR.responseText);
1081
                    } catch(err) {
1082
                        display_failure(0, serverID, 'Rename', jqXHR.responseText);
1083
                    }
1084
                },
1085
        success: function(data, textStatus, jqXHR) {
1086
                    if ( jqXHR.status == '204' || jqXHR.status == '1223') {
1087
                        try {
1088
                            console.info('renamed ' + serverID);
1089
                        } catch(err) {}
1090
                        // indicate that the action succeeded
1091
                        display_success(serverID);
1092
                    } else {
1093
                        ajax_error(jqXHR.status, serverID, 'Rename', jqXHR.responseText);
1094
                    }
1095
                }
1096
    });
1097
    return false;
1098
}
1099

    
1100
// get server metadata
1101
function get_metadata(serverID, keys_only) {
1102
    $.ajax({
1103
        url: API_URL + '/servers/' + serverID + '/meta',
1104
        cache: false,
1105
        type: "GET",
1106
        //async: false,
1107
        dataType: "json",
1108
        timeout: TIMEOUT,
1109
        error: function(jqXHR, textStatus, errorThrown) {
1110
            try {
1111
                // close wizard and show error box
1112
                $("a#metadata-scrollable").data('overlay').close();
1113
                ajax_error(jqXHR.status, undefined, 'Get metadata', jqXHR.responseText);
1114
            } catch (err) {
1115
                ajax_error(err);
1116
            }
1117
        },
1118
        success: function(data, textStatus, jqXHR) {
1119
            // to list the new results in the edit dialog
1120
            if (keys_only) {
1121
                list_metadata_keys(serverID, data.metadata.values);
1122
            } else {
1123
                list_metadata(data);
1124
                list_metadata_keys(serverID, data.metadata.values);
1125
            }
1126
            //hide spinner
1127
            $('#metadata-wizard .large-spinner').hide();
1128
        }
1129
    });
1130
    return false;
1131
}
1132

    
1133
// delete metadata key-value pair
1134
function delete_metadata(serverID, meta_key) {
1135
    $.ajax({
1136
        url: API_URL + '/servers/' + serverID + '/meta/' + meta_key,
1137
        type: "DELETE",
1138
        //async: false,
1139
        dataType: "json",
1140
        timeout: TIMEOUT,
1141
        error: function(jqXHR, textStatus, errorThrown) {
1142
            try {
1143
                // close wizard and show error box
1144
                $("a#metadata-scrollable").data('overlay').close();
1145
                ajax_error(jqXHR.status, undefined, 'Delete metadata', jqXHR.responseText);
1146
            } catch (err) {
1147
                ajax_error(err);
1148
            }
1149
        },
1150
        success: function(data, textStatus, jqXHR) {
1151
                    // success: Do nothing, the UI is already updated
1152
        }
1153
    });
1154
    return false;
1155
}
1156

    
1157
// add metadata key-value pair
1158
function update_metadata(serverID, meta_key, meta_value) {
1159
    var payload = {
1160
        "meta": {
1161
        }
1162
    };
1163
    payload["meta"][meta_key] = meta_value;
1164

    
1165
    $.ajax({
1166
        url: API_URL + '/servers/' + serverID + '/meta/' + meta_key,
1167
        type: "PUT",
1168
        contentType: "application/json",
1169
        dataType: "json",
1170
        data: JSON.stringify(payload),
1171
        timeout: TIMEOUT,
1172
        error: function(jqXHR, textStatus, errorThrown) {
1173
            try {
1174
                // close wizard and show error box
1175
                $("a#metadata-scrollable").data('overlay').close();
1176
                ajax_error(jqXHR.status, undefined, 'add metadata', jqXHR.responseText);
1177
            } catch (err) {
1178
                ajax_error(err);
1179
            }
1180
        },
1181
        success: function(data, textStatus, jqXHR) {
1182
            // success: Update icons if meta key is OS
1183
            if (meta_key == "OS") {
1184
                $("#metadata-wizard .machine-icon").attr("src","static/icons/machines/small/" + os_icon_from_value(meta_value) + '-' + $("#metadata-wizard div#on-off").text() + '.png');
1185
                $("#machinesview-icon").find("div#" + serverID).find("img.logo").attr("src", "static/icons/machines/medium/" + os_icon_from_value(meta_value) + '-' + $("#metadata-wizard div#on-off").text() + '.png');
1186
            }
1187
        }
1188
    });
1189
    return false;
1190
}
1191

    
1192
// create network
1193
function create_network(networkName){
1194
    // ajax post start call
1195
    var payload = {
1196
        "network": { "name": networkName }
1197
    };
1198

    
1199
    $.ajax({
1200
        url: API_URL + '/networks',
1201
        type: "POST",
1202
        contentType: "application/json",
1203
        dataType: "json",
1204
        data: JSON.stringify(payload),
1205
        timeout: TIMEOUT,
1206
        error: function(jqXHR, textStatus, errorThrown) {
1207
            try {
1208
                // close wizard and show error box
1209
                $("a#networkscreate").overlay().close();
1210
                ajax_error(jqXHR.status, undefined, 'Create network', jqXHR.responseText);
1211
            } catch (err) {
1212
                ajax_error(err);
1213
            }
1214
        },
1215
        success: function(data, textStatus, jqXHR) {
1216
            if ( jqXHR.status == '202') {
1217
                try {
1218
                    console.info('created network ' + networkName);
1219
                } catch(err) {}
1220
                /*
1221
                On success of this call nothing happens.
1222
                When the UI gets the first update containing the created server,
1223
                the creation wizard is closed and the new network is inserted
1224
                to the DOM. This is done in update_networks_view()
1225
                */
1226
            } else {
1227
                // close wizard and show error box
1228
                $("a#networkscreate").overlay().close();
1229
                ajax_error(jqXHR.status, undefined, 'Create network', jqXHR.responseText);
1230
            }
1231
        }
1232
    });
1233
    return false;
1234
}
1235

    
1236
// rename network
1237
function rename_network(networkID, networkName){
1238
    if (!networkID.length){
1239
        //ajax_success('DEFAULT');
1240
        return false;
1241
    }
1242
    // prepare payload
1243
    var payload = {
1244
        "network": {"name": networkName}
1245
    };
1246
    // ajax call
1247
    $.ajax({
1248
        url: API_URL + '/networks/' + networkID,
1249
        type: "PUT",
1250
        contentType: "application/json",
1251
        dataType: "json",
1252
        data: JSON.stringify(payload),
1253
        timeout: TIMEOUT,
1254
        error: function(jqXHR, textStatus, errorThrown) {
1255
            try {
1256
                ajax_error(jqXHR.status, undefined, 'Rename network', jqXHR.responseText);
1257
            } catch (err) {
1258
                ajax_error(0, undefined, 'Rename network', jqXHR.responseText);
1259
            }
1260
        },
1261
        success: function(data, textStatus, jqXHR) {
1262
            if ( jqXHR.status == '204') {
1263
                try {
1264
                    console.info('renamed network' + networkID);
1265
                } catch(err) {}
1266
            } else {
1267
                ajax_error(jqXHR.status, undefined, 'Rename network', jqXHR.responseText);
1268
            }
1269
        }
1270
    });
1271
    return false;
1272
}
1273

    
1274
function delete_network(networkIDs){
1275
    if (!networkIDs.length){
1276
        //ajax_success('DEFAULT');
1277
        return false;
1278
    }
1279
    // get a network
1280
    var networkID = networkIDs.pop();
1281
    // ajax post destroy call can have an empty request body
1282
    var payload = {};
1283
    // ajax call
1284
    $.ajax({
1285
        url: API_URL + '/networks/' + networkID,
1286
        type: "DELETE",
1287
        contentType: "application/json",
1288
        dataType: "json",
1289
        data: JSON.stringify(payload),
1290
        timeout: TIMEOUT,
1291
        error: function(jqXHR, textStatus, errorThrown) {
1292
            try {
1293
                display_net_failure(jqXHR.status, networkID, 'Delete', jqXHR.responseText);
1294
            } catch (err) {
1295
                display_net_failure(0, networkID, 'Delete', jqXHR.responseText);
1296
            }
1297
        },
1298
        success: function(data, textStatus, jqXHR) {
1299
            if ( jqXHR.status == '204') {
1300
                try {
1301
                    console.info('deleted network ' + networkID);
1302
                } catch(err) {}
1303
                // continue with the rest of the servers
1304
                delete_network(networkIDs);
1305
            } else {
1306
                try {
1307
                    display_net_failure(jqXHR.status, networkID, 'Delete', jqXHR.responseText);
1308
                } catch (err) {
1309
                    display_net_failure(0, networkID, 'Delete', jqXHR.responseText);
1310
                }
1311
            }
1312
        }
1313
    });
1314
    return false;
1315
}
1316

    
1317
function add_server_to_network(networkID, serverIDs, serverNames, serverStates) {
1318
    if (!serverIDs.length){
1319
        // close the overlay when all the calls are made
1320
        $("a#add-machines-overlay").overlay().close();
1321
        return false;
1322
    }
1323
    // get a server
1324
    var serverID = serverIDs.pop();
1325
    var serverName = serverNames.pop();
1326
    var serverState = serverStates.pop();
1327
    // prepare payload
1328
    var payload = {
1329
            "add": { "serverRef": serverID }
1330
        };
1331
    // prepare ajax call
1332
    $.ajax({
1333
        url: API_URL + '/networks/' + networkID + '/action',
1334
        type: "POST",
1335
        contentType: "application/json",
1336
        dataType: "json",
1337
        data: JSON.stringify(payload),
1338
        timeout: TIMEOUT,
1339
        error: function(jqXHR, textStatus, errorThrown) {
1340
            try {
1341
                // close wizard and show error box
1342
                $("a#add-machines-overlay").data('overlay').close();
1343
                ajax_error(jqXHR.status, undefined, 'Add server to network', jqXHR.responseText);
1344
            } catch (err) {
1345
                ajax_error(0, undefined, 'Add server to network', jqXHR.responseText);
1346
            }
1347
        },
1348
        success: function(data, textStatus, jqXHR) {
1349
            if ( jqXHR.status == '202') {
1350
                try {
1351
                    console.info('added server ' + serverID + ' to network ' + networkID);
1352
                } catch(err) {}
1353
                // toggle the reboot dialog
1354
                display_reboot_dialog(networkID, serverID, serverName, serverState);
1355
                // continue with the rest of the servers
1356
                add_server_to_network(networkID, serverIDs, serverNames, serverStates);
1357
            } else {
1358
                // close wizard and show error box
1359
                $("a#add-machines-overlay").data('overlay').close();
1360
                ajax_error(jqXHR.status, undefined, 'Add server to network', jqXHR.responseText);
1361
            }
1362
        }
1363
    });
1364
    return false;
1365
}
1366

    
1367
function remove_server_from_network(networkIDs, serverIDs, serverNames, serverStates) {
1368
    if (!networkIDs.length){
1369
        //ajax_success('DEFAULT');
1370
        return false;
1371
    }
1372
    // get a network and a server
1373
    var networkID = networkIDs.pop();
1374
    var serverID = serverIDs.pop();
1375
    var serverName = serverNames.pop();
1376
    var serverState = serverStates.pop();
1377
    // prepare payload
1378
    var payload = {
1379
            "remove": { "serverRef": serverID }
1380
        };
1381
    // prepare ajax call
1382
    $.ajax({
1383
        url: API_URL + '/networks/' + networkID + '/action',
1384
        type: "POST",
1385
        contentType: "application/json",
1386
        dataType: "json",
1387
        data: JSON.stringify(payload),
1388
        timeout: TIMEOUT,
1389
        error: function(jqXHR, textStatus, errorThrown) {
1390
            try {
1391
                ajax_error(jqXHR.status, undefined, 'Remove server form network', jqXHR.responseText);
1392
            } catch (err) {
1393
                ajax_error(0, undefined, 'Remove server form network', jqXHR.responseText);
1394
            }
1395
        },
1396
        success: function(data, textStatus, jqXHR) {
1397
            if ( jqXHR.status == '202') {
1398
                try {
1399
                    console.info('deleted server ' + serverID + ' from network ' + networkID);
1400
                } catch(err) {}
1401
                // toggle the reboot dialog
1402
                display_reboot_dialog(networkID, serverID, serverName, serverState);
1403
                // continue with the rest of the servers
1404
                remove_server_form_network(networkIDs, serverIDs, serverNames, serverStates);
1405
            } else {
1406
                ajax_error(jqXHR.status, undefined, 'Remove server form network', jqXHR.responseText);
1407
            }
1408
        }
1409
    });
1410
    return false;
1411
}
1412

    
1413
// show the welcome screen
1414
function showWelcome() {
1415
    $("#view-select").fadeOut("fast");
1416
    $("#emptymachineslist").fadeIn("fast");
1417
    $("#machinesview").hide();
1418
}
1419

    
1420
// hide the welcome screen
1421
function hideWelcome() {
1422
    $("#emptymachineslist").fadeOut("fast");
1423
    $("#view-select").fadeIn("fast");
1424
    $("div#view-select").show();
1425
    $("#machinesview").show();
1426
}
1427

    
1428
function log_server_status_change(server_entry, new_status) {
1429
    // firebug console logging
1430
    try {
1431
        if ($("#machinesview-single").length > 0) {
1432
            console.info(server_entry.find("div.machine-details div.name").text() +
1433
                        ' from ' + server_entry.find(".state-label").text() +
1434
                        ' to ' + STATUSES[new_status]);
1435
        } else {
1436
            console.info(server_entry.find("div.name span.name").text() +
1437
                        ' from ' + server_entry.find(".status").text() +
1438
                        ' to ' + STATUSES[new_status]);
1439
        }
1440
    } catch(err) {}
1441
}
1442

    
1443
function get_flavor_params(flavorRef) {
1444
    var cpus, ram, disk;
1445
    if ( flavors.length > 0 ) {
1446
        var current_flavor = '';
1447
        for (i=0; i<flavors.length; i++) {
1448
            if (flavors[i]['id'] == flavorRef) {
1449
                current_flavor = flavors[i];
1450
            }
1451
        }
1452
        cpus = current_flavor['cpu'];
1453
        ram = current_flavor['ram'];
1454
        disk = current_flavor['disk'];
1455
    } else {
1456
        cpus = 'undefined';
1457
        ram = 'undefined';
1458
        disk = 'undefined';
1459
    }
1460
    return {'cpus': cpus, 'ram': ram, 'disk': disk};
1461
}
1462

    
1463
function get_image_params(imageRef) {
1464
    var image_name, image_size;
1465
    if ( images.length > 0 ) {
1466
        var current_image = '';
1467
        for (i=0; i<images.length; i++) {
1468
            if (images[i]['id'] == imageRef) {
1469
                current_image = images[i];
1470
            }
1471
        }
1472
        try {
1473
            image_name = current_image['name'];
1474
        } catch(err) { image_name = 'undefined'; }
1475
        try{
1476
            image_size = current_image['metadata']['values']['size'];
1477
        } catch(err) { image_size = 'undefined'; }
1478
    } else {
1479
        image_name = 'undefined';
1480
        image_size = 'undefined';
1481
    }
1482
    return {'name': image_name,'size': image_size};
1483
}
1484

    
1485
function get_public_ips(server) {
1486
    var ip4, ip6;
1487
    try {
1488
        if (server.addresses.values) {
1489
            $.each (server.addresses.values, function(i, value) {
1490
                if (value.id == 'public') {
1491
                    try {
1492
                        $.each (value.values, function(i, ip) {
1493
                            if (ip.version == '4') {
1494
                                ip4 = ip.addr;
1495
                            } else if (ip.version == '6') {
1496
                                ip6 = ip.addr;
1497
                            } else {
1498
                                ip4 = 'undefined';
1499
                                ip6 = 'undefined';
1500
                            }
1501
                        });
1502
                    } catch (err){
1503
                        try{console.info('Server ' + server.id + ' has invalid ips')}catch(err){};
1504
                        ip4 = 'undefined';
1505
                        ip6 = 'undefined';
1506
                    }
1507
                }
1508
            });
1509
        }
1510
    } catch (err) {
1511
        try{console.info('Server ' + server.id + ' has no network addresses')}catch(err){};
1512
        ip4 = 'undefined';
1513
        ip6 = 'undefined';
1514
    }
1515
    return {'ip4': ip4, 'ip6': ip6};
1516
}
1517

    
1518
function get_private_ips(server) {
1519

    
1520
}
1521

    
1522
function close_all_overlays() {
1523
        try {
1524
                $("a#networkscreate").overlay().close();
1525
        } catch(err) {}
1526
        try {
1527
                $('a#create').overlay().close();
1528
        } catch(err) {}
1529
        try {
1530
                $("a#add-machines-overlay").overlay().close();
1531
        } catch(err) {}
1532
        try {
1533
                $("a#metadata-scrollable").overlay().close();
1534
        } catch(err) {}
1535
}