Statistics
| Branch: | Tag: | Revision:

root / ui / static / synnefo.js @ d994d118

History | View | Annotate | Download (26.2 kB)

1
var flavors = [], images = [], servers = [], disks = [], cpus = [], ram = [];
2
var changes_since = 0, deferred = 0, update_request = false, load_request = false, pending_actions = [];
3
var API_URL = "/api/v1.1";
4

    
5
//FIXME: sends a fake HTTP_AUTH_TOKEN
6
    $.ajaxSetup({
7
        'beforeSend': function(xhr) {xhr.setRequestHeader("X_AUTH_TOKEN", "46e427d657b20defe352804f0eb6f8a2")}
8
    });
9

    
10

    
11
function ISODateString(d){
12
    //return a date in an ISO 8601 format using UTC.
13
    //do not include time zone info (Z) at the end
14
    //taken from the Mozilla Developer Center
15
    function pad(n){ return n<10 ? '0'+n : n }
16
    return  d.getUTCFullYear()+ '-' +
17
                        pad(d.getUTCMonth()+1) + '-' +
18
                        pad(d.getUTCDate()) + 'T' +
19
                        pad(d.getUTCHours()) + ':' +
20
                        pad(d.getUTCMinutes()) + ':' +
21
                        pad(d.getUTCSeconds()) +'Z'
22
}
23

    
24

    
25
function parse_error(responseText){
26
        var errors = [];
27
        if (responseText.length == 0){
28
                errors[0] = {'code': 0};
29
        } else {
30
                responseObj = JSON.parse(responseText);
31
                //console.info(inp);
32
                for (var err in responseObj){
33
                        errors[errors.length] = responseObj[err];
34
                }
35
        }
36
        return errors;
37
}
38

    
39
// indexOf prototype for IE
40
if (!Array.prototype.indexOf) {
41
  Array.prototype.indexOf = function(elt /*, from*/) {
42
    var len = this.length;
43
    var from = Number(arguments[1]) || 0;
44
    from = (from < 0)
45
         ? Math.ceil(from)
46
         : Math.floor(from);
47
    if (from < 0)
48
      from += len;
49

    
50
    for (; from < len; from++) {
51
      if (from in this &&
52
          this[from] === elt)
53
        return from;
54
    }
55
    return -1;
56
  };
57
}
58

    
59

    
60
function update_confirmations(){
61
    // hide all confirm boxes to begin with
62
    $('div.confirm_single').hide();
63
    $('div.confirm_multiple').hide();
64

    
65
        // standard view only
66
        if ($.cookie("list") != '1') {
67
                for (var i=0;i<pending_actions.length;i++){
68
            // show single confirms
69
                        $("div.machine-container#"+pending_actions[i][1]+' .confirm_single').show();
70
                }                
71
        }
72

    
73
        // if more than one pending action show multiple confirm box
74
        if (pending_actions.length>1 || $.cookie("list") == '1' && pending_actions.length == 1){
75
                $('div.confirm_multiple span.actionLen').text(pending_actions.length);
76
                $('div.confirm_multiple').show();
77
        }
78
}
79

    
80
function list_view() {
81
        changes_since = 0; // to reload full list
82
        pending_actions = []; // clear pending actions
83
        update_confirmations();
84
        clearTimeout(deferred);        // clear old deferred calls
85
        try {
86
                update_request.abort(); // cancel pending ajax updates
87
                load_request.abort();
88
        }catch(err){}
89
    $.cookie("list", '1'); // set list cookie
90
        
91
        uri = $("#list").attr("href");
92
    load_request = $.ajax({
93
        url: uri,
94
        type: "GET",
95
        timeout: TIMEOUT,
96
        dataType: "html",
97
        error: function(jqXHR, textStatus, errorThrown) {                                                
98
                        return false;
99
                },
100
        success: function(data, textStatus, jqXHR) {
101
                        $("a#list")[0].className += ' activelink';
102
                        $("a#standard")[0].className = '';
103
                        $("div#machinesview").html(data);
104
                }
105
        });
106

    
107
    return false;
108
}
109

    
110
function standard_view() {
111
        changes_since = 0; // to reload full list
112
        pending_actions = []; // clear pending actions
113
        update_confirmations();
114
        clearTimeout(deferred);        // clear old deferred calls
115
        try {
116
                update_request.abort() // cancel pending ajax updates
117
                load_request.abort();
118
        }catch(err){}        
119
    $.cookie("list", '0');
120
        
121
    uri = $("a#standard").attr("href");
122
    load_request = $.ajax({
123
        url: uri,
124
        type: "GET",
125
        timeout: TIMEOUT,
126
        dataType: "html",
127
        error: function(jqXHR, textStatus, errorThrown) {                                                
128
                        return false;
129
                },
130
        success: function(data, textStatus, jqXHR) {
131
                        $("a#standard")[0].className += ' activelink';
132
                        $("a#list")[0].className = '';
133
                        $("div#machinesview").html(data);
134
                }
135
        });        
136

    
137
    return false;
138
}
139

    
140
function choose_view() {
141
    if ($.cookie("list")=='1') {
142
        list_view();
143
    } else {
144
        standard_view();
145
    }
146
}
147

    
148
function toggleMenu() {
149
    var primary = $("ul.css-tabs li a.primary");
150
    var secondary = $("ul.css-tabs li a.secondary");
151
    var all = $("ul.css-tabs li a");                        
152
    var toggled = $('ul.css-tabs li a.current').hasClass('secondary');
153

    
154
    // if anything is still moving, do nothing
155
    if ($(":animated").length) {
156
        return;
157
    }
158

    
159
    // nothing is current to begin with
160
    $('ul.css-tabs li a.current').removeClass('current');
161

    
162
    // move stuff around
163
    all.animate({top:'30px'}, {complete: function() {
164
        $(this).hide();
165
        if (toggled) {
166
            primary.show();
167
            primary.animate({top:'9px'}, {complete: function() {
168
                $('ul.css-tabs li a.primary#machines').addClass('current');
169
                $('a#machines').click();                                   
170
            }});
171
        } else {
172
            secondary.show();
173
            secondary.animate({top:'9px'}, {complete: function() {
174
                $('ul.css-tabs li a.secondary#files').addClass('current');
175
                $('a#files').click();                                                                           
176
            }});
177
        }
178
    }});
179

    
180
    // rotate arrow icon
181
    if (toggled) {
182
        $("#arrow").rotate({animateAngle: (0), bind:[{"click":function(){toggleMenu()}}]});
183
        $("#arrow").rotateAnimation(0);                    
184
    } else {
185
        $("#arrow").rotate({animateAngle: (-180), bind:[{"click":function(){toggleMenu()}}]});
186
        $("#arrow").rotateAnimation(-180);
187
    }
188
}
189

    
190
// confirmation overlay generation
191
function confirm_action(action_string, action_function, serverIDs, serverNames) {
192
    if (serverIDs.length == 1){
193
        $("#yes-no h3").text('You are about to ' + action_string + ' vm ' + serverNames[0]);
194
    } else if (serverIDs.length > 1){
195
        $("#yes-no h3").text('You are about to ' + action_string + ' ' + serverIDs.length + ' machines');
196
    } else {
197
        return false;
198
    }
199
    // action confirmation overlay
200
    var triggers = $("a#confirmation").overlay({
201
            // some mask tweaks suitable for modal dialogs
202
            mask: {
203
                    color: '#ebecff',
204
                    opacity: '0.9'
205
            },
206
        top: 'center',
207
        load: false
208
    });
209
    // yes or no?
210
    var buttons = $("#yes-no button").click(function(e) {
211
            // get user input
212
            var yes = buttons.index(this) === 0;
213
        //close the confirmation window
214
        $("a#confirmation").overlay().close();
215
        // return true=yes or false=no
216
        if (yes) {
217
            action_function(serverIDs);
218
        }
219
    });
220
    $("a#confirmation").data('overlay').load();
221
    return false;
222
}
223

    
224
// get and show a list of running and terminated machines
225
function update_vms(interval) {
226
    try{ console.info('updating machines'); } catch(err){}
227
        var uri= API_URL + '/servers/detail';
228

    
229
        if (changes_since != 0)
230
                uri+='?changes-since='+changes_since
231
                
232
    update_request = $.ajax({
233
        cache: false,
234
        url: uri,
235
        type: "GET",
236
        timeout: TIMEOUT,
237
        dataType: "json",
238
        error: function(jqXHR, textStatus, errorThrown) {
239
                        // don't forget to try again later
240
                        if (interval) {
241
                                clearTimeout(deferred);        // clear old deferred calls
242
                                deferred = setTimeout(update_vms,interval,interval);
243
                        }
244
                        // as for now, just show an error message
245
                        try { console.info('update_vms errback:' + jqXHR.status ) } catch(err) {}
246
                        ajax_error(jqXHR.status, undefined, 'Update VMs', jqXHR.responseText);                                                
247
                        return false;
248
                        },
249
        success: function(data, textStatus, jqXHR) {
250
            // create changes_since string if necessary
251
            if (jqXHR.getResponseHeader('Date') != null){
252
                            changes_since_date = new Date(jqXHR.getResponseHeader('Date'));
253
                            changes_since = ISODateString(changes_since_date);
254
            }
255

    
256
                        if (interval) {
257
                                clearTimeout(deferred);        // clear old deferred calls
258
                                deferred = setTimeout(update_vms,interval,interval);
259
                        }
260
                        
261
                        if (jqXHR.status == 200 || jqXHR.status == 203) {
262
                                try {
263
                                        servers = data.servers.values;
264
                                } catch(err) { ajax_error('400', undefined, 'Update VMs', jqXHR.responseText);}
265
                                update_machines_view(data);
266
                        } else if (jqXHR.status != 304){
267
                                try { console.info('update_vms callback:' + jqXHR.status ) } catch(err) {}
268
                                //ajax_error(jqXHR.status, undefined, 'Update VMs', jqXHR.responseText);                                        
269
                        }
270
                        return false;
271
        }
272
    });
273
    return false;
274
}
275

    
276
// get and show a list of available standard and custom images
277
function update_images() {
278
    $.ajax({
279
        url: API_URL + '/images/detail',
280
        type: "GET",
281
        //async: false,
282
        dataType: "json",
283
        timeout: TIMEOUT,
284
        error: function(jqXHR, textStatus, errorThrown) {
285
                    ajax_error(jqXHR.status, undefined, 'Update Images', jqXHR.responseText);
286
                    },
287
        success: function(data, textStatus, jqXHR) {
288
            try {
289
                                images = data.images.values;
290
                                update_wizard_images();
291
                        } catch(err){
292
                                ajax_error("NO_IMAGES");
293
                        }
294
        }
295
    });
296
    return false;
297
}
298

    
299
function update_wizard_images() {
300
        if ($("ul#standard-images li").toArray().length + $("ul#custom-images li").toArray().length == 0) {
301
                $.each(images, function(i,image){
302
                        var img = $('#image-template').clone().attr("id","img-"+image.id).fadeIn("slow");
303
                        img.find("label").attr('for',"img-radio-" + image.id);
304
                        img.find(".image-title").text(image.name);
305
            if (image.metadata) {
306
                if (image.metadata.values.description != undefined) {
307
                    img.find(".description").text(image.metadata.values.description);
308
                }
309
                if (image.metadata.values.size != undefined) {
310
                                img.find("#size").text(image.metadata.values.size);
311
                }
312
            }
313
                        img.find("input.radio").attr('id',"img-radio-" + image.id);
314
                        if (i==0) img.find("input.radio").attr("checked","checked");
315
            var image_logo = os_icon(image.metadata);
316
                        img.find("img.image-logo").attr('src','static/os_logos/'+image_logo+'.png');
317
            if (image.metadata) {
318
                if (image.metadata.values.serverId != undefined) {
319
                    img.appendTo("ul#custom-images");
320
                } else {
321
                    img.appendTo("ul#standard-images");
322
                }
323
            } else {
324
                img.appendTo("ul#standard-images");
325
            }
326
                });
327
        }        
328
}
329

    
330
function update_wizard_flavors(){
331
        // sliders for selecting VM flavor
332
        $("#cpu:range").rangeinput({min:0,
333
                                                           value:0,
334
                                                           step:1,
335
                                                           progress: true,
336
                                                           max:cpus.length-1});
337
        
338
        $("#storage:range").rangeinput({min:0,
339
                                                           value:0,
340
                                                           step:1,
341
                                                           progress: true,
342
                                                           max:disks.length-1});
343

    
344
        $("#ram:range").rangeinput({min:0,
345
                                                           value:0,
346
                                                           step:1,
347
                                                           progress: true,
348
                                                           max:ram.length-1});
349
        $("#small").click();
350

    
351
        // update the indicators when sliding
352
        $("#cpu:range").data().rangeinput.onSlide(function(event,value){
353
                $("#cpu-indicator")[0].value = cpus[Number(value)];
354
        $("#cpu-indicator").addClass('selectedrange');
355
        });
356
        $("#cpu:range").data().rangeinput.change(function(event,value){
357
                $("#cpu-indicator")[0].value = cpus[Number(value)];                                
358
                $("#custom").click();
359
        $("#cpu-indicator").removeClass('selectedrange');                
360
        });                        
361
        $("#ram:range").data().rangeinput.onSlide(function(event,value){
362
                $("#ram-indicator")[0].value = ram[Number(value)];
363
        $("#ram-indicator").addClass('selectedrange');
364
        });
365
        $("#ram:range").data().rangeinput.change(function(event,value){
366
                $("#ram-indicator")[0].value = ram[Number(value)];                                
367
                $("#custom").click();
368
        $("#ram-indicator").removeClass('selectedrange');                
369
        });                        
370
        $("#storage:range").data().rangeinput.onSlide(function(event,value){
371
                $("#storage-indicator")[0].value = disks[Number(value)];
372
        $("#storage-indicator").addClass('selectedrange');
373
        });
374
        $("#storage:range").data().rangeinput.change(function(event,value){
375
                $("#storage-indicator")[0].value = disks[Number(value)];                                
376
                $("#custom").click();
377
        $("#storage-indicator").removeClass('selectedrange');                
378
        });                                
379
}
380

    
381
Array.prototype.unique = function () {
382
        var r = new Array();
383
        o:for(var i = 0, n = this.length; i < n; i++)
384
        {
385
                for(var x = 0, y = r.length; x < y; x++)
386
                {
387
                        if(r[x]==this[i])
388
                        {
389
                                continue o;
390
                        }
391
                }
392
                r[r.length] = this[i];
393
        }
394
        return r;
395
}
396

    
397
// get and configure flavor selection
398
function update_flavors() {
399
    $.ajax({
400
        url: API_URL + '/flavors/detail',
401
        type: "GET",
402
        //async: false,
403
        dataType: "json",
404
        timeout: TIMEOUT,
405
        error: function(jqXHR, textStatus, errorThrown) {
406
            try {
407
                                ajax_error(jqXHR.status, undefined, 'Update Flavors', jqXHR.responseText);
408
                        } catch (err) {
409
                                ajax_error(err);
410
                        }
411
            // start updating vm list
412
            update_vms(UPDATE_INTERVAL);
413
        },
414
        success: function(data, textStatus, jqXHR) {
415
            flavors = data.flavors.values;
416
            $.each(flavors, function(i, flavor) {
417
                cpus[i] = flavor['cpu'];
418
                disks[i] = flavor['disk'];
419
                ram[i] = flavor['ram'];
420
            });
421
            cpus = cpus.unique();
422
            disks = disks.unique();
423
            ram = ram.unique();
424
                        update_wizard_flavors();
425
            // start updating vm list
426
            update_vms(UPDATE_INTERVAL);
427
        }
428
    });
429
    return false;
430
}
431

    
432
// return flavorRef from cpu, disk, ram values
433
function identify_flavor(cpu, disk, ram){
434
    for (i=0;i<flavors.length;i++){
435
        if (flavors[i]['cpu'] == cpu && flavors[i]['disk']==disk && flavors[i]['ram']==ram) {
436
            return flavors[i]['id']
437
        }
438
    }
439
    return 0;
440
}
441

    
442
// return image entry from imageRef
443
function get_image(imageRef) {
444
    for (i=0;i<images.length;i++){
445
        if (images[i]['id'] == imageRef) {
446
            return images[i];
447
        }
448
    }
449
    return 0;
450
}
451

    
452
// update the actions in list view
453
function updateActions() {
454
        var states = [];
455
        var on = [];
456
        var checked = $("table.list-machines tbody input[type='checkbox']:checked");
457
        // disable all actions to begin with
458
        for (action in actions) {
459
                $("#action-" + action).removeClass('enabled');
460
        }
461

    
462
        // are there multiple machines selected?
463
        if (checked.length>1)
464
                states[0] = 'multiple';
465
        
466
        // check the states of selected machines
467
        checked.each(function(i,checkbox) {
468
                states[states.length] = checkbox.className;
469
                var ip = $("#" + checkbox.id.replace('input-','') + ".ip span.public").text();
470
                if (ip.replace('undefined','').length)
471
                        states[states.length] = 'network';
472
        });
473

    
474
        // decide which actions should be enabled
475
        for (a in actions) {
476
                var enabled = false;
477
                for (var s =0; s<states.length; s++) {
478
                        if (actions[a].indexOf(states[s]) != -1 ) {
479
                                enabled = true;
480
                        } else {
481
                                enabled = false;
482
                                break;
483
                        }
484
                }
485
                if (enabled)
486
                        on[on.length]=a;
487
        }
488
        // enable those actions
489
        for (action in on) {
490
                $("#action-" + on[action]).addClass('enabled');
491
        }
492
}
493

    
494
//create server action
495
function create_vm(machineName, imageRef, flavorRef){
496

    
497
    var image_logo = os_icon(get_image(imageRef).metadata);
498

    
499
    var payload = {
500
        "server": {
501
            "name": machineName,
502
            "imageRef": imageRef,
503
            "flavorRef" : flavorRef,
504
            "metadata" : {
505
                "OS" : image_logo
506
            }
507
        }
508
    };
509
        var uri = API_URL + '/servers';
510

    
511
    $.ajax({
512
    url: uri,
513
    type: "POST",
514
        contentType: "application/json",
515
    dataType: "json",
516
    data: JSON.stringify(payload),
517
    timeout: TIMEOUT,
518
    error: function(jqXHR, textStatus, errorThrown) {
519
                ajax_error(jqXHR.status, undefined, 'Create VM', jqXHR.responseText);
520
           },
521
    success: function(data, textStatus, jqXHR) {
522
                if ( jqXHR.status == '202') {
523
                    ajax_success("CREATE_VM_SUCCESS", data.server.adminPass);
524
                } else {
525
                    ajax_error(jqXHR.status, undefined, 'Create VM', jqXHR.responseText);
526
                }
527
            }
528
    });
529
}
530

    
531
// reboot action
532
function reboot(serverIDs){
533
        if (!serverIDs.length){
534
                //ajax_success('DEFAULT');
535
                return false;
536
        }        
537
    // ajax post reboot call
538
    var payload = {
539
        "reboot": {"type" : "HARD"}
540
    };
541
    var serverID = serverIDs.pop();
542
        
543
        $.ajax({
544
                url: API_URL + '/servers/' + serverID + '/action',
545
                type: "POST",
546
                contentType: "application/json",
547
                dataType: "json",
548
                data: JSON.stringify(payload),
549
                timeout: TIMEOUT,
550
                error: function(jqXHR, textStatus, errorThrown) {
551
                    display_failure(jqXHR.status, serverID, 'Reboot', jqXHR.responseText)
552
                                },
553
                success: function(data, textStatus, jqXHR) {
554
                                        if ( jqXHR.status == '202') {
555
                        try {
556
                            console.info('rebooted ' + serverID);
557
                        } catch(err) {}
558
                                                // indicate that the action succeeded
559
                                                display_success(serverID);
560
                                                // continue with the rest of the servers
561
                                                reboot(serverIDs);
562
                                        } else {
563
                                                ajax_error(jqXHR.status, serverID, 'Reboot', jqXHR.responseText);
564
                                        }
565
                                }
566
    });
567

    
568
    return false;
569
}
570

    
571
// shutdown action
572
function shutdown(serverIDs) {
573
        if (!serverIDs.length){
574
                //ajax_success('DEFAULT');
575
                return false;
576
        }
577
    // ajax post shutdown call
578
    var payload = {
579
        "shutdown": {}
580
    };
581

    
582
        var serverID = serverIDs.pop()
583
    $.ajax({
584
            url: API_URL + '/servers/' + serverID + '/action',
585
            type: "POST",
586
                contentType: "application/json",
587
            dataType: "json",
588
        data: JSON.stringify(payload),
589
        timeout: TIMEOUT,
590
        error: function(jqXHR, textStatus, errorThrown) {
591
                    display_failure(jqXHR.status, serverID, 'Shutdown', jqXHR.responseText)
592
                    },
593
        success: function(data, textStatus, jqXHR) {
594
                    if ( jqXHR.status == '202') {
595
                                                try {
596
                            console.info('suspended ' + serverID);
597
                        } catch(err) {}
598
                                                // indicate that the action succeeded
599
                                                display_success(serverID);
600
                                                // continue with the rest of the servers
601
                        shutdown(serverIDs);
602
                    } else {
603
                        ajax_error(jqXHR.status, serverID, 'Shutdown', jqXHR.responseText);
604
                    }
605
                }
606
    });
607

    
608
    return false;
609
}
610

    
611
// destroy action
612
function destroy(serverIDs) {
613
        if (!serverIDs.length){
614
                //ajax_success('DEFAULT');
615
                return false;
616
        }
617
    // ajax post destroy call can have an empty request body
618
    var payload = {};
619

    
620
        serverID = serverIDs.pop()
621
    $.ajax({
622
            url: API_URL + '/servers/' + serverID,
623
            type: "DELETE",
624
                contentType: "application/json",
625
            dataType: "json",
626
        data: JSON.stringify(payload),
627
        timeout: TIMEOUT,
628
        error: function(jqXHR, textStatus, errorThrown) {
629
                    display_failure(jqXHR.status, serverID, 'Destroy', jqXHR.responseText)
630
                    },
631
        success: function(data, textStatus, jqXHR) {
632
                    if ( jqXHR.status == '204') {
633
                                                try {
634
                            console.info('destroyed ' + serverID);
635
                        } catch (err) {}
636
                                                // indicate that the action succeeded
637
                                                display_success(serverID);
638
                                                // continue with the rest of the servers
639
                        destroy(serverIDs);
640
                    } else {
641
                        ajax_error(jqXHR.status, serverID, 'Destroy', jqXHR.responseText);
642
                    }
643
                }
644
    });
645

    
646
    return false;
647
}
648

    
649
// start action
650
function start(serverIDs){
651
        if (!serverIDs.length){
652
                //ajax_success('DEFAULT');
653
                return false;
654
        }        
655
    // ajax post start call
656
    var payload = {
657
        "start": {}
658
    };
659

    
660
        var serverID = serverIDs.pop()
661
    $.ajax({
662
        url: API_URL + '/servers/' + serverID + '/action',
663
        type: "POST",
664
                contentType: "application/json",
665
        dataType: "json",
666
        data: JSON.stringify(payload),
667
        timeout: TIMEOUT,
668
        error: function(jqXHR, textStatus, errorThrown) {
669
                    display_failure(jqXHR.status, serverID, 'Start', jqXHR.responseText)
670
                    },
671
        success: function(data, textStatus, jqXHR) {
672
                    if ( jqXHR.status == '202') {
673
                                            try {
674
                            console.info('started ' + serverID);
675
                        } catch(err) {}
676
                                                // indicate that the action succeeded
677
                                                display_success(serverID);
678
                                                // continue with the rest of the servers                                                
679
                        start(serverIDs);
680
                    } else {
681
                        ajax_error(jqXHR.status, serverID, 'Start', jqXHR.responseText);
682
                    }
683
                }
684
    });
685

    
686
    return false;
687
}
688

    
689
// Show VNC console
690
function vnc_attachment(host, port, password) {
691
    // FIXME: Must be made into parameters, in settings.py
692
    //vnc = open("", "displayWindow",
693
    //    "status=yes,toolbar=yes,menubar=yes");
694
    vd = document.open("application/x-vnc");
695

    
696
    vd.writeln("[connection]");
697
    vd.writeln("host=" + host);
698
    vd.writeln("port=" + port);
699
    vd.writeln("password=" + password);
700

    
701
    vd.close();
702
}
703

    
704

    
705
// Show VNC console
706
function show_vnc_console(serverID, host, port, password) {
707
    // FIXME: Must be made into parameters, in settings.py
708

    
709
    var params_url = '?host=' + host + '&port=' + port + '&password=' + password ;
710

    
711
    window.open('/machines/console' + params_url, 'formresult' + serverID, 'scrollbars=no,menubar=no,height=600,width=800,resizable=yes,toolbar=no,status=no');
712

    
713
    return false;
714
}
715

    
716

    
717
// console action
718
function open_console(serverIDs){
719
        if (!serverIDs.length){
720
                //ajax_success('DEFAULT');
721
                return false;
722
        }
723
    // ajax post start call
724
    var payload = {
725
        "console": {"type": "vnc"}
726
    };
727

    
728
        var serverID = serverIDs.pop()
729
    $.ajax({
730
        url: API_URL + '/servers/' + serverID + '/action',
731
        type: "POST",
732
                contentType: "application/json",
733
        dataType: "json",
734
        data: JSON.stringify(payload),
735
        timeout: TIMEOUT,
736
        error: function(jqXHR, textStatus, errorThrown) {
737
                    display_failure(jqXHR.status, serverID, 'Console', jqXHR.responseText)
738
                    },
739
        success: function(data, textStatus, jqXHR) {
740
                    if ( jqXHR.status == '200') {
741
                                            try {
742
                            console.info('got_console ' + serverID);
743
                        } catch(err) {}
744
                                                // indicate that the action succeeded
745
                        show_vnc_console(serverID, data.console.host,data.console.port,data.console.password);
746
                                                display_success(serverID);
747
                        // hide spinner
748
                        $('#' + serverID + ' .spinner').hide();
749
                                                // continue with the rest of the servers
750
                        open_console(serverIDs);
751
                    } else {
752
                        ajax_error(jqXHR.status, serverID, 'Console', jqXHR.responseText);
753
                    }
754
                }
755
    });
756
    return false;
757
}
758

    
759

    
760
// rename server name action
761
function rename(serverID, serverName){
762
        if (!serverID.length){
763
                //ajax_success('DEFAULT');
764
                return false;
765
        }        
766
    // ajax post rename call
767
    var payload = {
768
        "server": {"name": serverName}
769
    };
770

    
771
    $.ajax({
772
        url: API_URL + '/servers/' + serverID,
773
        type: "PUT",
774
                contentType: "application/json",
775
        dataType: "json",
776
        data: JSON.stringify(payload),
777
        timeout: TIMEOUT,
778
        error: function(jqXHR, textStatus, errorThrown) {
779
                    display_failure(jqXHR.status, serverID, 'Rename', jqXHR.responseText)
780
                    },
781
        success: function(data, textStatus, jqXHR) {
782
                    if ( jqXHR.status == '204') {
783
                                            try {
784
                            console.info('renamed ' + serverID);
785
                        } catch(err) {}
786
                                                // indicate that the action succeeded
787
                                                display_success(serverID);
788
                    } else {
789
                        ajax_error(jqXHR.status, serverID, 'Rename', jqXHR.responseText);
790
                    }
791
                }
792
    });
793

    
794
    return false;
795
}
796

    
797
// get server metadata
798
function get_metadata(serverID) {
799
    $.ajax({
800
        url: API_URL + '/servers/' + serverID + '/meta',
801
        type: "GET",
802
        //async: false,
803
        dataType: "json",
804
        timeout: TIMEOUT,
805
        error: function(jqXHR, textStatus, errorThrown) {
806
            try {
807
                                ajax_error(jqXHR.status, undefined, 'Get metadata', jqXHR.responseText);
808
                        } catch (err) {
809
                                ajax_error(err);
810
                        }
811
        },
812
        success: function(data, textStatus, jqXHR) {
813
            // to list the new results in the edit dialog
814
            list_metadata(data);
815
            list_metadata_keys(serverID, data);
816
        }
817
    });
818
    return false;
819
}
820

    
821
// delete metadata key-value pair
822
function delete_metadata(serverID, meta_key) {
823
    $.ajax({
824
        url: API_URL + '/servers/' + serverID + '/meta/' + meta_key,
825
        type: "DELETE",
826
        //async: false,
827
        dataType: "json",
828
        timeout: TIMEOUT,
829
        error: function(jqXHR, textStatus, errorThrown) {
830
            try {
831
                                ajax_error(jqXHR.status, undefined, 'Delete metadata', jqXHR.responseText);
832
                        } catch (err) {
833
                                ajax_error(err);
834
                        }
835
        },
836
        success: function(data, textStatus, jqXHR) {
837
            // to GET new results and list them in the edit dialog
838
            get_metadata(serverID);
839
        }
840
    });
841
    return false;
842
}
843

    
844

    
845
// add metadata key-value pair
846
function add_metadata(serverID, meta_key, meta_value) {
847

    
848
    var payload = {
849
        "meta": {
850
        }
851
    };
852
    payload["meta"][meta_key] = meta_value;
853

    
854
    $.ajax({
855
        url: API_URL + '/servers/' + serverID + '/meta/' + meta_key,
856
        type: "PUT",
857
            contentType: "application/json",
858
        dataType: "json",
859
        data: JSON.stringify(payload),
860
        timeout: TIMEOUT,
861
        error: function(jqXHR, textStatus, errorThrown) {
862
            try {
863
                                ajax_error(jqXHR.status, undefined, 'add metadata', jqXHR.responseText);
864
                        } catch (err) {
865
                                ajax_error(err);
866
                        }
867
        },
868
        success: function(data, textStatus, jqXHR) {
869
            // to GET new results and list them in the edit dialog
870
            get_metadata(serverID);
871
        }
872
    });
873
    return false;
874
}
875

    
876

    
877
// show the welcome screen
878
function showWelcome() {
879
    $("#view-select").fadeOut("fast");
880
    $("#machinesview.standard").fadeOut("fast");
881
    $("#createcontainer").addClass('emptycreatecontainer')
882
    $("#create").addClass('emptycreate')
883
    $("#emptymachineslist").fadeIn("fast");
884
    $("#createbody").fadeIn("fast");
885
    $("#create").css("display", "block");
886
}
887

    
888
// hide the welcome screen
889
function hideWelcome() {
890
    $("#emptymachineslist").fadeOut("fast");
891
    $("#createbody").fadeOut("fast");
892
    $("#createcontainer").removeClass('emptycreatecontainer')
893
    $("#create").removeClass('emptycreate')
894
    $("#view-select").fadeIn("fast");
895
    $("#machinesview.standard").fadeIn("fast");
896
    $("div#view-select").show();
897
    $("#create").css("display", "inline");
898
}
899