Revision f533f224 ui/static/synnefo.js

b/ui/static/synnefo.js
1
var flavors = [], images = [], servers = [], disks = [], cpus = [], ram = [];
2
var changes_since = 0, deferred = 0, update_request = false, load_request = false, pending_actions = [];
3 1
var API_URL = "/api/v1.1";
2
var changes_since = 0, deferred = 0, update_request = false, load_request = false, pending_actions = [];
3
var flavors = [], images = [], servers = [], disks = [], cpus = [], ram = [];
4
var networks = [], networks_changes_since = 0;
5

  
4 6

  
5
//FIXME: authentication 
7
//FIXME: authentication
6 8
//if cookie with value X-Auth-Token exists, set the value on the headers.
7 9
    $.ajaxSetup({
8 10
        'beforeSend': function(xhr) {
......
20 22
    //taken from the Mozilla Developer Center
21 23
    function pad(n){ return n<10 ? '0'+n : n }
22 24
    return  d.getUTCFullYear()+ '-' +
23
			pad(d.getUTCMonth()+1) + '-' +
24
			pad(d.getUTCDate()) + 'T' +
25
			pad(d.getUTCHours()) + ':' +
26
			pad(d.getUTCMinutes()) + ':' +
27
			pad(d.getUTCSeconds()) +'Z'
25
            pad(d.getUTCMonth()+1) + '-' +
26
            pad(d.getUTCDate()) + 'T' +
27
            pad(d.getUTCHours()) + ':' +
28
            pad(d.getUTCMinutes()) + ':' +
29
            pad(d.getUTCSeconds()) +'Z'
28 30
}
29 31

  
30

  
31
function parse_error(responseText){
32
	var errors = [];
33
	if (responseText.length == 0){
34
		errors[0] = {'code': 0};
35
	} else {
36
		responseObj = JSON.parse(responseText);
37
		//console.info(inp);
38
		for (var err in responseObj){
39
			errors[errors.length] = responseObj[err];
40
		}
41
	}
42
	return errors;
32
function parse_error(responseText, errorCode){
33
    var errors = [];
34
    try {
35
        responseObj = JSON.parse(responseText);
36
    }
37
    catch(err) {
38
        errors[0] = {'code': errorCode};
39
        return errors;
40
    }
41
    for (var err in responseObj){
42
        errors[errors.length] = responseObj[err];
43
    }
44
    return errors;
43 45
}
44 46

  
45 47
// indexOf prototype for IE
......
62 64
  };
63 65
}
64 66

  
65

  
66 67
function update_confirmations(){
67 68
    // hide all confirm boxes to begin with
68
    $('div.confirm_single').hide();
69
    $('div.confirm_multiple').hide();
70

  
71
	// standard view only
72
	if ($.cookie("list") != '1') {
73
		for (var i=0;i<pending_actions.length;i++){
69
    $('#machines-pane div.confirm_single').hide();
70
    $('#machines-pane div.confirm_multiple').hide();
71
    // standard view only
72
    if ($.cookie("view") == '0') {
73
        for (var i=0;i<pending_actions.length;i++){
74 74
            // show single confirms
75
			$("div.machine-container#"+pending_actions[i][1]+' .confirm_single').show();
76
		}		
77
	}
75
            $("#machines-pane div.machine-container#"+pending_actions[i][1]+' .confirm_single').show();
76
        }
77
    }
78

  
79
    // if more than one pending action show multiple confirm box
80
    if (pending_actions.length>1 || $.cookie("view") == '1' && pending_actions.length == 1){
81
        $('#machines-pane div.confirm_multiple span.actionLen').text(pending_actions.length);
82
        $('#machines-pane div.confirm_multiple').show();
83
    }
84
}
78 85

  
79
	// if more than one pending action show multiple confirm box
80
	if (pending_actions.length>1 || $.cookie("list") == '1' && pending_actions.length == 1){
81
		$('div.confirm_multiple span.actionLen').text(pending_actions.length);
82
		$('div.confirm_multiple').show();
83
	}
86
function update_network_confirmations(){
87
    // hide all confirm boxes to begin with
88
    $('#networks-pane div.confirm_multiple').hide();
89

  
90
    for (var i=0;i<pending_actions.length;i++){
91
        // show single confirms depending on the action
92
        if (pending_actions[i][0] == delete_network) {
93
            $("#networks-pane div.network#net-"+pending_actions[i][1]).children('.confirm_single').show();
94
        } else if (pending_actions[i][0] == remove_server_from_network) {
95
            $("#networks-pane div.network #net-"+pending_actions[i][1]+"-server-"+pending_actions[i][2]).children('.confirm_single').show();
96
        } // else {}
97
    }
98

  
99
    // if more than one pending action show multiple confirm box
100
    if (pending_actions.length > 1){
101
        $('#networks-pane div.confirm_multiple span.actionLen').text(pending_actions.length);
102
        $('#networks-pane div.confirm_multiple').show();
103
    }
84 104
}
85 105

  
86 106
function list_view() {
87
	changes_since = 0; // to reload full list
88
	pending_actions = []; // clear pending actions
89
	update_confirmations();
90
	clearTimeout(deferred);	// clear old deferred calls
91
	try {
92
		update_request.abort(); // cancel pending ajax updates
93
		load_request.abort();
94
	}catch(err){}
95
    $.cookie("list", '1'); // set list cookie
96
	
97
	uri = $("#list").attr("href");
107
    changes_since = 0; // to reload full list
108
    pending_actions = []; // clear pending actions
109
    update_confirmations();
110
    clearTimeout(deferred);    // clear old deferred calls
111
    try {
112
        update_request.abort(); // cancel pending ajax updates
113
        load_request.abort();
114
    }catch(err){}
115
    $.cookie("view", '1'); // set list cookie
116
    uri = $("a#list").attr("href");
98 117
    load_request = $.ajax({
99 118
        url: uri,
100 119
        type: "GET",
101 120
        timeout: TIMEOUT,
102 121
        dataType: "html",
103
        error: function(jqXHR, textStatus, errorThrown) {						
104
			return false;
105
		},
122
        error: function(jqXHR, textStatus, errorThrown) {
123
            return false;
124
        },
106 125
        success: function(data, textStatus, jqXHR) {
107
			$("a#list")[0].className += ' activelink';
108
			$("a#standard")[0].className = '';
109
			$("div#machinesview").html(data);
110
		}
111
	});
126
            $("a#list")[0].className += ' activelink';
127
            $("a#standard")[0].className = '';
128
            $("a#single")[0].className = '';
129
            $("div#machinesview").html(data);
130
        }
131
    });
132
    return false;
133
}
112 134

  
135
function single_view() {
136
    changes_since = 0; // to reload full list
137
    pending_actions = []; // clear pending actions
138
    update_confirmations();
139
    clearTimeout(deferred);    // clear old deferred calls
140
    try {
141
        update_request.abort(); // cancel pending ajax updates
142
        load_request.abort();
143
    }catch(err){}
144
    $.cookie("view", '2'); // set list cookie
145
    uri = $("a#single").attr("href");
146
    load_request = $.ajax({
147
        url: uri,
148
        type: "GET",
149
        timeout: TIMEOUT,
150
        dataType: "html",
151
        error: function(jqXHR, textStatus, errorThrown) {
152
            return false;
153
        },
154
        success: function(data, textStatus, jqXHR) {
155
            $("a#single")[0].className += ' activelink';
156
            $("a#standard")[0].className = '';
157
            $("a#list")[0].className = '';
158
            $("div#machinesview").html(data);
159
        }
160
    });
113 161
    return false;
114 162
}
115 163

  
116 164
function standard_view() {
117
	changes_since = 0; // to reload full list
118
	pending_actions = []; // clear pending actions
119
	update_confirmations();
120
	clearTimeout(deferred);	// clear old deferred calls
121
	try {
122
		update_request.abort() // cancel pending ajax updates
123
		load_request.abort();
124
	}catch(err){}	
125
    $.cookie("list", '0');
126
	
165
    changes_since = 0; // to reload full list
166
    pending_actions = []; // clear pending actions
167
    update_confirmations();
168
    clearTimeout(deferred);    // clear old deferred calls
169
    try {
170
        update_request.abort() // cancel pending ajax updates
171
        load_request.abort();
172
    }catch(err){}
173
    $.cookie("view", '0');
127 174
    uri = $("a#standard").attr("href");
128 175
    load_request = $.ajax({
129 176
        url: uri,
130 177
        type: "GET",
131 178
        timeout: TIMEOUT,
132 179
        dataType: "html",
133
        error: function(jqXHR, textStatus, errorThrown) {						
134
			return false;
135
		},
180
        error: function(jqXHR, textStatus, errorThrown) {
181
            return false;
182
        },
136 183
        success: function(data, textStatus, jqXHR) {
137
			$("a#standard")[0].className += ' activelink';
138
			$("a#list")[0].className = '';
139
			$("div#machinesview").html(data);
140
		}
141
	});	
142

  
184
            $("a#standard")[0].className += ' activelink';
185
            $("a#list")[0].className = '';
186
            $("a#single")[0].className = '';
187
            $("div#machinesview").html(data);
188
        }
189
    });
143 190
    return false;
144 191
}
145 192

  
146 193
function choose_view() {
147
    if ($.cookie("list")=='1') {
194
    if ($.cookie("view")=='1') {
148 195
        list_view();
196
    } else if ($.cookie("view")=='2'){
197
        single_view();
149 198
    } else {
150 199
        standard_view();
151 200
    }
152 201
}
153 202

  
154
function toggleMenu() {
155
    var primary = $("ul.css-tabs li a.primary");
156
    var secondary = $("ul.css-tabs li a.secondary");
157
    var all = $("ul.css-tabs li a");			
158
    var toggled = $('ul.css-tabs li a.current').hasClass('secondary');
203
// get and show a list of running and terminated machines
204
function update_vms(interval) {
205
    try{ console.info('updating machines'); } catch(err){}
206
    var uri= API_URL + '/servers/detail';
159 207

  
160
    // if anything is still moving, do nothing
161
    if ($(":animated").length) {
162
        return;
163
    }
208
    if (changes_since != 0)
209
        uri+='?changes-since='+changes_since
164 210

  
165
    // nothing is current to begin with
166
    $('ul.css-tabs li a.current').removeClass('current');
167

  
168
    // move stuff around
169
    all.animate({top:'30px'}, {complete: function() {
170
        $(this).hide();
171
        if (toggled) {
172
            primary.show();
173
            primary.animate({top:'9px'}, {complete: function() {
174
                $('ul.css-tabs li a.primary#machines').addClass('current');
175
                $('a#machines').click();                           	
176
            }});
177
        } else {
178
            secondary.show();
179
            secondary.animate({top:'9px'}, {complete: function() {
180
                $('ul.css-tabs li a.secondary#files').addClass('current');
181
                $('a#files').click();                           			                	
182
            }});
183
        }
184
    }});
211
    update_request = $.ajax({
212
        cache: false,
213
        url: uri,
214
        type: "GET",
215
        timeout: TIMEOUT,
216
        dataType: "json",
217
        error: function(jqXHR, textStatus, errorThrown) {
218
            // don't forget to try again later
219
            if (interval) {
220
                clearTimeout(deferred);    // clear old deferred calls
221
                deferred = setTimeout(function() {update_vms(interval);},interval,interval);
222
            }
223
            // as for now, just show an error message
224
            try { console.info('update_vms errback:' + jqXHR.status ) } catch(err) {}
225
            ajax_error(jqXHR.status, undefined, 'Update VMs', jqXHR.responseText);
226
            return false;
227
            },
228
        success: function(data, textStatus, jqXHR) {
229
            // create changes_since string if necessary
230
            if (jqXHR.getResponseHeader('Date') != null){
231
                changes_since_date = new Date(jqXHR.getResponseHeader('Date'));
232
                changes_since = ISODateString(changes_since_date);
233
            }
185 234

  
186
    // rotate arrow icon
187
    if (toggled) {
188
        $("#arrow").rotate({animateAngle: (0), bind:[{"click":function(){toggleMenu()}}]});
189
        $("#arrow").rotateAnimation(0);            	
190
    } else {
191
        $("#arrow").rotate({animateAngle: (-180), bind:[{"click":function(){toggleMenu()}}]});
192
        $("#arrow").rotateAnimation(-180);
193
    }
194
}
235
            if (interval) {
236
                clearTimeout(deferred);    // clear old deferred calls
237
                deferred = setTimeout(function() {update_vms(interval);},interval,interval);
238
            }
195 239

  
196
// confirmation overlay generation
197
function confirm_action(action_string, action_function, serverIDs, serverNames) {
198
    if (serverIDs.length == 1){
199
        $("#yes-no h3").text('You are about to ' + action_string + ' vm ' + serverNames[0]);
200
    } else if (serverIDs.length > 1){
201
        $("#yes-no h3").text('You are about to ' + action_string + ' ' + serverIDs.length + ' machines');
202
    } else {
203
        return false;
204
    }
205
    // action confirmation overlay
206
    var triggers = $("a#confirmation").overlay({
207
	    // some mask tweaks suitable for modal dialogs
208
	    mask: {
209
		    color: '#ebecff',
210
		    opacity: '0.9'
211
	    },
212
        top: 'center',
213
        load: false
240
            if (jqXHR.status == 200 || jqXHR.status == 203) {
241
                try {
242
                    servers = data.servers.values;
243
                } catch(err) { ajax_error('400', undefined, 'Update VMs', jqXHR.responseText);}
244
                update_machines_view(data);
245
            } else if (jqXHR.status != 304){
246
                try { console.info('update_vms callback:' + jqXHR.status ) } catch(err) {}
247
                /*
248
                FIXME:  Here it should return the error, however Opera does not support 304.
249
                        Instead 304 it returns 0. To dealt with this we treat 0 as an
250
                        304, which should be corrected (Bug #317).
251
                */
252
                //ajax_error(jqXHR.status, undefined, 'Update VMs', jqXHR.responseText);
253
            }
254
            return false;
255
        }
214 256
    });
215
    // yes or no?
216
    var buttons = $("#yes-no button").click(function(e) {
217
	    // get user input
218
	    var yes = buttons.index(this) === 0;
219
        //close the confirmation window
220
        $("a#confirmation").overlay().close();
221
        // return true=yes or false=no
222
        if (yes) {
223
            action_function(serverIDs);
257
    return false;
258
}
259

  
260
// get a list of running and terminated machines, used in network view
261
function update_networks(interval) {
262
    try{ console.info('updating networks'); } catch(err){}
263
    var uri= API_URL + '/servers/detail';
264

  
265
    if (changes_since != 0)
266
        uri+='?changes-since='+changes_since
267

  
268
    update_request = $.ajax({
269
        cache: false,
270
        url: uri,
271
        type: "GET",
272
        timeout: TIMEOUT,
273
        dataType: "json",
274
        error: function(jqXHR, textStatus, errorThrown) {
275
            // don't forget to try again later
276
            if (interval) {
277
                clearTimeout(deferred);    // clear old deferred calls
278
                deferred = setTimeout(function() {update_networks(interval);},interval,interval);
279
            }
280
            // as for now, just show an error message
281
            try { console.info('update_networks errback:' + jqXHR.status ) } catch(err) {}
282
            ajax_error(jqXHR.status, undefined, 'Update networks', jqXHR.responseText);
283
            return false;
284
            },
285
        success: function(data, textStatus, jqXHR) {
286
            // create changes_since string if necessary
287
            if (jqXHR.getResponseHeader('Date') != null){
288
                changes_since_date = new Date(jqXHR.getResponseHeader('Date'));
289
                changes_since = ISODateString(changes_since_date);
290
            }
291

  
292
            if (interval) {
293
                clearTimeout(deferred);    // clear old deferred calls
294
                deferred = setTimeout(function() {update_networks(interval);},interval,interval);
295
            }
296

  
297
            if (jqXHR.status == 200 || jqXHR.status == 203) {
298
                try {
299
                    servers = data.servers.values;
300
                } catch(err) { ajax_error('400', undefined, 'Update networks', jqXHR.responseText);}
301
                update_network_names(data);
302
            } else if (jqXHR.status == 304) {
303
                update_network_names();
304
            }
305
            else {
306
                try { console.info('update_networks callback:' + jqXHR.status ) } catch(err) {}
307
                /*
308
                FIXME:  Here it should return the error, however Opera does not support 304.
309
                        Instead 304 it returns 0. To dealt with this we treat 0 as an
310
                        304, which should be corrected (Bug #317).
311
                */
312
                //ajax_error(jqXHR.status, undefined, 'Update networks', jqXHR.responseText);
313
                update_network_names();
314
            }
315
            return false;
224 316
        }
225 317
    });
226
    $("a#confirmation").data('overlay').load();
227 318
    return false;
228 319
}
229 320

  
230
// get and show a list of running and terminated machines
231
function update_vms(interval) {
232
    try{ console.info('updating machines'); } catch(err){}
233
	var uri= API_URL + '/servers/detail';
321
// get and show a list of public and private networks
322
function update_network_names(servers_data) {
323
    try{ console.info('updating network names'); } catch(err){}
324
    var uri= API_URL + '/networks/detail';
325

  
326
    if (networks_changes_since != 0)
327
        //FIXME: Comment out the following, until metadata do not 304 when changed
328
        uri+='?changes-since=' + networks_changes_since
234 329

  
235
	if (changes_since != 0)
236
		uri+='?changes-since='+changes_since
237
		
238 330
    update_request = $.ajax({
239 331
        cache: false,
240 332
        url: uri,
......
242 334
        timeout: TIMEOUT,
243 335
        dataType: "json",
244 336
        error: function(jqXHR, textStatus, errorThrown) {
245
			// don't forget to try again later
246
			if (interval) {
247
				clearTimeout(deferred);	// clear old deferred calls
248
				deferred = setTimeout(update_vms,interval,interval);
249
			}
250
			// as for now, just show an error message
251
			try { console.info('update_vms errback:' + jqXHR.status ) } catch(err) {}
252
			ajax_error(jqXHR.status, undefined, 'Update VMs', jqXHR.responseText);						
253
			return false;
254
			},
337
            // as for now, just show an error message
338
            try {
339
                console.info('update_network names errback:' + jqXHR.status )
340
            } catch(err) {}
341
            ajax_error(jqXHR.status, undefined, 'Update network names', jqXHR.responseText);
342
            return false;
343
            },
255 344
        success: function(data, textStatus, jqXHR) {
256 345
            // create changes_since string if necessary
257 346
            if (jqXHR.getResponseHeader('Date') != null){
258
			    changes_since_date = new Date(jqXHR.getResponseHeader('Date'));
259
			    changes_since = ISODateString(changes_since_date);
260
            }
261

  
262
			if (interval) {
263
				clearTimeout(deferred);	// clear old deferred calls
264
				deferred = setTimeout(update_vms,interval,interval);
265
			}
266
			
267
			if (jqXHR.status == 200 || jqXHR.status == 203) {
268
				try {
269
					servers = data.servers.values;
270
				} catch(err) { ajax_error('400', undefined, 'Update VMs', jqXHR.responseText);}
271
				update_machines_view(data);
272
			} else if (jqXHR.status != 304){
273
				try { console.info('update_vms callback:' + jqXHR.status ) } catch(err) {}
274
				//ajax_error(jqXHR.status, undefined, 'Update VMs', jqXHR.responseText);					
275
			}
276
			return false;
347
                changes_since_date = new Date(jqXHR.getResponseHeader('Date'));
348
                networks_changes_since = ISODateString(changes_since_date);
349
            }
350

  
351
            if (jqXHR.status == 200 || jqXHR.status == 203) {
352
                try {
353
                    networks = data.networks.values;
354
                } catch(err) {
355
                    ajax_error('400', undefined, 'Update network names', jqXHR.responseText);
356
                }
357
                update_networks_view(servers_data, data);
358
            } else if (jqXHR.status == 304) {
359
                update_networks_view(servers_data);
360
            } else if (jqXHR.status != 304){
361
                try { console.info('update_network_names callback:' + jqXHR.status ) } catch(err) {}
362
                /*
363
                FIXME:  Here it should return the error, however Opera does not support 304.
364
                        Instead 304 it returns 0. To dealt with this we treat 0 as an
365
                        304, which should be corrected (Bug #317).
366
                */
367
                //ajax_error(jqXHR.status, undefined, 'Update network names', jqXHR.responseText);
368
                update_networks_view(servers_data);
369
            }
370
            return false;
277 371
        }
278 372
    });
279 373
    return false;
......
292 386
                    },
293 387
        success: function(data, textStatus, jqXHR) {
294 388
            try {
295
				images = data.images.values;
296
				update_wizard_images();
297
			} catch(err){
298
				ajax_error("NO_IMAGES");
299
			}
389
                images = data.images.values;
390
                update_wizard_images();
391
            } catch(err){
392
                ajax_error("NO_IMAGES");
393
            }
300 394
        }
301 395
    });
302 396
    return false;
303 397
}
304 398

  
305 399
function update_wizard_images() {
306
	if ($("ul#standard-images li").toArray().length + $("ul#custom-images li").toArray().length == 0) {
307
		$.each(images, function(i,image){
308
			var img = $('#image-template').clone().attr("id","img-"+image.id).fadeIn("slow");
309
			img.find("label").attr('for',"img-radio-" + image.id);
310
			img.find(".image-title").text(image.name);
400
    if ($("ul#standard-images li").toArray().length + $("ul#custom-images li").toArray().length == 0) {
401
        $.each(images, function(i,image){
402
            var img = $('#image-template').clone().attr("id","img-"+image.id).fadeIn("slow");
403
            img.find("label").attr('for',"img-radio-" + image.id);
404
            img.find(".image-title").text(image.name);
311 405
            if (image.metadata) {
312 406
                if (image.metadata.values.description != undefined) {
313 407
                    img.find(".description").text(image.metadata.values.description);
314 408
                }
315 409
                if (image.metadata.values.size != undefined) {
316
    			    img.find("#size").text(image.metadata.values.size);
410
                    img.find("#size").text(image.metadata.values.size);
317 411
                }
318 412
            }
319
			img.find("input.radio").attr('id',"img-radio-" + image.id);
320
			if (i==0) img.find("input.radio").attr("checked","checked");
413
            img.find("input.radio").attr('id',"img-radio-" + image.id);
414
            if (i==0) img.find("input.radio").attr("checked","checked");
321 415
            var image_logo = os_icon(image.metadata);
322
			img.find("img.image-logo").attr('src','static/os_logos/'+image_logo+'.png');
416
            img.find("img.image-logo").attr('src','static/icons/os/'+image_logo+'.png');
323 417
            if (image.metadata) {
324 418
                if (image.metadata.values.serverId != undefined) {
325 419
                    img.appendTo("ul#custom-images");
......
329 423
            } else {
330 424
                img.appendTo("ul#standard-images");
331 425
            }
332
		});
333
	}	
426
        });
427
    }
334 428
}
335 429

  
336 430
function update_wizard_flavors(){
337
	// sliders for selecting VM flavor
338
	$("#cpu:range").rangeinput({min:0,
339
							   value:0,
340
							   step:1,
341
							   progress: true,
342
							   max:cpus.length-1});
343
	
344
	$("#storage:range").rangeinput({min:0,
345
							   value:0,
346
							   step:1,
347
							   progress: true,
348
							   max:disks.length-1});
349

  
350
	$("#ram:range").rangeinput({min:0,
351
							   value:0,
352
							   step:1,
353
							   progress: true,
354
							   max:ram.length-1});
355
	$("#small").click();
356

  
357
	// update the indicators when sliding
358
	$("#cpu:range").data().rangeinput.onSlide(function(event,value){
359
		$("#cpu-indicator")[0].value = cpus[Number(value)];
431
    // sliders for selecting VM flavor
432
    $("#cpu:range").rangeinput({min:0,
433
                               value:0,
434
                               step:1,
435
                               progress: true,
436
                               max:cpus.length-1});
437

  
438
    $("#storage:range").rangeinput({min:0,
439
                               value:0,
440
                               step:1,
441
                               progress: true,
442
                               max:disks.length-1});
443

  
444
    $("#ram:range").rangeinput({min:0,
445
                               value:0,
446
                               step:1,
447
                               progress: true,
448
                               max:ram.length-1});
449
    $("#small").click();
450

  
451
    // update the indicators when sliding
452
    $("#cpu:range").data().rangeinput.onSlide(function(event,value){
453
        $("#cpu-indicator")[0].value = cpus[Number(value)];
360 454
        $("#cpu-indicator").addClass('selectedrange');
361
	});
362
	$("#cpu:range").data().rangeinput.change(function(event,value){
363
		$("#cpu-indicator")[0].value = cpus[Number(value)];				
364
		$("#custom").click();
365
        $("#cpu-indicator").removeClass('selectedrange');		
366
	});			
367
	$("#ram:range").data().rangeinput.onSlide(function(event,value){
368
		$("#ram-indicator")[0].value = ram[Number(value)];
455
    });
456
    $("#cpu:range").data().rangeinput.change(function(event,value){
457
        $("#cpu-indicator")[0].value = cpus[Number(value)];
458
        $("#custom").click();
459
        $("#cpu-indicator").removeClass('selectedrange');
460
    });
461
    $("#ram:range").data().rangeinput.onSlide(function(event,value){
462
        $("#ram-indicator")[0].value = ram[Number(value)];
369 463
        $("#ram-indicator").addClass('selectedrange');
370
	});
371
	$("#ram:range").data().rangeinput.change(function(event,value){
372
		$("#ram-indicator")[0].value = ram[Number(value)];				
373
		$("#custom").click();
374
        $("#ram-indicator").removeClass('selectedrange');		
375
	});			
376
	$("#storage:range").data().rangeinput.onSlide(function(event,value){
377
		$("#storage-indicator")[0].value = disks[Number(value)];
464
    });
465
    $("#ram:range").data().rangeinput.change(function(event,value){
466
        $("#ram-indicator")[0].value = ram[Number(value)];
467
        $("#custom").click();
468
        $("#ram-indicator").removeClass('selectedrange');
469
    });
470
    $("#storage:range").data().rangeinput.onSlide(function(event,value){
471
        $("#storage-indicator")[0].value = disks[Number(value)];
378 472
        $("#storage-indicator").addClass('selectedrange');
379
	});
380
	$("#storage:range").data().rangeinput.change(function(event,value){
381
		$("#storage-indicator")[0].value = disks[Number(value)];				
382
		$("#custom").click();
383
        $("#storage-indicator").removeClass('selectedrange');		
384
	});				
473
    });
474
    $("#storage:range").data().rangeinput.change(function(event,value){
475
        $("#storage-indicator")[0].value = disks[Number(value)];
476
        $("#custom").click();
477
        $("#storage-indicator").removeClass('selectedrange');
478
    });
385 479
}
386 480

  
387 481
Array.prototype.unique = function () {
388
	var r = new Array();
389
	o:for(var i = 0, n = this.length; i < n; i++)
390
	{
391
		for(var x = 0, y = r.length; x < y; x++)
392
		{
393
			if(r[x]==this[i])
394
			{
395
				continue o;
396
			}
397
		}
398
		r[r.length] = this[i];
399
	}
400
	return r;
482
    var r = new Array();
483
    o:for(var i = 0, n = this.length; i < n; i++)
484
    {
485
        for(var x = 0, y = r.length; x < y; x++)
486
        {
487
            if(r[x]==this[i])
488
            {
489
                continue o;
490
            }
491
        }
492
        r[r.length] = this[i];
493
    }
494
    return r;
401 495
}
402 496

  
403 497
// get and configure flavor selection
......
410 504
        timeout: TIMEOUT,
411 505
        error: function(jqXHR, textStatus, errorThrown) {
412 506
            try {
413
				ajax_error(jqXHR.status, undefined, 'Update Flavors', jqXHR.responseText);
414
			} catch (err) {
415
				ajax_error(err);
416
			}
507
                ajax_error(jqXHR.status, undefined, 'Update Flavors', jqXHR.responseText);
508
            } catch (err) {
509
                ajax_error(err);
510
            }
417 511
            // start updating vm list
418 512
            update_vms(UPDATE_INTERVAL);
419 513
        },
......
427 521
            cpus = cpus.unique();
428 522
            disks = disks.unique();
429 523
            ram = ram.unique();
430
			update_wizard_flavors();
524
            update_wizard_flavors();
431 525
            // start updating vm list
432 526
            update_vms(UPDATE_INTERVAL);
433 527
        }
......
455 549
    return 0;
456 550
}
457 551

  
552
// return machine entry from serverID
553
function get_machine(serverID) {
554
    for (i=0;i<servers.length;i++){
555
        if (servers[i]['id'] == serverID) {
556
            return servers[i];
557
        }
558
    }
559
    return 0;
560
}
561

  
562
// update the actions in icon view, per server
563
function update_iconview_actions(serverID, server_status) {
564
    // remove .disable from all actions to begin with
565
    $('#machinesview-icon.standard #' + serverID + ' div.actions').children().removeClass('disabled');
566
    // decide which actions should be disabled
567
    for (current_action in actions) {
568
        if (actions[current_action].indexOf(server_status) == -1 ) {
569
            $('#machinesview-icon.standard #' + serverID + ' a.action-' + current_action).addClass('disabled');
570
        }
571
    }
572
}
573

  
458 574
// update the actions in list view
459
function updateActions() {
460
	var states = [];
461
	var on = [];
462
	var checked = $("table.list-machines tbody input[type='checkbox']:checked");
463
	// disable all actions to begin with
464
	for (action in actions) {
465
		$("#action-" + action).removeClass('enabled');
466
	}
467

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

  
480
	// decide which actions should be enabled
481
	for (a in actions) {
482
		var enabled = false;
483
		for (var s =0; s<states.length; s++) {
484
			if (actions[a].indexOf(states[s]) != -1 ) {
485
				enabled = true;
486
			} else {
487
				enabled = false;
488
				break;
489
			}
490
		}
491
		if (enabled)
492
			on[on.length]=a;
493
	}
494
	// enable those actions
495
	for (action in on) {
496
		$("#action-" + on[action]).addClass('enabled');
497
	}
575
function update_listview_actions() {
576
    var states = [];
577
    var on = [];
578
    var checked = $("table.list-machines tbody input[type='checkbox']:checked");
579
    // disable all actions to begin with
580
    $('#machinesview .list div.actions').children().removeClass('enabled');
581

  
582
    // are there multiple machines selected?
583
    if (checked.length>1)
584
        states[0] = 'multiple';
585

  
586
    // check the states of selected machines
587
    checked.each(function(i,checkbox) {
588
        states[states.length] = checkbox.className;
589
        var ip = $("#" + checkbox.id.replace('input-','') + ".ip span.public").text();
590
        if (ip.replace('undefined','').length)
591
            states[states.length] = 'network';
592
    });
593

  
594
    // decide which actions should be enabled
595
    for (a in actions) {
596
        var enabled = false;
597
        for (var s =0; s<states.length; s++) {
598
            if (actions[a].indexOf(states[s]) != -1 ) {
599
                enabled = true;
600
            } else {
601
                enabled = false;
602
                break;
603
            }
604
        }
605
        if (enabled)
606
            on[on.length]=a;
607
    }
608
    // enable those actions
609
    for (action in on) {
610
        $("#action-" + on[action]).addClass('enabled');
611
    }
498 612
}
499 613

  
500 614
//create server action
501 615
function create_vm(machineName, imageRef, flavorRef){
502

  
503 616
    var image_logo = os_icon(get_image(imageRef).metadata);
504

  
617
    var uri = API_URL + '/servers';
505 618
    var payload = {
506 619
        "server": {
507 620
            "name": machineName,
......
512 625
            }
513 626
        }
514 627
    };
515
	var uri = API_URL + '/servers';
516 628

  
517 629
    $.ajax({
518 630
    url: uri,
519 631
    type: "POST",
520
	contentType: "application/json",
632
    contentType: "application/json",
521 633
    dataType: "json",
522 634
    data: JSON.stringify(payload),
523 635
    timeout: TIMEOUT,
......
536 648

  
537 649
// reboot action
538 650
function reboot(serverIDs){
539
	if (!serverIDs.length){
540
		//ajax_success('DEFAULT');
541
		return false;
542
	}	
651
    if (!serverIDs.length){
652
        //ajax_success('DEFAULT');
653
        return false;
654
    }
543 655
    // ajax post reboot call
544 656
    var payload = {
545 657
        "reboot": {"type" : "HARD"}
546 658
    };
659

  
547 660
    var serverID = serverIDs.pop();
548
	
549
	$.ajax({
550
		url: API_URL + '/servers/' + serverID + '/action',
551
		type: "POST",
552
		contentType: "application/json",
553
		dataType: "json",
554
		data: JSON.stringify(payload),
555
		timeout: TIMEOUT,
556
		error: function(jqXHR, textStatus, errorThrown) {
661

  
662
    $.ajax({
663
        url: API_URL + '/servers/' + serverID + '/action',
664
        type: "POST",
665
        contentType: "application/json",
666
        dataType: "json",
667
        data: JSON.stringify(payload),
668
        timeout: TIMEOUT,
669
        error: function(jqXHR, textStatus, errorThrown) {
557 670
                    display_failure(jqXHR.status, serverID, 'Reboot', jqXHR.responseText)
558
				},
559
		success: function(data, textStatus, jqXHR) {
560
					if ( jqXHR.status == '202') {
671
                },
672
        success: function(data, textStatus, jqXHR) {
673
                    if ( jqXHR.status == '202') {
561 674
                        try {
562 675
                            console.info('rebooted ' + serverID);
563 676
                        } catch(err) {}
564
						// indicate that the action succeeded
565
						display_success(serverID);
566
						// continue with the rest of the servers
567
						reboot(serverIDs);
568
					} else {
569
						ajax_error(jqXHR.status, serverID, 'Reboot', jqXHR.responseText);
570
					}
571
				}
677
                        // indicate that the action succeeded
678
                        display_success(serverID);
679
                        // continue with the rest of the servers
680
                        reboot(serverIDs);
681
                    } else {
682
                        ajax_error(jqXHR.status, serverID, 'Reboot', jqXHR.responseText);
683
                    }
684
                }
572 685
    });
573

  
574 686
    return false;
575 687
}
576 688

  
577 689
// shutdown action
578 690
function shutdown(serverIDs) {
579
	if (!serverIDs.length){
580
		//ajax_success('DEFAULT');
581
		return false;
582
	}
691
    if (!serverIDs.length){
692
        //ajax_success('DEFAULT');
693
        return false;
694
    }
583 695
    // ajax post shutdown call
584 696
    var payload = {
585 697
        "shutdown": {}
586 698
    };
587 699

  
588
	var serverID = serverIDs.pop()
700
    var serverID = serverIDs.pop();
701

  
589 702
    $.ajax({
590
	    url: API_URL + '/servers/' + serverID + '/action',
591
	    type: "POST",
592
		contentType: "application/json",
593
	    dataType: "json",
703
        url: API_URL + '/servers/' + serverID + '/action',
704
        type: "POST",
705
        contentType: "application/json",
706
        dataType: "json",
594 707
        data: JSON.stringify(payload),
595 708
        timeout: TIMEOUT,
596 709
        error: function(jqXHR, textStatus, errorThrown) {
......
598 711
                    },
599 712
        success: function(data, textStatus, jqXHR) {
600 713
                    if ( jqXHR.status == '202') {
601
						try {
714
                        try {
602 715
                            console.info('suspended ' + serverID);
603 716
                        } catch(err) {}
604
						// indicate that the action succeeded
605
						display_success(serverID);
606
						// continue with the rest of the servers
717
                        // indicate that the action succeeded
718
                        display_success(serverID);
719
                        // continue with the rest of the servers
607 720
                        shutdown(serverIDs);
608 721
                    } else {
609 722
                        ajax_error(jqXHR.status, serverID, 'Shutdown', jqXHR.responseText);
610 723
                    }
611 724
                }
612 725
    });
613

  
614 726
    return false;
615 727
}
616 728

  
617 729
// destroy action
618 730
function destroy(serverIDs) {
619
	if (!serverIDs.length){
620
		//ajax_success('DEFAULT');
621
		return false;
622
	}
731
    if (!serverIDs.length){
732
        //ajax_success('DEFAULT');
733
        return false;
734
    }
623 735
    // ajax post destroy call can have an empty request body
624 736
    var payload = {};
625 737

  
626
	serverID = serverIDs.pop()
738
    var serverID = serverIDs.pop();
739

  
627 740
    $.ajax({
628
	    url: API_URL + '/servers/' + serverID,
629
	    type: "DELETE",
630
		contentType: "application/json",
631
	    dataType: "json",
741
        url: API_URL + '/servers/' + serverID,
742
        type: "DELETE",
743
        contentType: "application/json",
744
        dataType: "json",
632 745
        data: JSON.stringify(payload),
633 746
        timeout: TIMEOUT,
634 747
        error: function(jqXHR, textStatus, errorThrown) {
......
636 749
                    },
637 750
        success: function(data, textStatus, jqXHR) {
638 751
                    if ( jqXHR.status == '204') {
639
						try {
752
                        try {
640 753
                            console.info('destroyed ' + serverID);
641 754
                        } catch (err) {}
642
						// indicate that the action succeeded
643
						display_success(serverID);
644
						// continue with the rest of the servers
755
                        // indicate that the action succeeded
756
                        display_success(serverID);
757
                        // continue with the rest of the servers
645 758
                        destroy(serverIDs);
646 759
                    } else {
647 760
                        ajax_error(jqXHR.status, serverID, 'Destroy', jqXHR.responseText);
648 761
                    }
649 762
                }
650 763
    });
651

  
652 764
    return false;
653 765
}
654 766

  
655 767
// start action
656 768
function start(serverIDs){
657
	if (!serverIDs.length){
658
		//ajax_success('DEFAULT');
659
		return false;
660
	}	
769
    if (!serverIDs.length){
770
        //ajax_success('DEFAULT');
771
        return false;
772
    }
661 773
    // ajax post start call
662 774
    var payload = {
663 775
        "start": {}
664 776
    };
665 777

  
666
	var serverID = serverIDs.pop()
778
    var serverID = serverIDs.pop();
779

  
667 780
    $.ajax({
668 781
        url: API_URL + '/servers/' + serverID + '/action',
669 782
        type: "POST",
670
		contentType: "application/json",
783
        contentType: "application/json",
671 784
        dataType: "json",
672 785
        data: JSON.stringify(payload),
673 786
        timeout: TIMEOUT,
......
676 789
                    },
677 790
        success: function(data, textStatus, jqXHR) {
678 791
                    if ( jqXHR.status == '202') {
679
					    try {
792
                        try {
680 793
                            console.info('started ' + serverID);
681 794
                        } catch(err) {}
682
						// indicate that the action succeeded
683
						display_success(serverID);
684
						// continue with the rest of the servers						
795
                        // indicate that the action succeeded
796
                        display_success(serverID);
797
                        // continue with the rest of the servers
685 798
                        start(serverIDs);
686 799
                    } else {
687 800
                        ajax_error(jqXHR.status, serverID, 'Start', jqXHR.responseText);
688 801
                    }
689 802
                }
690 803
    });
691

  
692 804
    return false;
693 805
}
694 806

  
......
707 819
    vd.close();
708 820
}
709 821

  
710

  
711 822
// Show VNC console
712
function show_vnc_console(serverID, host, port, password) {
713
    // FIXME: Must be made into parameters, in settings.py
714

  
715
    var params_url = '?host=' + host + '&port=' + port + '&password=' + password ;
716

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

  
823
function show_vnc_console(serverID, serverName, serverIP, host, port, password) {
824
    var params_url = '?machine=' + serverName + '&host_ip=' + serverIP + '&host=' + host + '&port=' + port + '&password=' + password;
825
    var params_window = 'scrollbars=no,' +
826
                        'menubar=no,' +
827
                        'toolbar=no,' +
828
                        'status=no,' +
829
                        'top=0,' +
830
                        'left=0,' +
831
                        'height=' + screen.height + ',' +
832
                        'width=' + screen.width + ',' +
833
                        'fullscreen=yes';
834

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

  
837
    // Restore os icon in list view
838
    osIcon = $('#'+serverID).parent().parent().find('.list-logo');
839
    osIcon.attr('src',osIcon.attr('os'));
719 840
    return false;
720 841
}
721 842

  
722

  
723 843
// console action
724 844
function open_console(serverIDs){
725
	if (!serverIDs.length){
726
		//ajax_success('DEFAULT');
727
		return false;
728
	}
845
    if (!serverIDs.length){
846
        //ajax_success('DEFAULT');
847
        return false;
848
    }
729 849
    // ajax post start call
730 850
    var payload = {
731 851
        "console": {"type": "vnc"}
732 852
    };
733 853

  
734
	var serverID = serverIDs.pop()
854
    var serverID = serverIDs.pop();
855

  
856
    var machine = get_machine(serverID);
857
    var serverName = machine.name;
858
    var serverIP = machine.addresses.values[0].values[0].addr;
859

  
735 860
    $.ajax({
736 861
        url: API_URL + '/servers/' + serverID + '/action',
737 862
        type: "POST",
738
		contentType: "application/json",
863
        contentType: "application/json",
739 864
        dataType: "json",
740 865
        data: JSON.stringify(payload),
741 866
        timeout: TIMEOUT,
......
744 869
                    },
745 870
        success: function(data, textStatus, jqXHR) {
746 871
                    if ( jqXHR.status == '200') {
747
					    try {
872
                        try {
748 873
                            console.info('got_console ' + serverID);
749 874
                        } catch(err) {}
750
						// indicate that the action succeeded
751
                        show_vnc_console(serverID, data.console.host,data.console.port,data.console.password);
752
						display_success(serverID);
875
                        // indicate that the action succeeded
876
                        //show_vnc_console(serverID, serverName, serverIP, data.console.host,data.console.port,data.console.password);
877
show_vnc_console(serverID, serverName, serverIP, data.console.host,data.console.port,data.console.password);
878
                        display_success(serverID);
753 879
                        // hide spinner
754 880
                        $('#' + serverID + ' .spinner').hide();
755
						// continue with the rest of the servers
881
                        // continue with the rest of the servers
756 882
                        open_console(serverIDs);
757 883
                    } else {
758 884
                        ajax_error(jqXHR.status, serverID, 'Console', jqXHR.responseText);
......
762 888
    return false;
763 889
}
764 890

  
765

  
766
// rename server name action
891
// rename server
767 892
function rename(serverID, serverName){
768
	if (!serverID.length){
769
		//ajax_success('DEFAULT');
770
		return false;
771
	}	
893
    if (!serverID.length){
894
        //ajax_success('DEFAULT');
895
        return false;
896
    }
772 897
    // ajax post rename call
773 898
    var payload = {
774 899
        "server": {"name": serverName}
......
777 902
    $.ajax({
778 903
        url: API_URL + '/servers/' + serverID,
779 904
        type: "PUT",
780
		contentType: "application/json",
905
        contentType: "application/json",
781 906
        dataType: "json",
782 907
        data: JSON.stringify(payload),
783 908
        timeout: TIMEOUT,
......
786 911
                    },
787 912
        success: function(data, textStatus, jqXHR) {
788 913
                    if ( jqXHR.status == '204') {
789
					    try {
914
                        try {
790 915
                            console.info('renamed ' + serverID);
791 916
                        } catch(err) {}
792
						// indicate that the action succeeded
793
						display_success(serverID);
917
                        // indicate that the action succeeded
918
                        display_success(serverID);
794 919
                    } else {
795 920
                        ajax_error(jqXHR.status, serverID, 'Rename', jqXHR.responseText);
796 921
                    }
797 922
                }
798 923
    });
799

  
800 924
    return false;
801 925
}
802 926

  
803 927
// get server metadata
804
function get_metadata(serverID) {
928
function get_metadata(serverID, keys_only) {
805 929
    $.ajax({
806 930
        url: API_URL + '/servers/' + serverID + '/meta',
807 931
        type: "GET",
......
810 934
        timeout: TIMEOUT,
811 935
        error: function(jqXHR, textStatus, errorThrown) {
812 936
            try {
813
				ajax_error(jqXHR.status, undefined, 'Get metadata', jqXHR.responseText);
814
			} catch (err) {
815
				ajax_error(err);
816
			}
937
                ajax_error(jqXHR.status, undefined, 'Get metadata', jqXHR.responseText);
938
            } catch (err) {
939
                ajax_error(err);
940
            }
817 941
        },
818 942
        success: function(data, textStatus, jqXHR) {
819 943
            // to list the new results in the edit dialog
820
            list_metadata(data);
821
            list_metadata_keys(serverID, data);
944
            if (keys_only) {
945
                list_metadata_keys(serverID, data.metadata.values);
946
            } else {
947
                list_metadata(data);
948
                list_metadata_keys(serverID, data.metadata.values);
949
            }
950
            //hide spinner
951
            $('#metadata-wizard .large-spinner').hide();
822 952
        }
823 953
    });
824 954
    return false;
......
834 964
        timeout: TIMEOUT,
835 965
        error: function(jqXHR, textStatus, errorThrown) {
836 966
            try {
837
				ajax_error(jqXHR.status, undefined, 'Delete metadata', jqXHR.responseText);
838
			} catch (err) {
839
				ajax_error(err);
840
			}
967
                ajax_error(jqXHR.status, undefined, 'Delete metadata', jqXHR.responseText);
968
            } catch (err) {
969
                ajax_error(err);
970
            }
841 971
        },
842 972
        success: function(data, textStatus, jqXHR) {
843
            // to GET new results and list them in the edit dialog
844
            get_metadata(serverID);
973
            // success: Do nothing, the UI is already updated
845 974
        }
846 975
    });
847 976
    return false;
848 977
}
849 978

  
850

  
851 979
// add metadata key-value pair
852
function add_metadata(serverID, meta_key, meta_value) {
853

  
980
function update_metadata(serverID, meta_key, meta_value) {
854 981
    var payload = {
855 982
        "meta": {
856 983
        }
......
860 987
    $.ajax({
861 988
        url: API_URL + '/servers/' + serverID + '/meta/' + meta_key,
862 989
        type: "PUT",
863
    	contentType: "application/json",
990
        contentType: "application/json",
991
        dataType: "json",
992
        data: JSON.stringify(payload),
993
        timeout: TIMEOUT,
994
        error: function(jqXHR, textStatus, errorThrown) {
995
            try {
996
                ajax_error(jqXHR.status, undefined, 'add metadata', jqXHR.responseText);
997
            } catch (err) {
998
                ajax_error(err);
999
            }
1000
        },
1001
        success: function(data, textStatus, jqXHR) {
1002
            // success: Update icons if meta key is OS
1003
            if (meta_key == "OS") {
1004
                $("#metadata-wizard .machine-icon").attr("src","static/icons/machines/small/" + os_icon_from_value(meta_value) + '-' + $("#metadata-wizard div#on-off").text() + '.png');
1005
                $("#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');
1006
            }
1007
        }
1008
    });
1009
    return false;
1010
}
1011

  
1012
// create network
1013
function create_network(networkName){
1014
    // ajax post start call
1015
    var payload = {
1016
        "network": { "name": networkName }
1017
    };
1018

  
1019
    $.ajax({
1020
        url: API_URL + '/networks',
1021
        type: "POST",
1022
        contentType: "application/json",
1023
        dataType: "json",
1024
        data: JSON.stringify(payload),
1025
        timeout: TIMEOUT,
1026
        error: function(jqXHR, textStatus, errorThrown) {
1027
            try {
1028
                ajax_error(jqXHR.status, undefined, 'Create network', jqXHR.responseText);
1029
            } catch (err) {
1030
                ajax_error(err);
1031
            }
1032
        },
1033
        success: function(data, textStatus, jqXHR) {
1034
            if ( jqXHR.status == '202') {
1035
                try {
1036
                    console.info('created network ' + networkName);
1037
                } catch(err) {}
1038
                update_networks(UPDATE_INTERVAL);
1039
                $("a#networkscreate").overlay().close();
1040
            } else {
1041
                ajax_error(jqXHR.status, undefined, 'Create network', jqXHR.responseText);
1042
            }
1043
        }
1044
    });
1045
    return false;
1046
}
1047

  
1048
// rename network
1049
function rename_network(networkID, networkName){
1050
    if (!networkID.length){
1051
        //ajax_success('DEFAULT');
1052
        return false;
1053
    }
1054
    // prepare payload
1055
    var payload = {
1056
        "network": {"name": networkName}
1057
    };
1058
    // ajax call
1059
    $.ajax({
1060
        url: API_URL + '/networks/' + networkID,
1061
        type: "PUT",
1062
        contentType: "application/json",
1063
        dataType: "json",
1064
        data: JSON.stringify(payload),
1065
        timeout: TIMEOUT,
1066
        error: function(jqXHR, textStatus, errorThrown) {
1067
            try {
1068
                ajax_error(jqXHR.status, undefined, 'Rename network', jqXHR.responseText);
1069
            } catch (err) {
1070
                ajax_error(err);
1071
            }
1072
        },
1073
        success: function(data, textStatus, jqXHR) {
1074
            if ( jqXHR.status == '204') {
1075
                try {
1076
                    console.info('renamed network' + networkID);
1077
                } catch(err) {}
1078
            } else {
1079
                ajax_error(jqXHR.status, undefined, 'Rename network', jqXHR.responseText);
1080
            }
1081
        }
1082
    });
1083
    return false;
1084
}
1085

  
1086
function delete_network(networkIDs){
1087
    if (!networkIDs.length){
1088
        //ajax_success('DEFAULT');
1089
        return false;
1090
    }
1091
    // get a network
1092
    var networkID = networkIDs.pop();
1093
    // ajax post destroy call can have an empty request body
1094
    var payload = {};
1095
    // ajax call
1096
    $.ajax({
1097
        url: API_URL + '/networks/' + networkID,
1098
        type: "DELETE",
1099
        contentType: "application/json",
1100
        dataType: "json",
1101
        data: JSON.stringify(payload),
1102
        timeout: TIMEOUT,
1103
        error: function(jqXHR, textStatus, errorThrown) {
1104
            try {
1105
                ajax_error(jqXHR.status, undefined, 'Delete network', jqXHR.responseText);
1106
            } catch (err) {
1107
                ajax_error(err);
1108
            }
1109
        },
1110
        success: function(data, textStatus, jqXHR) {
1111
            if ( jqXHR.status == '204') {
1112
                try {
1113
                    console.info('deleted network ' + networkID);
1114
                } catch(err) {}
1115
                // continue with the rest of the servers
1116
                delete_network(networkIDs);
1117
            } else {
1118
                ajax_error(jqXHR.status, undefined, 'Delete network', jqXHR.responseText);
1119
            }
1120
        }
1121
    });
1122
    return false;
1123
}
1124

  
1125
function add_server_to_network(networkID, serverIDs) {
1126
    if (!serverIDs.length){
1127
        //ajax_success('DEFAULT');
1128
        update_networks(UPDATE_INTERVAL);
1129
        $("a#add-machines-overlay").overlay().close();
1130
        return false;
1131
    }
1132
    // get a server
1133
    var serverID = serverIDs.pop();
1134
    // prepare payload
1135
    var payload = {
1136
            "add": { "serverRef": serverID }
1137
        };
1138
    // prepare ajax call
1139
    $.ajax({
1140
        url: API_URL + '/networks/' + networkID + '/action',
1141
        type: "POST",
1142
        contentType: "application/json",
864 1143
        dataType: "json",
865 1144
        data: JSON.stringify(payload),
866 1145
        timeout: TIMEOUT,
867 1146
        error: function(jqXHR, textStatus, errorThrown) {
868 1147
            try {
869
				ajax_error(jqXHR.status, undefined, 'add metadata', jqXHR.responseText);
870
			} catch (err) {
871
				ajax_error(err);
872
			}
1148
                ajax_error(jqXHR.status, undefined, 'Add server to network', jqXHR.responseText);
1149
            } catch (err) {
1150
                ajax_error(err);
1151
            }
873 1152
        },
874 1153
        success: function(data, textStatus, jqXHR) {
875
            // to GET new results and list them in the edit dialog
876
            get_metadata(serverID);
1154
            if ( jqXHR.status == '202') {
1155
                try {
1156
                    console.info('added server ' + serverID + ' to network ' + networkID);
1157
                } catch(err) {}
1158
                // continue with the rest of the servers
1159
                add_server_to_network(networkID, serverIDs);
1160
            } else {
1161
                ajax_error(jqXHR.status, undefined, 'Add server to network', jqXHR.responseText);
1162
            }
877 1163
        }
878 1164
    });
879 1165
    return false;
880 1166
}
881 1167

  
1168
function remove_server_from_network(networkIDs, serverIDs) {
1169
    if (!networkIDs.length){
1170
        //ajax_success('DEFAULT');
1171
        return false;
1172
    }
1173
    // get a network and a server
1174
    var networkID = networkIDs.pop();
1175
    var serverID = serverIDs.pop();
1176
    // prepare payload
1177
    var payload = {
1178
            "remove": { "serverRef": serverID }
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff