// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
var g_mySession = null;
var g_sessionKey = null;
var g_role = null; // roles - root, domain-admin, ro-admin, user
var g_username = null;
var g_account = null;
var g_domainid = null;
var g_loginCmdText = null;
var g_enableLogging = false;
var g_timezoneoffset = null;
var g_timezone = null;
var g_supportELB = null;
var g_userPublicTemplateEnabled = "true";
var g_cloudstackversion = null;
var g_queryAsyncJobResultInterval = 3000;
//keyboard keycode
var keycode_Enter = 13;
//XMLHttpResponse.status
var ERROR_ACCESS_DENIED_DUE_TO_UNAUTHORIZED = 401;
var ERROR_INTERNET_NAME_NOT_RESOLVED = 12007;
var ERROR_INTERNET_CANNOT_CONNECT = 12029;
var ERROR_VMOPS_ACCOUNT_ERROR = 531;
// Default password is MD5 hashed. Set the following variable to false to disable this.
var md5Hashed = false;
var md5HashedLogin = false;
//page size for API call (e.g."listXXXXXXX&pagesize=N" )
var pageSize = 20;
var rootAccountId = 1;
var havingSwift = false;
var havingS3 = false;
//async action
var pollAsyncJobResult = function(args) {
$.ajax({
url: createURL("queryAsyncJobResult&jobId=" + args._custom.jobId),
dataType: "json",
async: false,
success: function(json) {
var result = json.queryasyncjobresultresponse;
if (result.jobstatus == 0) {
return; //Job has not completed
}
else {
if (result.jobstatus == 1) { // Succeeded
if(args._custom.getUpdatedItem != null && args._custom.getActionFilter != null) {
args.complete({
data: args._custom.getUpdatedItem(json),
actionFilter: args._custom.getActionFilter()
});
}
else if(args._custom.getUpdatedItem != null && args._custom.getActionFilter == null) {
args.complete({
data: args._custom.getUpdatedItem(json)
});
}
else {
args.complete({ data: json.queryasyncjobresultresponse.jobresult });
}
if(args._custom.fullRefreshAfterComplete == true) {
setTimeout(function() {
$(window).trigger('cloudStack.fullRefresh');
}, 500);
}
if (args._custom.onComplete) {
args._custom.onComplete(json, args._custom);
}
}
else if (result.jobstatus == 2) { // Failed
var msg = (result.jobresult.errortext == null)? "": result.jobresult.errortext;
if (args._custom.getUpdatedItemWhenAsyncJobFails != null && args._custom.getActionFilter != null) {
args.error({message: msg, updatedData: args._custom.getUpdatedItemWhenAsyncJobFails(), actionFilter: args._custom.getActionFilter()});
} else if (args._custom.getUpdatedItemWhenAsyncJobFails != null && args._custom.getActionFilter == null) {
args.error({message: msg, updatedData: args._custom.getUpdatedItemWhenAsyncJobFails()});
}
else {
args.error({message: msg});
}
}
}
},
error: function(XMLHttpResponse) {
args.error();
}
});
}
//API calls
function createURL(apiName, options) {
if (!options) options = {};
var urlString = clientApiUrl + "?" + "command=" + apiName +"&response=json&sessionkey=" + g_sessionKey;
if (cloudStack.context && cloudStack.context.projects && !options.ignoreProject) {
urlString = urlString + '&projectid=' + cloudStack.context.projects[0].id;
}
return urlString;
}
function todb(val) {
return encodeURIComponent(val);
}
//LB provider map
var lbProviderMap = {
"publicLb": {
"non-vpc": ["VirtualRouter", "Netscaler", "F5"],
"vpc": ["VpcVirtualRouter", "Netscaler"]
},
"internalLb": {
"non-vpc": [],
"vpc": ["InternalLbVm"]
}
};
// Role Functions
function isAdmin() {
return (g_role == 1);
}
function isDomainAdmin() {
return (g_role == 2);
}
function isUser() {
return (g_role == 0);
}
function isSelfOrChildDomainUser(username, useraccounttype, userdomainid, iscallerchilddomain) {
if(username == g_username) { //is self
return true;
} else if(isDomainAdmin()
&& iscallerchilddomain
&& (useraccounttype == 0)) { //domain admin to user
return true;
} else if(isDomainAdmin()
&& iscallerchilddomain
&& (userdomainid != g_domainid) ) { //domain admin to subdomain admin and user
return true;
} else {
return false;
}
}
// FUNCTION: Handles AJAX error callbacks. You can pass in an optional function to
// handle errors that are not already handled by this method.
function handleError(XMLHttpResponse, handleErrorCallback) {
// User Not authenticated
if (XMLHttpResponse.status == ERROR_ACCESS_DENIED_DUE_TO_UNAUTHORIZED) {
$("#dialog_session_expired").dialog("open");
}
else if (XMLHttpResponse.status == ERROR_INTERNET_NAME_NOT_RESOLVED) {
$("#dialog_error_internet_not_resolved").dialog("open");
}
else if (XMLHttpResponse.status == ERROR_INTERNET_CANNOT_CONNECT) {
$("#dialog_error_management_server_not_accessible").dialog("open");
}
else if (XMLHttpResponse.status == ERROR_VMOPS_ACCOUNT_ERROR && handleErrorCallback != undefined) {
handleErrorCallback();
}
else if (handleErrorCallback != undefined) {
handleErrorCallback();
}
else {
var errorMsg = parseXMLHttpResponse(XMLHttpResponse);
$("#dialog_error").text(_s(errorMsg)).dialog("open");
}
}
function parseXMLHttpResponse(XMLHttpResponse) {
if(isValidJsonString(XMLHttpResponse.responseText) == false) {
return "";
}
//var json = jQuery.parseJSON(XMLHttpResponse.responseText);
var json = JSON.parse(XMLHttpResponse.responseText);
if (json != null) {
var property;
for(property in json) {
var errorObj = json[property];
if(errorObj.errorcode == 401 && errorObj.errortext == "unable to verify user credentials and/or request signature")
return _l('label.session.expired');
else
return _s(errorObj.errortext);
}
}
else {
return "";
}
}
function isValidJsonString(str) {
try {
JSON.parse(str);
}
catch (e) {
return false;
}
return true;
}
cloudStack.validate = {
vmHostName: function(args) {
// 1 ~ 63 characters long
// ASCII letters 'a' through 'z', 'A' through 'Z', digits '0' through '9', hyphen ('-')
// must start with a letter
// must end with a letter or a digit (must not end with a hyphen)
var regexp = /^[a-zA-Z]{1}[a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]{0,1}$/;
var b = regexp.test(args); //true or false
if(b == false)
cloudStack.dialog.notice({ message: 'message.validate.instance.name' });
return b;
}
}
cloudStack.preFilter = {
createTemplate: function(args) {
if(isAdmin()) {
args.$form.find('.form-item[rel=isPublic]').css('display', 'inline-block');
args.$form.find('.form-item[rel=isFeatured]').css('display', 'inline-block');
}
else {
if (g_userPublicTemplateEnabled == "true") {
args.$form.find('.form-item[rel=isPublic]').css('display', 'inline-block');
}
else {
args.$form.find('.form-item[rel=isPublic]').hide();
}
args.$form.find('.form-item[rel=isFeatured]').hide();
}
},
addLoadBalancerDevice: function(args) { //add netscaler device OR add F5 device
args.$form.find('.form-item[rel=dedicated]').bind('change', function() {
var $dedicated = args.$form.find('.form-item[rel=dedicated]');
var $capacity = args.$form.find('.form-item[rel=capacity]');
if($dedicated.find('input[type=checkbox]:checked').length > 0) {
$capacity.hide();
$capacity.find('input[type=text]').val('1');
}
else if($dedicated.find('input[type=checkbox]:unchecked').length > 0) {
$capacity.css('display', 'inline-block');
$capacity.find('input[type=text]').val('');
}
});
args.$form.change();
}
}
cloudStack.actionFilter = {
guestNetwork: function(args) {
var jsonObj = args.context.item;
var allowedActions = [];
allowedActions.push('replaceacllist');
if(jsonObj.type == 'Isolated') {
allowedActions.push('edit'); //only Isolated network is allowed to upgrade to a different network offering (Shared network is not allowed to)
allowedActions.push('restart');
allowedActions.push('remove');
}
else if(jsonObj.type == 'Shared') {
if(isAdmin()) {
allowedActions.push('restart');
allowedActions.push('remove');
}
}
return allowedActions;
}
}
var roleTypeUser = "0";
var roleTypeAdmin = "1";
var roleTypeDomainAdmin = "2";
cloudStack.converters = {
convertBytes: function(bytes) {
if (bytes < 1024 * 1024) {
return (bytes / 1024).toFixed(2) + " KB";
} else if (bytes < 1024 * 1024 * 1024) {
return (bytes / 1024 / 1024).toFixed(2) + " MB";
} else if (bytes < 1024 * 1024 * 1024 * 1024) {
return (bytes / 1024 / 1024 / 1024).toFixed(2) + " GB";
} else {
return (bytes / 1024 / 1024 / 1024 / 1024).toFixed(2) + " TB";
}
},
toLocalDate: function(UtcDate) {
var localDate = "";
if (UtcDate != null && UtcDate.length > 0) {
var disconnected = new Date();
disconnected.setISO8601(UtcDate);
if(g_timezoneoffset != null)
localDate = disconnected.getTimePlusTimezoneOffset(g_timezoneoffset);
else
localDate = disconnected.toUTCString();
// localDate = disconnected.getTimePlusTimezoneOffset(0);
}
return localDate;
},
toBooleanText: function(booleanValue) {
if(booleanValue == true)
return "Yes";
return "No";
},
convertHz: function(hz) {
if (hz == null)
return "";
if (hz < 1000) {
return hz + " MHz";
} else {
return (hz / 1000).toFixed(2) + " GHz";
}
},
toDayOfWeekDesp: function(dayOfWeek) {
if (dayOfWeek == "1")
return "Sunday";
else if (dayOfWeek == "2")
return "Monday";
else if (dayOfWeek == "3")
return "Tuesday";
else if (dayOfWeek == "4")
return "Wednesday";
else if (dayOfWeek == "5")
return "Thursday"
else if (dayOfWeek == "6")
return "Friday";
else if (dayOfWeek == "7")
return "Saturday";
},
toDayOfWeekDesp: function(dayOfWeek) {
if (dayOfWeek == "1")
return "Sunday";
else if (dayOfWeek == "2")
return "Monday";
else if (dayOfWeek == "3")
return "Tuesday";
else if (dayOfWeek == "4")
return "Wednesday";
else if (dayOfWeek == "5")
return "Thursday"
else if (dayOfWeek == "6")
return "Friday";
else if (dayOfWeek == "7")
return "Saturday";
},
toNetworkType: function(usevirtualnetwork) {
if(usevirtualnetwork == true || usevirtualnetwork == "true")
return "Public";
else
return "Direct";
},
toRole: function(type) {
if (type == roleTypeUser) {
return "User";
} else if (type == roleTypeAdmin) {
return "Admin";
} else if (type == roleTypeDomainAdmin) {
return "Domain-Admin";
}
},
toAlertType: function(alertCode) {
switch (alertCode) {
case 0 : return _l('label.memory');
case 1 : return _l('label.cpu');
case 2 : return _l('label.storage');
case 3 : return _l('label.primary.storage');
case 4 : return _l('label.public.ips');
case 5 : return _l('label.management.ips');
case 6 : return _l('label.secondary.storage');
case 7 : return _l('label.host');
case 9 : return _l('label.domain.router');
case 10 : return _l('label.console.proxy');
// These are old values -- can be removed in the future
case 8 : return "User VM";
case 11 : return "Routing Host";
case 12 : return "Storage";
case 13 : return "Usage Server";
case 14 : return "Management Server";
case 15 : return "Domain Router";
case 16 : return "Console Proxy";
case 17 : return "User VM";
case 18 : return "VLAN";
case 19 : return "Secondary Storage VM";
case 20 : return "Usage Server";
case 21 : return "Storage";
case 22 : return "Update Resource Count";
case 23 : return "Usage Sanity Result";
case 24 : return "Direct Attached Public IP";
case 25 : return "Local Storage";
case 26 : return "Resource Limit Exceeded";
}
},
toCapacityCountType:function(capacityCode){
switch(capacityCode){
case 0 : return _l('label.memory');
case 1 : return _l('label.cpu');
case 2 : return _l('label.storage');
case 3 : return _l('label.primary.storage');
case 4 : return _l('label.public.ips');
case 5 : return _l('label.management.ips');
case 6 : return _l('label.secondary.storage');
case 7 : return _l('label.vlan');
case 8 : return _l('label.direct.ips');
case 9 : return _l('label.local.storage');
case 10 : return "Routing Host";
case 11 : return "Storage";
case 12 : return "Usage Server";
case 13 : return "Management Server";
case 14 : return "Domain Router";
case 15 : return "Console Proxy";
case 16 : return "User VM";
case 17 : return "VLAN";
case 18 : return "Secondary Storage VM";
}
},
convertByType: function(alertCode, value) {
switch(alertCode) {
case 0: return cloudStack.converters.convertBytes(value);
case 1: return cloudStack.converters.convertHz(value);
case 2: return cloudStack.converters.convertBytes(value);
case 3: return cloudStack.converters.convertBytes(value);
case 6: return cloudStack.converters.convertBytes(value);
case 9: return cloudStack.converters.convertBytes(value);
case 11: return cloudStack.converters.convertBytes(value);
}
return value;
}
}
//data parameter passed to API call in listView
function listViewDataProvider(args, data) {
//search
if(args.filterBy != null) {
if(args.filterBy.advSearch != null && typeof(args.filterBy.advSearch) == "object") { //advanced search
for(var key in args.filterBy.advSearch) {
if(key == 'tagKey' && args.filterBy.advSearch[key].length > 0) {
$.extend(data, {
'tags[0].key': args.filterBy.advSearch[key]
});
}
else if(key == 'tagValue' && args.filterBy.advSearch[key].length > 0) {
$.extend(data, {
'tags[0].value': args.filterBy.advSearch[key]
});
}
else if(args.filterBy.advSearch[key] != null && args.filterBy.advSearch[key].length > 0) {
data[key] = args.filterBy.advSearch[key]; //do NOT use $.extend(data, { key: args.filterBy.advSearch[key] }); which will treat key variable as "key" string
}
}
}
else if(args.filterBy.search != null && args.filterBy.search.by != null && args.filterBy.search.value != null) { //basic search
switch(args.filterBy.search.by) {
case "name":
if(args.filterBy.search.value.length > 0) {
$.extend(data, {
keyword: args.filterBy.search.value
});
}
break;
}
}
}
//pagination
$.extend(data, {
listAll: true,
page: args.page,
pagesize: pageSize
});
}
//used by infrastruct page and network page
var addExtraPropertiesToGuestNetworkObject = function(jsonObj) {
jsonObj.networkdomaintext = jsonObj.networkdomain;
jsonObj.networkofferingidText = jsonObj.networkofferingid;
if(jsonObj.acltype == "Domain") {
if(jsonObj.domainid == rootAccountId)
jsonObj.scope = "All";
else
jsonObj.scope = "Domain (" + jsonObj.domain + ")";
}
else if (jsonObj.acltype == "Account"){
if(jsonObj.project != null)
jsonObj.scope = "Account (" + jsonObj.domain + ", " + jsonObj.project + ")";
else
jsonObj.scope = "Account (" + jsonObj.domain + ", " + jsonObj.account + ")";
}
if(jsonObj.vlan == null && jsonObj.broadcasturi != null) {
jsonObj.vlan = jsonObj.broadcasturi.replace("vlan://", "");
}
}
//find service object in network object
function ipFindNetworkServiceByName(pName, networkObj) {
if(networkObj == null)
return null;
if(networkObj.service != null) {
for(var i=0; i