cloudstack/ui/legacy/scripts/templates.js
Rohit Yadav 02f80d3370
ui: deprecate old UI and move to legacy to be served at /client/legacy (#4518)
As notified in the 4.14.0.0 release notes, this deprecates the legacy UI
and moves it under the ui/legacy directory which will be served at
/client/legacy URL path. This will also ensure that users upgrading or
installing 4.15.0.0 will get the new UI by default. This will also make
it simpler to remove the old UI for future 4.16/master releases.

Co-authored-by: Daan Hoogland <daan.hoogland@shapeblue.com>
2020-12-05 20:36:59 +05:30

4217 lines
255 KiB
JavaScript

// 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.
(function(cloudStack, $) {
var ostypeObjs;
var previousCollection = [];
var previousFilterType = null;
cloudStack.sections.templates = {
title: 'label.menu.templates',
id: 'templates',
sectionSelect: {
label: 'label.select-view'
},
sections: {
templates: {
type: 'select',
title: 'label.menu.templates',
listView: {
id: 'templates',
label: 'label.menu.templates',
filters: {
all: {
preFilter: function(args) {
if (isAdmin()|| isDomainAdmin()) //"listTemplates&templatefilter=all" only for root-admin and domain-admin. Domain-admin is able to see all templates in his domain.
return true;
else
return false;
},
label: 'ui.listView.filters.all'
},
mine: {
label: 'ui.listView.filters.mine'
},
shared: {
label: 'label.shared'
},
featured: {
label: 'label.featured'
},
community: {
label: 'label.community'
}
},
preFilter: function() {
if (isAdmin()||isDomainAdmin()) {
return []
}
return ['account']
},
fields: {
name: {
label: 'label.name'
},
hypervisor: {
label: 'label.hypervisor'
},
ostypename: {
label: 'label.os.type'
},
account: {
label: 'label.account'
}
},
advSearchFields: {
name: {
label: 'label.name'
},
zoneid: {
label: 'label.zone',
select: function(args) {
$.ajax({
url: createURL('listZones'),
data: {
listAll: true
},
success: function(json) {
var zones = json.listzonesresponse.zone ? json.listzonesresponse.zone : [];
args.response.success({
data: $.map(zones, function(zone) {
return {
id: zone.id,
description: zone.name
};
})
});
}
});
}
},
tagKey: {
label: 'label.tag.key'
},
tagValue: {
label: 'label.tag.value'
}
},
reorder: cloudStack.api.actions.sort('updateTemplate', 'templates'),
actions: {
add: {
label: 'label.add',
messages: {
notification: function(args) {
return 'label.action.register.template';
}
},
createForm: {
title: 'label.action.register.template',
docID: 'helpNetworkOfferingName',
preFilter: cloudStack.preFilter.createTemplate,
fields: {
url: {
label: 'label.url',
docID: 'helpRegisterTemplateURL',
validation: {
required: true
}
},
name: {
label: 'label.name',
docID: 'helpRegisterTemplateName',
validation: {
required: true
}
},
description: {
label: 'label.description',
docID: 'helpRegisterTemplateDescription',
validation: {
required: true
}
},
zone: {
label: 'label.zone',
docID: 'helpRegisterTemplateZone',
isMultiple: true,
validation: {
allzonesonly: true
},
select: function(args) {
if(g_regionsecondaryenabled == true) {
args.response.success({
data: [{
id: -1,
description: "All Zones"
}]
});
} else {
$.ajax({
url: createURL("listZones&available=true"),
dataType: "json",
async: true,
success: function(json) {
var zoneObjs = [];
var items = json.listzonesresponse.zone;
if (items != null) {
for (var i = 0; i < items.length; i++) {
zoneObjs.push({
id: items[i].id,
description: items[i].name
});
}
}
if (isAdmin() && !(cloudStack.context.projects && cloudStack.context.projects[0])) {
zoneObjs.unshift({
id: -1,
description: "All Zones"
});
}
args.response.success({
data: zoneObjs
});
}
});
}
}
},
hypervisor: {
label: 'label.hypervisor',
docID: 'helpRegisterTemplateHypervisor',
dependsOn: 'zone',
select: function(args) {
if (args.zone == null)
return;
// We want only distinct Hypervisor entries to be visible to the user
var items = [];
var distinctHVNames = [];
var length = 1;
// When only one zone is selected, args.zone is NOT an array.
if (Object.prototype.toString.call( args.zone ) === '[object Array]')
length = args.zone.length;
for (var index = 0; index < length; index++)
{
var zoneId;
if (length == 1)
zoneId = args.zone;
else
zoneId = args.zone[index];
var apiCmd;
if (zoneId == -1) { //All Zones
apiCmd = "listHypervisors";
}
else {
apiCmd = "listHypervisors&zoneid=" + zoneId;
}
$.ajax({
url: createURL(apiCmd),
dataType: "json",
async: false,
success: function(json) {
var hypervisorObjs = json.listhypervisorsresponse.hypervisor;
$(hypervisorObjs).each(function() {
// Only if this hypervisor isn't already part of this
// list, then add to the drop down
if (distinctHVNames.indexOf(this.name) < 0 ){
distinctHVNames.push(this.name);
items.push({
id: this.name,
description: this.name
});
}
});
}
});
}
args.$select.change(function() {
var $form = $(this).closest('form');
if ($(this).val() == "VMware") {
$form.find('.form-item[rel=rootDiskControllerType]').hide();
$form.find('.form-item[rel=nicAdapterType]').hide();
$form.find('.form-item[rel=keyboardType]').css('display', 'inline-block');
$form.find('.form-item[rel=xenserverToolsVersion61plus]').hide();
$form.find('.form-item[rel=rootDiskControllerTypeKVM]').hide();
$form.find('.form-item[rel=directdownload]').hide();
$form.find('.form-item[rel=requireshvm]').hide();
} else if ($(this).val() == "XenServer") {
$form.find('.form-item[rel=rootDiskControllerType]').hide();
$form.find('.form-item[rel=nicAdapterType]').hide();
$form.find('.form-item[rel=keyboardType]').hide();
$form.find('.form-item[rel=rootDiskControllerTypeKVM]').hide();
$form.find('.form-item[rel=directdownload]').hide();
$form.find('.form-item[rel=requireshvm]').css('display', 'inline-block');
if (isAdmin()) {
$form.find('.form-item[rel=xenserverToolsVersion61plus]').css('display', 'inline-block');
}
} else if ($(this).val() == "KVM") {
$form.find('.form-item[rel=rootDiskControllerType]').hide();
$form.find('.form-item[rel=nicAdapterType]').hide();
$form.find('.form-item[rel=keyboardType]').hide();
$form.find('.form-item[rel=xenserverToolsVersion61plus]').hide();
$form.find('.form-item[rel=rootDiskControllerTypeKVM]').css('display', 'inline-block');
$('#label_root_disk_controller').prop('selectedIndex', 2);
$form.find('.form-item[rel=requireshvm]').css('display', 'inline-block');
if (isAdmin()) {
$form.find('.form-item[rel=directdownload]').css('display', 'inline-block');
}
} else {
$form.find('.form-item[rel=rootDiskControllerType]').hide();
$form.find('.form-item[rel=nicAdapterType]').hide();
$form.find('.form-item[rel=keyboardType]').hide();
$form.find('.form-item[rel=xenserverToolsVersion61plus]').hide();
$form.find('.form-item[rel=rootDiskControllerTypeKVM]').hide();
$form.find('.form-item[rel=directdownload]').hide();
$form.find('.form-item[rel=requireshvm]').css('display', 'inline-block');
}
});
items.push({
id: "Any",
description: "Any"
});
args.response.success({
data: items
});
args.$select.trigger('change');
}
},
// fields for hypervisor == XenServer (starts here)
xenserverToolsVersion61plus: {
label: 'label.xenserver.tools.version.61.plus',
isBoolean: true,
isChecked: function (args) {
var b = true;
if (isAdmin()) {
$.ajax({
url: createURL('listConfigurations'),
data: {
name: 'xenserver.pvdriver.version'
},
async: false,
success: function (json) {
if (json.listconfigurationsresponse.configuration != null && json.listconfigurationsresponse.configuration[0].value != 'xenserver61') {
b = false;
}
}
});
}
return b;
},
isHidden: true
},
// fields for hypervisor == XenServer (ends here)
// fields for hypervisor == "KVM" (starts here)
// Direct Download
directdownload : {
label: 'label.direct.download',
docID: 'helpRegisterTemplateDirectDownload',
isBoolean: true,
dependsOn: 'hypervisor',
isHidden: true
},
checksum: {
label: 'label.checksum',
dependsOn: 'directdownload',
isHidden: true
},
// Direct Download - End
rootDiskControllerTypeKVM: {
label: 'label.root.disk.controller',
isHidden: true,
select: function(args) {
var items = []
items.push({
id: "",
description: ""
});
items.push({
id: "ide",
description: "ide"
});
items.push({
id: "osdefault",
description: "osdefault"
});
items.push({
id: "scsi",
description: "virtio-scsi"
});
items.push({
id: "virtio",
description: "virtio"
});
args.response.success({
data: items
});
}
},
// fields for hypervisor == "KVM" (ends here)
// fields for hypervisor == "VMware" (starts here)
rootDiskControllerType: {
label: 'label.root.disk.controller',
isHidden: true,
select: function(args) {
var items = []
items.push({
id: "",
description: ""
});
items.push({
id: "scsi",
description: "scsi"
});
items.push({
id: "ide",
description: "ide"
});
items.push({
id: "osdefault",
description: "osdefault"
});
items.push({
id: "pvscsi",
description: "pvscsi"
});
items.push({
id: "lsilogic",
description: "lsilogic"
});
items.push({
id: "lsisas1068",
description: "lsilogicsas"
});
items.push({
id: "buslogic",
description: "buslogic"
});
args.response.success({
data: items
});
}
},
nicAdapterType: {
label: 'label.nic.adapter.type',
isHidden: true,
select: function(args) {
var items = []
items.push({
id: "",
description: ""
});
items.push({
id: "E1000",
description: "E1000"
});
items.push({
id: "PCNet32",
description: "PCNet32"
});
items.push({
id: "Vmxnet2",
description: "Vmxnet2"
});
items.push({
id: "Vmxnet3",
description: "Vmxnet3"
});
args.response.success({
data: items
});
}
},
keyboardType: {
label: 'label.keyboard.type',
isHidden: true,
select: function(args) {
var items = []
items.push({
id: "",
description: ""
});
for (var key in cloudStackOptions.keyboardOptions) {
items.push({
id: key,
description: _l(cloudStackOptions.keyboardOptions[key])
});
}
args.response.success({
data: items
});
}
},
// fields for hypervisor == "VMware" (ends here)
format: {
label: 'label.format',
docID: 'helpRegisterTemplateFormat',
dependsOn: 'hypervisor',
select: function(args) {
var items = [];
if (args.hypervisor == "XenServer") {
//formatSelect.append("<option value='VHD'>VHD</option>");
items.push({
id: 'VHD',
description: 'VHD'
});
} else if (args.hypervisor == "VMware") {
//formatSelect.append("<option value='OVA'>OVA</option>");
items.push({
id: 'OVA',
description: 'OVA'
});
} else if (args.hypervisor == "KVM") {
//formatSelect.append("<option value='QCOW2'>QCOW2</option>");
items.push({
id: 'QCOW2',
description: 'QCOW2'
});
items.push({
id: 'RAW',
description: 'RAW'
});
items.push({
id: 'VHD',
description: 'VHD'
});
items.push({
id: 'VMDK',
description: 'VMDK'
});
} else if (args.hypervisor == "BareMetal") {
//formatSelect.append("<option value='BareMetal'>BareMetal</option>");
items.push({
id: 'BareMetal',
description: 'BareMetal'
});
} else if (args.hypervisor == "Ovm") {
//formatSelect.append("<option value='RAW'>RAW</option>");
items.push({
id: 'RAW',
description: 'RAW'
});
} else if (args.hypervisor == "LXC") {
//formatSelect.append("<option value='TAR'>TAR</option>");
items.push({
id: 'TAR',
description: 'TAR'
});
} else if (args.hypervisor == "Hyperv") {
items.push({
id: 'VHD',
description: 'VHD'
});
items.push({
id: 'VHDX',
description: 'VHDX'
});
}
args.response.success({
data: items
});
}
},
osTypeId: {
label: 'label.os.type',
docID: 'helpRegisterTemplateOSType',
select: function(args) {
$.ajax({
url: createURL("listOsTypes"),
dataType: "json",
async: true,
success: function(json) {
var ostypeObjs = json.listostypesresponse.ostype;
args.response.success({
data: ostypeObjs
});
}
});
}
},
isExtractable: {
label: "label.extractable",
docID: 'helpRegisterTemplateExtractable',
isBoolean: true
},
isPasswordEnabled: {
label: "label.password.enabled",
docID: 'helpRegisterTemplatePasswordEnabled',
isBoolean: true
},
isdynamicallyscalable: {
label: "label.dynamically.scalable",
docID: 'helpRegisterTemplateDynamicallyScalable',
isBoolean: true
},
isPublic: {
label: "label.public",
docID: 'helpRegisterTemplatePublic',
isBoolean: true,
isHidden: true
},
isFeatured: {
label: "label.featured",
docID: 'helpRegisterTemplateFeatured',
isBoolean: true,
isHidden: true
},
isrouting: {
label: 'label.routing',
docID: 'helpRegisterTemplateRouting',
isBoolean: true,
isHidden: true
},
requireshvm: {
label: 'label.hvm',
docID: 'helpRegisterTemplateHvm',
isBoolean: true,
isHidden: false,
isChecked: true
}
}
},
action: function(args) {
var zones = "";
if (Object.prototype.toString.call( args.data.zone ) === '[object Array]'){
zones = args.data.zone.join(",");
}
else
zones = args.data.zone;
var data = {
name: args.data.name,
displayText: args.data.description,
url: args.data.url,
zoneids: zones,
format: args.data.format,
isextractable: (args.data.isExtractable == "on"),
passwordEnabled: (args.data.isPasswordEnabled == "on"),
isdynamicallyscalable: (args.data.isdynamicallyscalable == "on"),
osTypeId: args.data.osTypeId,
hypervisor: args.data.hypervisor
};
if (args.$form.find('.form-item[rel=isPublic]').css("display") != "none") {
$.extend(data, {
ispublic: (args.data.isPublic == "on")
});
}
if (args.$form.find('.form-item[rel=requireshvm]').css("display") != "none") {
$.extend(data, {
requireshvm: (args.data.requireshvm == "on")
});
}
if (args.$form.find('.form-item[rel=isFeatured]').css("display") != "none") {
$.extend(data, {
isfeatured: (args.data.isFeatured == "on")
});
}
if (args.$form.find('.form-item[rel=isrouting]').is(':visible')) {
$.extend(data, {
isrouting: (args.data.isrouting === 'on')
});
}
// for hypervisor == XenServer (starts here)
if (args.$form.find('.form-item[rel=xenserverToolsVersion61plus]').css("display") != "none") {
$.extend(data, {
'details[0].hypervisortoolsversion': (args.data.xenserverToolsVersion61plus == "on") ? "xenserver61" : "xenserver56"
});
}
// for hypervisor == XenServer (ends here)
// for hypervisor == KVM (starts here)
if (args.$form.find('.form-item[rel=rootDiskControllerTypeKVM]').css("display") != "none" && args.data.rootDiskControllerTypeKVM != "") {
$.extend(data, {
'details[0].rootDiskController': args.data.rootDiskControllerTypeKVM
});
}
if (args.$form.find('.form-item[rel=directdownload]').css("display") != "none" && args.data.directdownload != "") {
$.extend(data, {
'directdownload': (args.data.directdownload == "on") ? "true" : "false",
'checksum': args.data.checksum
});
}
// for hypervisor == KVM (ends here)
// for hypervisor == VMware (starts here)
if (args.$form.find('.form-item[rel=rootDiskControllerType]').css("display") != "none" && args.data.rootDiskControllerType != "") {
$.extend(data, {
'details[0].rootDiskController': args.data.rootDiskControllerType
});
}
if (args.$form.find('.form-item[rel=nicAdapterType]').css("display") != "none" && args.data.nicAdapterType != "") {
$.extend(data, {
'details[0].nicAdapter': args.data.nicAdapterType
});
}
if (args.$form.find('.form-item[rel=keyboardType]').css("display") != "none" && args.data.keyboardType != "") {
$.extend(data, {
'details[0].keyboard': args.data.keyboardType
});
}
// for hypervisor == VMware (ends here)
$.ajax({
url: createURL('registerTemplate'),
data: data,
success: function(json) {
var items = json.registertemplateresponse.template; //items might have more than one array element if it's create templates for all zones.
args.response.success({
data: items[0]
});
},
error: function(XMLHttpResponse) {
var errorMsg = parseXMLHttpResponse(XMLHttpResponse);
args.response.error(errorMsg);
}
});
},
notification: {
poll: function(args) {
args.complete();
}
}
},
uploadTemplateFromLocal: {
isHeader: true,
label: 'label.upload.from.local',
messages: {
notification: function(args) {
return 'label.upload.template.from.local';
}
},
createForm: {
title: 'label.upload.template.from.local',
preFilter: cloudStack.preFilter.createTemplate,
fileUpload: {
getURL: function(args) {
args.data = args.formData;
var data = {
name: args.data.name,
displayText: args.data.description,
zoneid: args.data.zone,
format: args.data.format,
isextractable: (args.data.isExtractable == "on"),
passwordEnabled: (args.data.isPasswordEnabled == "on"),
isdynamicallyscalable: (args.data.isdynamicallyscalable == "on"),
osTypeId: args.data.osTypeId,
hypervisor: args.data.hypervisor
};
// for hypervisor == XenServer (starts here)
if (args.$form.find('.form-item[rel=xenserverToolsVersion61plus]').css("display") != "none") {
$.extend(data, {
'details[0].hypervisortoolsversion': (args.data.xenserverToolsVersion61plus == "on") ? "xenserver61" : "xenserver56"
});
}
// for hypervisor == XenServer (ends here)
// for hypervisor == KVM (starts here)
if (args.$form.find('.form-item[rel=rootDiskControllerTypeKVM]').css("display") != "none" && args.data.rootDiskControllerTypeKVM != "") {
$.extend(data, {
'details[0].rootDiskController': args.data.rootDiskControllerTypeKVM
});
}
// for hypervisor == KVM (ends here)
// for hypervisor == VMware (starts here)
if (args.$form.find('.form-item[rel=rootDiskControllerType]').css("display") != "none" && args.data.rootDiskControllerType != "") {
$.extend(data, {
'details[0].rootDiskController': args.data.rootDiskControllerType
});
}
if (args.$form.find('.form-item[rel=nicAdapterType]').css("display") != "none" && args.data.nicAdapterType != "") {
$.extend(data, {
'details[0].nicAdapter': args.data.nicAdapterType
});
}
if (args.$form.find('.form-item[rel=keyboardType]').css("display") != "none" && args.data.keyboardType != "") {
$.extend(data, {
'details[0].keyboard': args.data.keyboardType
});
}
// for hypervisor == VMware (ends here)
if (args.$form.find('.form-item[rel=isPublic]').css("display") != "none") {
$.extend(data, {
ispublic: (args.data.isPublic == "on")
});
}
if (args.$form.find('.form-item[rel=requireshvm]').css("display") != "none") {
$.extend(data, {
requireshvm: (args.data.requireshvm == "on")
});
}
if (args.$form.find('.form-item[rel=isFeatured]').css("display") != "none") {
$.extend(data, {
isfeatured: (args.data.isFeatured == "on")
});
}
if (args.$form.find('.form-item[rel=isrouting]').is(':visible')) {
$.extend(data, {
isrouting: (args.data.isrouting === 'on')
});
}
$.ajax({
url: createURL('getUploadParamsForTemplate'),
data: data,
async: false,
success: function(json) {
var uploadparams = json.postuploadtemplateresponse.getuploadparams;
var templateId = uploadparams.id;
args.response.success({
url: uploadparams.postURL,
ajaxPost: true,
data: {
'X-signature': uploadparams.signature,
'X-expires': uploadparams.expires,
'X-metadata': uploadparams.metadata
}
});
}
});
},
postUpload: function(args) {
if(args.error) {
args.response.error(args.errorMsg);
} else {
cloudStack.dialog.notice({
message: "This template file has been uploaded. Please check its status at Templates menu > " + args.data.name + " > Zones tab > click a zone > Status field and Ready field."
});
args.response.success();
}
}
},
fields: {
templateFileUpload: {
label: 'label.local.file',
isFileUpload: true,
validation: {
required: true
}
},
name: {
label: 'label.name',
docID: 'helpRegisterTemplateName',
validation: {
required: true
}
},
description: {
label: 'label.description',
docID: 'helpRegisterTemplateDescription',
validation: {
required: true
}
},
zone: {
label: 'label.zone',
docID: 'helpRegisterTemplateZone',
select: function(args) {
$.ajax({
url: createURL("listZones&available=true"),
dataType: "json",
async: true,
success: function(json) {
var zoneObjs = json.listzonesresponse.zone;
args.response.success({
descriptionField: 'name',
data: zoneObjs
});
}
});
}
},
hypervisor: {
label: 'label.hypervisor',
docID: 'helpRegisterTemplateHypervisor',
dependsOn: 'zone',
select: function(args) {
if (args.zone == null)
return;
var apiCmd;
if (args.zone == -1) { //All Zones
//apiCmd = "listHypervisors&zoneid=-1"; //"listHypervisors&zoneid=-1" has been changed to return only hypervisors available in all zones (bug 8809)
apiCmd = "listHypervisors";
} else {
apiCmd = "listHypervisors&zoneid=" + args.zone;
}
$.ajax({
url: createURL(apiCmd),
dataType: "json",
async: false,
success: function(json) {
var hypervisorObjs = json.listhypervisorsresponse.hypervisor;
var items = [];
$(hypervisorObjs).each(function() {
items.push({
id: this.name,
description: this.name
});
});
args.response.success({
data: items
});
}
});
args.$select.change(function() {
var $form = $(this).closest('form');
if ($(this).val() == "VMware") {
$form.find('.form-item[rel=rootDiskControllerType]').css('display', 'inline-block');
$form.find('.form-item[rel=nicAdapterType]').css('display', 'inline-block');
$form.find('.form-item[rel=keyboardType]').css('display', 'inline-block');
$form.find('.form-item[rel=xenserverToolsVersion61plus]').hide();
$form.find('.form-item[rel=rootDiskControllerTypeKVM]').hide();
$form.find('.form-item[rel=requireshvm]').hide();
} else if ($(this).val() == "XenServer") {
$form.find('.form-item[rel=rootDiskControllerType]').hide();
$form.find('.form-item[rel=nicAdapterType]').hide();
$form.find('.form-item[rel=keyboardType]').hide();
$form.find('.form-item[rel=rootDiskControllerTypeKVM]').hide();
$form.find('.form-item[rel=requireshvm]').css('display', 'inline-block');
if (isAdmin()) {
$form.find('.form-item[rel=xenserverToolsVersion61plus]').css('display', 'inline-block');
}
} else if ($(this).val() == "KVM") {
$form.find('.form-item[rel=rootDiskControllerType]').hide();
$form.find('.form-item[rel=nicAdapterType]').hide();
$form.find('.form-item[rel=keyboardType]').hide();
$form.find('.form-item[rel=xenserverToolsVersion61plus]').hide();
$form.find('.form-item[rel=rootDiskControllerTypeKVM]').css('display', 'inline-block');
$('#label_root_disk_controller').prop('selectedIndex', 2);
$form.find('.form-item[rel=requireshvm]').css('display', 'inline-block');
} else {
$form.find('.form-item[rel=rootDiskControllerType]').hide();
$form.find('.form-item[rel=nicAdapterType]').hide();
$form.find('.form-item[rel=keyboardType]').hide();
$form.find('.form-item[rel=xenserverToolsVersion61plus]').hide();
$form.find('.form-item[rel=rootDiskControllerTypeKVM]').hide();
$form.find('.form-item[rel=requireshvm]').css('display', 'inline-block');
}
});
args.$select.trigger('change');
}
},
// fields for hypervisor == XenServer (starts here)
xenserverToolsVersion61plus: {
label: 'label.xenserver.tools.version.61.plus',
isBoolean: true,
isChecked: function (args) {
var b = true;
if (isAdmin()) {
$.ajax({
url: createURL('listConfigurations'),
data: {
name: 'xenserver.pvdriver.version'
},
async: false,
success: function (json) {
if (json.listconfigurationsresponse.configuration != null && json.listconfigurationsresponse.configuration[0].value != 'xenserver61') {
b = false;
}
}
});
}
return b;
},
isHidden: true
},
// fields for hypervisor == XenServer (ends here)
// fields for hypervisor == "KVM" (starts here)
rootDiskControllerTypeKVM: {
label: 'label.root.disk.controller',
isHidden: true,
select: function(args) {
var items = []
items.push({
id: "",
description: ""
});
items.push({
id: "ide",
description: "ide"
});
items.push({
id: "osdefault",
description: "osdefault"
});
items.push({
id: "scsi",
description: "virtio-scsi"
});
items.push({
id: "virtio",
description: "virtio"
});
args.response.success({
data: items
});
}
},
// fields for hypervisor == "KVM" (ends here)
// fields for hypervisor == "VMware" (starts here)
rootDiskControllerType: {
label: 'label.root.disk.controller',
isHidden: true,
select: function(args) {
var items = []
items.push({
id: "",
description: ""
});
items.push({
id: "scsi",
description: "scsi"
});
items.push({
id: "ide",
description: "ide"
});
items.push({
id: "osdefault",
description: "osdefault"
});
items.push({
id: "pvscsi",
description: "pvscsi"
});
items.push({
id: "lsilogic",
description: "lsilogic"
});
items.push({
id: "lsisas1068",
description: "lsilogicsas"
});
items.push({
id: "buslogic",
description: "buslogic"
});
args.response.success({
data: items
});
}
},
nicAdapterType: {
label: 'label.nic.adapter.type',
isHidden: true,
select: function(args) {
var items = []
items.push({
id: "",
description: ""
});
items.push({
id: "E1000",
description: "E1000"
});
items.push({
id: "PCNet32",
description: "PCNet32"
});
items.push({
id: "Vmxnet2",
description: "Vmxnet2"
});
items.push({
id: "Vmxnet3",
description: "Vmxnet3"
});
args.response.success({
data: items
});
}
},
keyboardType: {
label: 'label.keyboard.type',
isHidden: true,
select: function(args) {
var items = []
items.push({
id: "",
description: ""
});
for (var key in cloudStackOptions.keyboardOptions) {
items.push({
id: key,
description: _l(cloudStackOptions.keyboardOptions[key])
});
}
args.response.success({
data: items
});
}
},
// fields for hypervisor == "VMware" (ends here)
format: {
label: 'label.format',
docID: 'helpRegisterTemplateFormat',
dependsOn: 'hypervisor',
select: function(args) {
var items = [];
if (args.hypervisor == "XenServer") {
items.push({
id: 'VHD',
description: 'VHD'
});
} else if (args.hypervisor == "VMware") {
items.push({
id: 'OVA',
description: 'OVA'
});
} else if (args.hypervisor == "KVM") {
items.push({
id: 'QCOW2',
description: 'QCOW2'
});
items.push({
id: 'RAW',
description: 'RAW'
});
items.push({
id: 'VHD',
description: 'VHD'
});
items.push({
id: 'VMDK',
description: 'VMDK'
});
} else if (args.hypervisor == "BareMetal") {
items.push({
id: 'BareMetal',
description: 'BareMetal'
});
} else if (args.hypervisor == "Ovm") {
items.push({
id: 'RAW',
description: 'RAW'
});
} else if (args.hypervisor == "LXC") {
items.push({
id: 'TAR',
description: 'TAR'
});
} else if (args.hypervisor == "Hyperv") {
items.push({
id: 'VHD',
description: 'VHD'
});
items.push({
id: 'VHDX',
description: 'VHDX'
});
}
args.response.success({
data: items
});
}
},
osTypeId: {
label: 'label.os.type',
docID: 'helpRegisterTemplateOSType',
select: function(args) {
$.ajax({
url: createURL("listOsTypes"),
dataType: "json",
async: true,
success: function(json) {
var ostypeObjs = json.listostypesresponse.ostype;
args.response.success({
data: ostypeObjs
});
}
});
}
},
isExtractable: {
label: "label.extractable",
docID: 'helpRegisterTemplateExtractable',
isBoolean: true
},
isPasswordEnabled: {
label: "label.password.enabled",
docID: 'helpRegisterTemplatePasswordEnabled',
isBoolean: true
},
isdynamicallyscalable: {
label: "label.dynamically.scalable",
docID: 'helpRegisterTemplateDynamicallyScalable',
isBoolean: true
},
isPublic: {
label: "label.public",
docID: 'helpRegisterTemplatePublic',
isBoolean: true,
isHidden: true
},
isFeatured: {
label: "label.featured",
docID: 'helpRegisterTemplateFeatured',
isBoolean: true,
isHidden: true
},
isrouting: {
label: 'label.routing',
docID: 'helpRegisterTemplateRouting',
isBoolean: true,
isHidden: true
},
requireshvm: {
label: 'label.hvm',
docID: 'helpRegisterTemplateHvm',
isBoolean: true,
isHidden: false,
isChecked: true
}
}
},
action: function(args) {
return; //createForm.fileUpload.getURL() has executed the whole action. Therefore, nothing needs to be done here.
},
notification: {
poll: function(args) {
args.complete();
}
}
}
},
dataProvider: function(args) {
var data = {};
listViewDataProvider(args, data);
// Due to zonal grouping, low pagesize can result lower
// aggregated items, resulting in no scroll shown
// So, use maximum pagesize
data.pagesize = 200;
var ignoreProject = false;
if (args.filterBy != null) { //filter dropdown
if (args.filterBy.kind != null) {
if (previousFilterType != args.filterBy.kind || args.page == 1) {
previousFilterType = args.filterBy.kind;
previousCollection = [];
}
switch (args.filterBy.kind) {
case "all":
$.extend(data, {
templatefilter: 'all'
});
break;
case "mine":
$.extend(data, {
templatefilter: 'self'
});
break;
case "shared":
$.extend(data, {
templatefilter: 'shared'
});
break;
case "featured":
ignoreProject = true;
$.extend(data, {
templatefilter: 'featured'
});
break;
case "community":
ignoreProject = true;
$.extend(data, {
templatefilter: 'community'
});
break;
}
}
}
$.ajax({
url: createURL('listTemplates', {
ignoreProject: ignoreProject
}),
data: data,
success: function(json) {
var items = json.listtemplatesresponse.template;
var itemsView = [];
$(items).each(function(index, item) {
var existing = $.grep(previousCollection, function(it){
return it != null && it.id !=null && it.id == item.id;
});
if (existing.length > 0) {
return true; // skip adding this entry
} else {
var templateItem = $.extend(item, {
zones: item.zonename,
zoneids: [item.zoneid]
});
itemsView.push(templateItem);
previousCollection.push(templateItem);
}
});
args.response.success({
actionFilter: templateActionfilter,
data: itemsView
});
}
});
},
detailView: {
name: 'Template details',
viewAll: {
label: 'label.instances',
path: 'instances'
},
actions: {
edit: {
label: 'label.edit',
action: function(args) {
//***** updateTemplate *****
var data = {
id: args.context.templates[0].id,
//zoneid: args.context.templates[0].zoneid, //can't update template/ISO in only one zone. It always get updated in all zones.
name: args.data.name,
displaytext: args.data.displaytext,
ostypeid: args.data.ostypeid,
templatetype: args.data.templatetype,
passwordenabled: (args.data.passwordenabled == "on"),
isdynamicallyscalable: (args.data.isdynamicallyscalable == "on")
};
if (args.data.isrouting != null) {
$.extend(data, {
isrouting: (args.data.isrouting === 'on')
});
}
$.ajax({
url: createURL('updateTemplate'),
data: data,
async: false,
success: function(json) {
//API returns an incomplete embedded object (some properties are missing in the embedded template object)
}
});
//***** updateTemplatePermissions *****
var data = {
id: args.context.templates[0].id
//zoneid: args.context.templates[0].zoneid //can't update template/ISO in only one zone. It always get updated in all zones.
};
//if args.data.ispublic is undefined(i.e. checkbox is hidden), do not pass ispublic to API call.
if (args.data.ispublic == "on") {
$.extend(data, {
ispublic: true
});
} else if (args.data.ispublic == "off") {
$.extend(data, {
ispublic: false
});
}
//if args.data.isfeatured is undefined(i.e. checkbox is hidden), do not pass isfeatured to API call.
if (args.data.isfeatured == "on") {
$.extend(data, {
isfeatured: true
});
} else if (args.data.isfeatured == "off") {
$.extend(data, {
isfeatured: false
});
}
//if args.data.isextractable is undefined(i.e. checkbox is hidden), do not pass isextractable to API call.
if (args.data.isextractable == "on") {
$.extend(data, {
isextractable: true
});
} else if (args.data.isextractable == "off") {
$.extend(data, {
isextractable: false
});
}
$.ajax({
url: createURL('updateTemplatePermissions'),
data: data,
async: false,
success: function(json) {
//API doesn't return an embedded object
}
});
//***** addResourceDetail *****
//XenServer only (starts here)
if(args.$detailView.find('form').find('div .detail-group').find('.xenserverToolsVersion61plus').length > 0) {
$.ajax({
url: createURL('addResourceDetail'),
data: {
resourceType: 'template',
resourceId: args.context.templates[0].id,
'details[0].key': 'hypervisortoolsversion',
'details[0].value': (args.data.xenserverToolsVersion61plus == "on") ? 'xenserver61' : 'xenserver56'
},
success: function(json) {
var jobId = json.addResourceDetailresponse.jobid;
var addResourceDetailIntervalID = setInterval(function() {
$.ajax({
url: createURL("queryAsyncJobResult&jobid=" + jobId),
dataType: "json",
success: function(json) {
var result = json.queryasyncjobresultresponse;
if (result.jobstatus == 0) {
return; //Job has not completed
} else {
clearInterval(addResourceDetailIntervalID);
if (result.jobstatus == 1) {
//do nothing
} else if (result.jobstatus == 2) {
cloudStack.dialog.notice({
message: "message.XSTools61plus.update.failed" + " " + _s(result.jobresult.errortext)
});
}
}
},
error: function(XMLHttpResponse) {
cloudStack.dialog.notice({
message: "message.XSTools61plus.update.failed" + " " + parseXMLHttpResponse(XMLHttpResponse)
});
}
});
}, g_queryAsyncJobResultInterval);
}
});
}
//XenServer only (ends here)
//***** listTemplates *****
//So, we call listTemplates API to get a complete template object
var data = {
id: args.context.templates[0].id,
zoneid: args.context.templates[0].zoneid,
templatefilter: 'self'
};
$.ajax({
url: createURL('listTemplates'),
data: data,
async: false,
success: function(json) {
var item = json.listtemplatesresponse.template;
args.response.success({
data: item
});
}
});
}
},
downloadTemplate: {
label: 'label.action.download.template',
messages: {
confirm: function(args) {
return 'message.action.download.template';
},
notification: function(args) {
return 'message.action.downloading.template';
},
complete: function(args) {
var url = args.url;
var htmlMsg = _l('message.download.template');
var htmlMsg2 = htmlMsg.replace(/#/, url).replace(/00000/, url);
return htmlMsg2;
}
},
action: function(args) {
var apiCmd = "extractTemplate&mode=HTTP_DOWNLOAD&id=" + args.context.templates[0].id;
if (args.context.templates[0].zoneid != null)
apiCmd += "&zoneid=" + args.context.templates[0].zoneid;
$.ajax({
url: createURL(apiCmd),
dataType: "json",
async: true,
success: function(json) {
var jid = json.extracttemplateresponse.jobid;
args.response.success({
_custom: {
jobId: jid,
getUpdatedItem: function(json) {
return json.queryasyncjobresultresponse.jobresult.template;
},
getActionFilter: function() {
return templateActionfilter;
}
}
});
}
});
},
notification: {
poll: pollAsyncJobResult
}
},
// Share template
shareTemplate: {
label: 'label.action.share.template',
messages: {
notification: function (args) {
return 'label.action.share.template';
}
},
createForm: {
title: 'label.action.share.template',
desc: '',
fields: {
operation: {
label: 'label.operation',
docID: 'helpUpdateTemplateOperation',
validation: {
required: true
},
select: function (args) {
var items = [];
items.push({
id: "add",
description: "Add"
});
items.push({
id: "remove",
description: "Remove"
});
items.push({
id: "reset",
description: "Reset"
});
args.response.success({
data: items
});
// Select change
args.$select.change(function () {
var $form = $(this).closest('form');
var selectedOperation = $(this).val();
if (selectedOperation === "reset") {
$form.find('[rel=projects]').hide();
$form.find('[rel=sharewith]').hide();
$form.find('[rel=accounts]').hide();
$form.find('[rel=accountlist]').hide();
} else {
// allow.user.view.domain.accounts = true
// Populate List of accounts in domain as dropdown multiselect
$form.find('[rel=sharewith]').css('display', 'inline-block');
if (!isUser() || g_allowUserViewAllDomainAccounts === true) {
$form.find('[rel=projects]').css('display', 'inline-block');
$form.find('[rel=accounts]').css('display', 'inline-block');
$form.find('[rel=accountlist]').hide();
} else {
// If users are not allowed to see accounts in the domain, show input text field for Accounts
// Projects will always be shown as dropdown multiselect
$form.find('[rel=projects]').css('display', 'inline-block');
$form.find('[rel=accountslist]').css('display', 'inline-block');
$form.find('[rel=accounts]').hide();
}
}
});
}
},
shareWith: {
label: 'label.share.with',
docID: 'helpUpdateTemplateShareWith',
validation: {
required: true
},
dependsOn: 'operation',
select: function (args) {
var items = [];
items.push({
id: "account",
description: "Account"
});
items.push({
id: "project",
description: "Project"
});
args.response.success({ data: items });
// Select change
args.$select.change(function () {
var $form = $(this).closest('form');
var sharedWith = $(this).val();
if (args.operation !== "reset") {
if (sharedWith === "project") {
$form.find('[rel=accounts]').hide();
$form.find('[rel=accountlist]').hide();
$form.find('[rel=projects]').css('display', 'inline-block');
} else {
// allow.user.view.domain.accounts = true
// Populate List of accounts in domain as dropdown multiselect
if (!isUser() || g_allowUserViewAllDomainAccounts === true) {
$form.find('[rel=projects]').hide();
$form.find('[rel=accountlist]').hide();
$form.find('[rel=accounts]').css('display', 'inline-block');
} else {
// If users are not allowed to see accounts in the domain, show input text field for Accounts
// Projects will always be shown as dropdown multiselect
$form.find('[rel=projects]').hide();
$form.find('[rel=accounts]').hide();
$form.find('[rel=accountlist]').css('display', 'inline-block');
}
}
}
});
}
},
accountlist: {
label: 'label.accounts',
docID: 'helpUpdateTemplateAccountList'
},
accounts: {
label: 'label.accounts',
docID: 'helpUpdateTemplateAccounts',
dependsOn: 'shareWith',
isMultiple: true,
select: function (args) {
var operation = args.operation;
if (operation !== "reset") {
$.ajax({
url: createURL("listAccounts&listall=true"),
dataType: "json",
async: true,
success: function (jsonAccounts) {
var accountByName = {};
$.each(jsonAccounts.listaccountsresponse.account, function(idx, account) {
// Only add current domain's accounts for add as update template permissions supports that
if (account.domainid === g_domainid && operation === "add") {
accountByName[account.name] = {
projName: account.name,
hasPermission: false
};
}
});
$.ajax({
url: createURL('listTemplatePermissions&id=' + args.context.templates[0].id),
dataType: "json",
async: true,
success: function (json) {
items = json.listtemplatepermissionsresponse.templatepermission.account;
$.each(items, function(idx, accountName) {
if (accountByName[accountName]) {
accountByName[accountName].hasPermission = true;
}
});
var accountObjs = [];
if (operation === "add") {
// Skip already permitted accounts
$.each(Object.keys(accountByName), function(idx, accountName) {
if (accountByName[accountName].hasPermission == false) {
accountObjs.push({
name: accountName,
description: accountName
});
}
});
} else if (items != null) {
$.each(items, function(idx, accountName) {
if (accountName !== g_account) {
accountObjs.push({
name: accountName,
description: accountName
});
}
});
}
args.$select.html('');
args.response.success({data: accountObjs});
}
});
}
});
}
}
},
projects: {
label: 'label.projects',
docID: 'helpUpdateTemplateProjectIds',
dependsOn: 'shareWith',
isMultiple: true,
select: function (args) {
var operation = args.operation;
if (operation !== "reset") {
$.ajax({
url: createURL("listProjects&listall=true"),
dataType: "json",
async: true,
success: function (jsonProjects) {
var projectsByIds = {};
$.each(jsonProjects.listprojectsresponse.project, function(idx, project) {
// Only add current domain's projects for add operation as update template permissions supports that
if ((project.domainid === g_domainid && operation === "add") || operation === "remove") {
projectsByIds[project.id] = {
projName: project.name,
hasPermission: false
};
}
});
$.ajax({
url: createURL('listTemplatePermissions&id=' + args.context.templates[0].id),
dataType: "json",
async: true,
success: function (json) {
items = json.listtemplatepermissionsresponse.templatepermission.projectids;
$.each(items, function(idx, projectId) {
if (projectsByIds[projectId]) {
projectsByIds[projectId].hasPermission = true;
}
});
var projectObjs = [];
if (operation === "add") {
// Skip already permitted accounts
$.each(Object.keys(projectsByIds), function(idx, projectId) {
if (projectsByIds[projectId].hasPermission == false) {
projectObjs.push({
id: projectId,
description: projectsByIds[projectId].projName
});
}
});
} else if (items != null) {
$.each(items, function(idx, projectId) {
if (projectId !== g_account) {
projectObjs.push({
id: projectId,
description: projectsByIds[projectId] ? projectsByIds[projectId].projName : projectId
});
}
});
}
args.$select.html('');
args.response.success({data: projectObjs});
}
});
}
});
}
}
}
}
},
action: function (args) {
// Load data from form
var data = {
id: args.context.templates[0].id,
op: args.data.operation
};
var selectedOperation = args.data.operation;
if (selectedOperation === "reset") {
// Do not append Project ID or Account to data object
} else {
var projects = args.data.projects;
var accounts = args.data.accounts;
var accountList = args.data.accountlist;
if (accounts !== undefined || (accountList !== undefined && accountList.length > 0)) {
var accountNames = "";
if (accountList !== undefined && accounts === undefined) {
accountNames = accountList;
} else {
if (Object.prototype.toString.call(accounts) === '[object Array]') {
accountNames = accounts.join(",");
} else {
accountNames = accounts;
}
}
$.extend(data, {
accounts: accountNames
});
}
if (projects !== undefined) {
var projectIds = "";
if (Object.prototype.toString.call(projects) === '[object Array]') {
projectIds = projects.join(",");
} else {
projectIds = projects;
}
$.extend(data, {
projectids: projectIds
});
}
}
$.ajax({
url: createURL('updateTemplatePermissions'),
data: data,
dataType: "json",
async: false,
success: function (json) {
var item = json.updatetemplatepermissionsresponse.success;
args.response.success({
data: item
});
}
}); //end ajax
}
}
},
tabFilter: function (args) {
var hiddenTabs = [];
return hiddenTabs;
},
tabs: {
details: {
title: 'label.details',
preFilter: function(args) {
var hiddenFields;
if (isAdmin()) {
hiddenFields = [];
} else {
hiddenFields = ["hypervisor", 'xenserverToolsVersion61plus', 'isrouting'];
}
if ('templates' in args.context && args.context.templates[0].hypervisor != 'XenServer') {
hiddenFields.push('xenserverToolsVersion61plus');
}
if ('templates' in args.context && args.context.templates[0].ostypeid != undefined) {
var ostypeObjs;
$.ajax({
url: createURL("listOsTypes"),
dataType: "json",
async: false,
success: function(json) {
var ostypeObjs = json.listostypesresponse.ostype;
}
});
if (ostypeObjs != undefined) {
var ostypeName;
for (var i = 0; i < ostypeObjs.length; i++) {
if (ostypeObjs[i].id == args.context.templates[0].ostypeid) {
ostypeName = ostypeObjs[i].description;
break;
}
}
if (ostypeName == undefined || ostypeName.indexOf("Win") == -1) {
hiddenFields.push('xenserverToolsVersion61plus');
}
}
}
if (!('templates' in args.context && args.context.templates[0].domainid == g_domainid && args.context.templates[0].account == g_account) && !isAdmin()) {
hiddenFields.push('url');
}
return hiddenFields;
},
fields: [{
name: {
label: 'label.name',
isEditable: true,
validation: {
required: true
}
}
}, {
hypervisor: {
label: 'label.hypervisor'
},
xenserverToolsVersion61plus: {
label: 'label.xenserver.tools.version.61.plus',
isBoolean: true,
isEditable: function () {
if (isAdmin())
return true;
else
return false;
},
converter: cloudStack.converters.toBooleanText
},
size: {
label: 'label.size',
converter: function(args) {
if (args == null || args == 0)
return "";
else
return cloudStack.converters.convertBytes(args);
}
},
directdownload: {
label: 'label.direct.download',
isBoolean: true,
converter: cloudStack.converters.toBooleanText
},
isextractable: {
label: 'label.extractable.lower',
isBoolean: true,
isEditable: true,
converter: cloudStack.converters.toBooleanText
},
passwordenabled: {
label: 'label.password.enabled',
isBoolean: true,
isEditable: true,
converter: cloudStack.converters.toBooleanText
},
isdynamicallyscalable: {
label: 'label.dynamically.scalable',
isBoolean: true,
isEditable: true,
converter: cloudStack.converters.toBooleanText
},
ispublic: {
label: 'label.public',
isBoolean: true,
isEditable: function() {
if (isAdmin()) {
return true;
} else {
if (g_userPublicTemplateEnabled == "true")
return true;
else
return false;
}
},
converter: cloudStack.converters.toBooleanText
},
isfeatured: {
label: 'label.featured',
isBoolean: true,
isEditable: function() {
if (isAdmin())
return true;
else
return false;
},
converter: cloudStack.converters.toBooleanText
},
ostypeid: {
label: 'label.os.type',
isEditable: true,
select: function(args) {
var ostypeObjs;
$.ajax({
url: createURL("listOsTypes"),
dataType: "json",
async: false,
success: function(json) {
ostypeObjs = json.listostypesresponse.ostype;
}
});
var items = [];
$(ostypeObjs).each(function() {
items.push({
id: this.id,
description: this.description
});
});
args.response.success({
data: items
});
}
},
isrouting: {
label: 'label.routing',
isBoolean: true,
isEditable: function() {
if (isAdmin()) {
return true;
} else {
return false;
}
},
converter: cloudStack.converters.toBooleanText
},
crossZones: {
label: 'label.cross.zones',
converter: cloudStack.converters.toBooleanText
},
displaytext: {
label: 'label.description',
isEditable: true,
validation: {
required: true
}
},
domain: {
label: 'label.domain'
},
account: {
label: 'label.account'
},
created: {
label: 'label.created',
converter: cloudStack.converters.toLocalDate
},
url: {
label: 'label.url'
},
templatetype: {
label: 'label.type',
isEditable: function() {
if (isAdmin()) {
return true;
} else {
return false;
}
},
select: function(args) {
var items = [];
items.push({
id: 'ROUTING',
description: 'ROUTING'
});
items.push({
id: 'SYSTEM',
description: 'SYSTEM'
});
items.push({
id: 'BUILTIN',
description: 'BUILTIN'
});
items.push({
id: 'PERHOST',
description: 'PERHOST'
});
items.push({
id: 'USER',
description: 'USER'
});
args.response.success({
data: items
});
}
},
id: {
label: 'label.id'
}
}],
tags: cloudStack.api.tags({
resourceType: 'Template',
contextId: 'templates'
}),
dataProvider: function(args) { // UI > Templates menu (listing) > select a template from listing > Details tab
$.ajax({
url: createURL("listTemplates"),
data: {
templatefilter: "self",
id: args.context.templates[0].id
},
success: function(json) {
var jsonObj = json.listtemplatesresponse.template[0];
if ('details' in jsonObj && 'hypervisortoolsversion' in jsonObj.details) {
if (jsonObj.details.hypervisortoolsversion == 'xenserver61')
jsonObj.xenserverToolsVersion61plus = true;
else
jsonObj.xenserverToolsVersion61plus = false;
}
if (jsonObj.templatetype == 'ROUTING') {
jsonObj.isrouting = true;
} else {
jsonObj.isrouting = false;
}
args.response.success({
actionFilter: templateActionfilter,
data: jsonObj
});
}
});
}
},
zones: {
title: 'label.zones',
listView: {
id: 'zones',
fields: {
zonename: {
label: 'label.name'
},
status: {
label: 'label.status'
},
isready: {
label: 'state.Ready',
converter: cloudStack.converters.toBooleanText
}
},
hideSearchBar: true,
dataProvider: function(args) { // UI > Templates menu (listing) > select a template from listing > Details tab > Zones tab (listing)
var data = { templatefilter: "self",
id: args.context.templates[0].id
};
listViewDataProvider(args, data);
$.ajax({
url: createURL("listTemplates"),
data: data,
success: function(json) {
var jsonObjs = json.listtemplatesresponse.template;
if (jsonObjs != undefined) {
for (var i = 0; i < jsonObjs.length; i++) {
var jsonObj = jsonObjs[i];
if ('details' in jsonObj && 'hypervisortoolsversion' in jsonObj.details) {
if (jsonObj.details.hypervisortoolsversion == 'xenserver61')
jsonObj.xenserverToolsVersion61plus = true;
else
jsonObj.xenserverToolsVersion61plus = false;
}
}
if (!'zonename' in jsonObj) {
jsonObj.zonename = 'All Zones';
}
}
args.response.success({
actionFilter: templateActionfilter,
data: jsonObjs
});
}
});
},
detailView: {
noCompact: true,
actions: {
remove: {
label: 'label.action.delete.template',
createForm: {
title: 'label.action.delete.template',
desc: function(args) {
if(args.context.templates[0].crossZones == true) {
return 'message.action.delete.template.for.all.zones';
} else {
return 'message.action.delete.template';
}
},
fields: {
forced: {
label: 'force.delete',
isBoolean: true,
isChecked: false
}
}
},
messages: {
notification: function(args) {
return 'label.action.delete.template';
}
},
action: function(args) {
var queryParams = "deleteTemplate&id=" + args.context.templates[0].id;
if (!args.context.templates[0].crossZones){
queryParams += "&zoneid=" + args.context.zones[0].zoneid;
}
$.ajax({
url: createURL(queryParams + "&forced=" + (args.data.forced == "on")),
dataType: "json",
async: true,
success: function(json) {
var jid = json.deletetemplateresponse.jobid;
args.response.success({
_custom: {
jobId: jid
}
});
}
});
},
notification: {
poll: pollAsyncJobResult
}
},
copyTemplate: {
label: 'label.action.copy.template',
messages: {
success: function(args) {
return 'message.template.copying';
},
notification: function(args) {
return 'label.action.copy.template';
}
},
action: {
custom: cloudStack.uiCustom.copyTemplate({
listView: {
listView: {
id: 'destinationZones',
fields: {
destinationZoneName: {
label: 'label.name'
}
},
dataProvider: function(args) {
var data = {
page: args.page,
pagesize: pageSize
};
if (args.filterBy.search.value) {
data.keyword = args.filterBy.search.value;
}
$.ajax({
url: createURL("listZones&available=true"),
dataType: "json",
data: data,
async: true,
success: function(json) {
var zoneObjs = [];
var items = json.listzonesresponse.zone;
if (items != null) {
for (var i = 0; i < items.length; i++) {
if (args.context.zones[0].zoneid != items[i].id) {
zoneObjs.push({
id: items[i].id,
destinationZoneName: items[i].name
});
}
}
args.response.success({
data: zoneObjs
});
}else if(args.page == 1) {
args.response.success({
data: []
});
} else {
args.response.success({
data: []
});
}
}
});
}
}
},
action: function(args) {
var zoneids = "";
if (args.context.selectedZone != null &&
args.context.selectedZone.length > 0) {
for (var i = 0; i < args.context.selectedZone.length; i++){
if (i != 0 )
zoneids += ",";
zoneids += args.context.selectedZone[i].id;
}
}
if (zoneids == "")
return;
var data = {
id: args.context.templates[0].id,
destzoneids: zoneids,
sourcezoneid: args.context.zones[0].zoneid
};
$.ajax({
url: createURL('copyTemplate'),
data: data,
success: function(json) {
var jid = json.copytemplateresponse.jobid;
args.response.success({
_custom: {
jobId: jid,
getUpdatedItem: function(json) {
return {}; //nothing in this template needs to be updated
},
getActionFilter: function() {
return templateActionfilter;
}
}
});
}
});
}
})
},
notification: {
poll: pollAsyncJobResult
}
}
},
tabs: {
details: {
title: 'label.details',
preFilter: function(args) {
var hiddenFields;
if (isAdmin()) {
hiddenFields = [];
} else {
hiddenFields = ["hypervisor", 'xenserverToolsVersion61plus'];
}
if ('templates' in args.context && args.context.templates[0].hypervisor != 'XenServer') {
hiddenFields.push('xenserverToolsVersion61plus');
}
if ('templates' in args.context && args.context.templates[0].ostypeid != undefined) {
var ostypeObjs;
$.ajax({
url: createURL("listOsTypes"),
dataType: "json",
async: false,
success: function(json) {
ostypeObjs = json.listostypesresponse.ostype;
}
});
if (ostypeObjs != undefined) {
var ostypeName;
for (var i = 0; i < ostypeObjs.length; i++) {
if (ostypeObjs[i].id == args.context.templates[0].ostypeid) {
ostypeName = ostypeObjs[i].description;
break;
}
}
if (ostypeName == undefined || ostypeName.indexOf("Win") == -1) {
hiddenFields.push('xenserverToolsVersion61plus');
}
}
}
return hiddenFields;
},
fields: [{
name: {
label: 'label.name',
isEditable: true,
validation: {
required: true
}
}
}, {
id: {
label: 'label.id'
},
zonename: {
label: 'label.zone.name'
},
zoneid: {
label: 'label.zone.id'
},
isready: {
label: 'state.Ready',
converter: cloudStack.converters.toBooleanText
},
status: {
label: 'label.status'
}
}, {
hypervisor: {
label: 'label.hypervisor'
},
xenserverToolsVersion61plus: {
label: 'label.xenserver.tools.version.61.plus',
isBoolean: true,
isEditable: function () {
if (isAdmin())
return true;
else
return false;
},
converter: cloudStack.converters.toBooleanText
},
size: {
label: 'label.size',
converter: function(args) {
if (args == null || args == 0)
return "";
else
return cloudStack.converters.convertBytes(args);
}
},
isextractable: {
label: 'label.extractable.lower',
isBoolean: true,
isEditable: true,
converter: cloudStack.converters.toBooleanText
},
passwordenabled: {
label: 'label.password.enabled',
isBoolean: true,
isEditable: true,
converter: cloudStack.converters.toBooleanText
},
isdynamicallyscalable: {
label: 'label.dynamically.scalable',
isBoolean: true,
isEditable: true,
converter: cloudStack.converters.toBooleanText
},
ispublic: {
label: 'label.public',
isBoolean: true,
isEditable: function() {
if (isAdmin()) {
return true;
} else {
if (g_userPublicTemplateEnabled == "true")
return true;
else
return false;
}
},
converter: cloudStack.converters.toBooleanText
},
isfeatured: {
label: 'label.featured',
isBoolean: true,
isEditable: function() {
if (isAdmin())
return true;
else
return false;
},
converter: cloudStack.converters.toBooleanText
},
ostypeid: {
label: 'label.os.type',
isEditable: true,
select: function(args) {
var ostypeObjs;
$.ajax({
url: createURL("listOsTypes"),
dataType: "json",
async: false,
success: function(json) {
ostypeObjs = json.listostypesresponse.ostype;
}
});
var items = [];
$(ostypeObjs).each(function() {
items.push({
id: this.id,
description: this.description
});
});
args.response.success({
data: items
});
}
},
displaytext: {
label: 'label.description',
isEditable: true,
validation: {
required: true
}
},
domain: {
label: 'label.domain'
},
account: {
label: 'label.account'
},
created: {
label: 'label.created',
converter: cloudStack.converters.toLocalDate
},
templatetype: {
label: 'label.type'
}
}],
tags: cloudStack.api.tags({
resourceType: 'Template',
contextId: 'templates'
}),
dataProvider: function(args) { // UI > Templates menu (listing) > select a template from listing > Details tab > Zones tab (listing) > select a zone from listing > Details tab
var jsonObj = args.context.zones[0];
if ('details' in jsonObj && 'hypervisortoolsversion' in jsonObj.details) {
if (jsonObj.details.hypervisortoolsversion == 'xenserver61')
jsonObj.xenserverToolsVersion61plus = true;
else
jsonObj.xenserverToolsVersion61plus = false;
}
args.response.success({
actionFilter: templateActionfilter,
data: jsonObj
});
}
}
}}
}
},
/**
* Settings tab
*/
settings: {
title: 'label.settings',
custom: cloudStack.uiCustom.granularDetails({
resourceType: 'Template',
dataProvider: function(args) {
// no paging for listTemplates details
if (args.page > 1) {
args.response.success({
data: []
});
return;
}
$.ajax({
url: createURL('listTemplates'),
data: {
templatefilter: "self",
id: args.context.templates[0].id
},
success: function(json) {
var details = json.listtemplatesresponse.template[0].details;
var listDetails = [];
for (detail in details){
var det = {};
det["name"] = detail;
det["value"] = details[detail];
listDetails.push(det);
}
args.response.success({
data: listDetails
});
},
error: function(json) {
args.response.error(parseXMLHttpResponse(json));
}
});
},
actions: {
edit: function(args) {
var data = {
name: args.data.jsonObj.name,
value: args.data.value
};
var existingDetails = args.context.templates[0].details;
var newDetails = '';
for (d in existingDetails) {
if (d != data.name) {
newDetails += 'details[0].' + d + '=' + existingDetails[d] + '&';
}
}
newDetails += 'details[0].' + data.name + '=' + data.value;
$.ajax({
url: createURL('updateTemplate&id=' + args.context.templates[0].id + '&' + newDetails),
success: function(json) {
var template = json.updatetemplateresponse.template;
args.context.templates[0].details = template.details;
args.response.success({
data: template.details
});
},
error: function(json) {
args.response.error(parseXMLHttpResponse(json));
}
});
},
remove: function(args) {
var existingDetails = args.context.templates[0].details;
var detailToDelete = args.data.jsonObj.name;
var newDetails = ''
for (detail in existingDetails) {
if (detail != detailToDelete) {
newDetails += 'details[0].' + detail + '=' + existingDetails[detail] + '&';
}
}
if (newDetails != '') {
newDetails = newDetails.substring(0, newDetails.length - 1);
}
else {
newDetails += 'cleanupdetails=true';
}
$.ajax({
url: createURL('updateTemplate&id=' + args.context.templates[0].id + '&' + newDetails),
success: function(json) {
var template = json.updatetemplateresponse.template;
args.context.templates[0].details = template.details;
args.response.success({
data: template.details
});
},
error: function(json) {
args.response.error(parseXMLHttpResponse(json));
}
});
},
add: function(args) {
var name = args.data.name;
var value = args.data.value;
var details = args.context.templates[0].details;
var detailsFormat = '';
for (key in details) {
detailsFormat += "details[0]." + key + "=" + details[key] + "&";
}
// Add new detail to the existing ones
detailsFormat += "details[0]." + name + "=" + value;
$.ajax({
url: createURL('updateTemplate&id=' + args.context.templates[0].id + "&" + detailsFormat),
async: false,
success: function(json) {
var template = json.updatetemplateresponse.template;
args.context.templates[0].details = template.details;
args.response.success({
data: template.details
});
}
});
}
}
})
}
}
}
}
},
isos: {
type: 'select',
title: 'label.iso',
listView: {
label: 'label.iso',
filters: {
all: {
preFilter: function(args) {
if (isAdmin()||isDomainAdmin()) //"listIsos&filter=all" works for root-admin and domain-admin. Domain-admin is able to see all Isos in his domain.
return true;
else
return false;
},
label: 'ui.listView.filters.all'
},
mine: {
label: 'ui.listView.filters.mine'
},
shared: {
label: 'label.shared'
},
featured: {
label: 'label.featured'
},
community: {
label: 'label.community'
}
},
preFilter: function() {
if (isAdmin()||isDomainAdmin()) {
return []
}
return ['account']
},
fields: {
name: {
label: 'label.name'
},
ostypename: {
label: 'label.os.type'
},
account: {
label: 'label.account'
}
},
reorder: cloudStack.api.actions.sort('updateIso', 'isos'),
actions: {
add: {
label: 'label.action.register.iso',
messages: {
notification: function(args) {
return 'label.action.register.iso';
}
},
createForm: {
title: 'label.action.register.iso',
preFilter: cloudStack.preFilter.createTemplate,
fields: {
name: {
label: 'label.name',
docID: 'helpRegisterISOName',
validation: {
required: true
}
},
description: {
label: 'label.description',
docID: 'helpRegisterISODescription',
validation: {
required: true
}
},
url: {
label: 'label.url',
docID: 'helpRegisterISOURL',
validation: {
required: true
}
},
// For KVM only: Direct Download
directdownload : {
label: 'label.direct.download',
docID: 'helpRegisterTemplateDirectDownload',
isBoolean: true
},
checksum: {
label: 'label.checksum',
dependsOn: 'directdownload',
isHidden: true
},
// Direct Download - End
zone: {
label: 'label.zone',
docID: 'helpRegisterISOZone',
select: function(args) {
if(g_regionsecondaryenabled == true) {
args.response.success({
data: [{
id: -1,
description: "All Zones"
}]
});
} else {
$.ajax({
url: createURL("listZones&available=true"),
dataType: "json",
async: true,
success: function(json) {
var zoneObjs = [];
var items = json.listzonesresponse.zone;
if (items != null) {
for (var i = 0; i < items.length; i++) {
zoneObjs.push({
id: items[i].id,
description: items[i].name
});
}
}
if (isAdmin() && !(cloudStack.context.projects && cloudStack.context.projects[0])) {
zoneObjs.unshift({
id: -1,
description: "All Zones"
});
}
args.response.success({
data: zoneObjs
});
}
});
}
}
},
isBootable: {
label: "label.bootable",
docID: 'helpRegisterISOBootable',
isBoolean: true,
isChecked: true
},
osTypeId: {
label: 'label.os.type',
docID: 'helpRegisterISOOSType',
dependsOn: 'isBootable',
isHidden: false,
validation: {
required: true
},
select: function(args) {
$.ajax({
url: createURL("listOsTypes"),
dataType: "json",
async: true,
success: function(json) {
var ostypeObjs = json.listostypesresponse.ostype;
var items = [];
//items.push({id: "", description: "None"}); //shouldn't have None option when bootable is checked
$(ostypeObjs).each(function() {
items.push({
id: this.id,
description: this.description
});
});
args.response.success({
data: items
});
}
});
}
},
isExtractable: {
label: "label.extractable",
docID: 'helpRegisterISOExtractable',
isBoolean: true
},
isPublic: {
label: "label.public",
docID: 'helpRegisterISOPublic',
isBoolean: true,
isHidden: true
},
isFeatured: {
label: "label.featured",
docID: 'helpRegisterISOFeatured',
isBoolean: true,
isHidden: true
}
}
},
action: function(args) {
var data = {
name: args.data.name,
displayText: args.data.description,
url: args.data.url,
zoneid: args.data.zone,
isextractable: (args.data.isExtractable == "on"),
bootable: (args.data.isBootable == "on"),
directdownload: (args.data.directdownload == "on")
};
if (args.$form.find('.form-item[rel=osTypeId]').css("display") != "none") {
$.extend(data, {
osTypeId: args.data.osTypeId
});
}
if (args.$form.find('.form-item[rel=isPublic]').css("display") != "none") {
$.extend(data, {
ispublic: (args.data.isPublic == "on")
});
}
if (args.$form.find('.form-item[rel=isFeatured]').css("display") != "none") {
$.extend(data, {
isfeatured: (args.data.isFeatured == "on")
});
}
if (args.$form.find('.form-item[rel=checksum]').css("display") != "none") {
$.extend(data, {
checksum: args.data.checksum
});
}
$.ajax({
url: createURL('registerIso'),
data: data,
success: function(json) {
var items = json.registerisoresponse.iso; //items might have more than one array element if it's create ISOs for all zones.
args.response.success({
data: items[0]
});
/*
if(items.length > 1) {
for(var i=1; i<items.length; i++) {
var $midmenuItem2 = $("#midmenu_item").clone();
ISOToMidmenu(items[i], $midmenuItem2);
bindClickToMidMenu($midmenuItem2, templateToRightPanel, ISOGetMidmenuId);
$("#midmenu_container").append($midmenuItem2.show()); }
}
*/
},
error: function(XMLHttpResponse) {
var errorMsg = parseXMLHttpResponse(XMLHttpResponse);
args.response.error(errorMsg);
}
});
},
notification: {
poll: function(args) {
args.complete();
}
}
},
uploadISOFromLocal: {
isHeader: true,
label: 'label.upload.from.local',
messages: {
notification: function(args) {
return 'label.upload.iso.from.local';
}
},
createForm: {
title: 'label.upload.iso.from.local',
preFilter: cloudStack.preFilter.createTemplate,
fileUpload: {
getURL: function(args) {
args.data = args.formData;
var data = {
name: args.data.name,
displayText: args.data.description,
zoneid: args.data.zone,
format: "ISO",
isextractable: (args.data.isExtractable == "on"),
bootable: (args.data.isBootable == "on"),
ispublic: (args.data.isPublic == "on"),
isfeatured: (args.data.isFeatured == "on")
};
if (args.$form.find('.form-item[rel=osTypeId]').is(':visible')) {
$.extend(data, {
osTypeId: args.data.osTypeId,
});
}
$.ajax({
url: createURL('getUploadParamsForIso'),
data: data,
async: false,
success: function(json) {
var uploadparams = json.postuploadisoresponse.getuploadparams;
var templateId = uploadparams.id;
args.response.success({
url: uploadparams.postURL,
ajaxPost: true,
data: {
'X-signature': uploadparams.signature,
'X-expires': uploadparams.expires,
'X-metadata': uploadparams.metadata
}
});
}
});
},
postUpload: function(args) {
if(args.error) {
args.response.error(args.errorMsg);
} else {
cloudStack.dialog.notice({
message: "This ISO file has been uploaded. Please check its status at Templates menu > " + args.data.name + " > Zones tab > click a zone > Status field and Ready field."
});
args.response.success();
}
}
},
fields: {
templateFileUpload: {
label: 'label.local.file',
isFileUpload: true,
validation: {
required: true
}
},
name: {
label: 'label.name',
docID: 'helpRegisterISOName',
validation: {
required: true
}
},
description: {
label: 'label.description',
docID: 'helpRegisterISODescription',
validation: {
required: true
}
},
zone: {
label: 'label.zone',
docID: 'helpRegisterISOZone',
select: function(args) {
$.ajax({
url: createURL("listZones&available=true"),
dataType: "json",
async: true,
success: function(json) {
var zoneObjs = json.listzonesresponse.zone;
args.response.success({
descriptionField: 'name',
data: zoneObjs
});
}
});
}
},
isBootable: {
label: "label.bootable",
docID: 'helpRegisterISOBootable',
isBoolean: true,
isChecked: true
},
osTypeId: {
label: 'label.os.type',
docID: 'helpRegisterISOOSType',
dependsOn: 'isBootable',
isHidden: false,
validation: {
required: true
},
select: function(args) {
$.ajax({
url: createURL("listOsTypes"),
dataType: "json",
async: true,
success: function(json) {
var ostypeObjs = json.listostypesresponse.ostype;
var items = [];
$(ostypeObjs).each(function() {
items.push({
id: this.id,
description: this.description
});
});
args.response.success({
data: items
});
}
});
}
},
isExtractable: {
label: "label.extractable",
docID: 'helpRegisterISOExtractable',
isBoolean: true
},
isPublic: {
label: "label.public",
docID: 'helpRegisterISOPublic',
isBoolean: true,
isHidden: true
},
isFeatured: {
label: "label.featured",
docID: 'helpRegisterISOFeatured',
isBoolean: true,
isHidden: true
}
}
},
action: function(args) {
return;
},
notification: {
poll: function(args) {
args.complete();
}
}
}
},
advSearchFields: {
name: {
label: 'label.name'
},
zoneid: {
label: 'label.zone',
select: function(args) {
$.ajax({
url: createURL('listZones'),
data: {
listAll: true
},
success: function(json) {
var zones = json.listzonesresponse.zone ? json.listzonesresponse.zone : [];
args.response.success({
data: $.map(zones, function(zone) {
return {
id: zone.id,
description: zone.name
};
})
});
}
});
}
},
tagKey: {
label: 'label.tag.key'
},
tagValue: {
label: 'label.tag.value'
}
},
dataProvider: function(args) {
var data = {};
listViewDataProvider(args, data);
// Due to zonal grouping, low pagesize can result lower
// aggregated items, resulting in no scroll shown
// So, use maximum pagesize
data.pagesize = 200;
var ignoreProject = false;
if (args.filterBy != null) { //filter dropdown
if (args.filterBy.kind != null) {
if (previousFilterType != args.filterBy.kind || args.page == 1) {
previousFilterType = args.filterBy.kind;
previousCollection = [];
}
switch (args.filterBy.kind) {
case "all":
$.extend(data, {
isofilter: 'all'
});
break;
case "mine":
$.extend(data, {
isofilter: 'self'
});
break;
case "shared":
$.extend(data, {
isofilter: 'shared'
});
break;
case "featured":
ignoreProject = true;
$.extend(data, {
isofilter: 'featured'
});
break;
case "community":
ignoreProject = true;
$.extend(data, {
isofilter: 'community'
});
break;
}
}
}
$.ajax({
url: createURL('listIsos', {
ignoreProject: ignoreProject
}),
data: data,
success: function(json) {
var items = json.listisosresponse.iso;
var itemsView = [];
$(items).each(function(index, item) {
var existing = $.grep(previousCollection, function(it){
return it != null && it.id !=null && it.id == item.id;
});
if (existing.length > 0) {
return true; // skip adding this entry
} else {
var isoItem = {
id: item.id,
name: item.name,
description: item.description,
ostypename: item.ostypename,
ostypeid: item.ostypeid,
account: item.account,
domain: item.domain,
zones: item.zonename,
zoneids: [item.zoneid]
};
itemsView.push(isoItem);
previousCollection.push(isoItem);
}
}
);
args.response.success({
actionFilter: isoActionfilter,
data: itemsView
});
}
});
},
detailView: {
name: 'label.details',
viewAll: {
label: 'label.instances',
path: 'instances'
},
actions: {
edit: {
label: 'label.edit',
action: function(args) {
//***** updateIso *****
var data = {
id: args.context.isos[0].id,
//zoneid: args.context.isos[0].zoneid, //can't update template/ISO in only one zone. It always get updated in all zones.
name: args.data.name,
displaytext: args.data.displaytext,
bootable: (args.data.bootable == "on"),
ostypeid: args.data.ostypeid
};
$.ajax({
url: createURL('updateIso'),
data: data,
async: false,
success: function(json) {
//updateIso API returns an incomplete ISO object (isextractable and isfeatured are missing)
}
});
//***** updateIsoPermissions *****
var data = {
id: args.context.isos[0].id
//zoneid: args.context.isos[0].zoneid //can't update template/ISO in only one zone. It always get updated in all zones.
};
//if args.data.ispublic is undefined(i.e. checkbox is hidden), do not pass ispublic to API call.
if (args.data.ispublic == "on") {
$.extend(data, {
ispublic: true
});
} else if (args.data.ispublic == "off") {
$.extend(data, {
ispublic: false
});
}
//if args.data.isfeatured is undefined(i.e. checkbox is hidden), do not pass isfeatured to API call.
if (args.data.isfeatured == "on") {
$.extend(data, {
isfeatured: true
});
} else if (args.data.isfeatured == "off") {
$.extend(data, {
isfeatured: false
});
}
//if args.data.isextractable is undefined(i.e. checkbox is hidden), do not pass isextractable to API call.
if (args.data.isextractable == "on") {
$.extend(data, {
isextractable: true
});
} else if (args.data.isextractable == "off") {
$.extend(data, {
isextractable: false
});
}
$.ajax({
url: createURL('updateIsoPermissions'),
data: data,
async: false,
success: function(json) {
//updateIsoPermissions API doesn't return ISO object
}
});
//***** listIsos *****
//So, we call listIsos API to get a complete ISO object
var data = {
id: args.context.isos[0].id,
zoneid: args.context.isos[0].zoneid,
isofilter: 'self'
};
$.ajax({
url: createURL('listIsos'),
data: data,
async: false,
success: function(json) {
var item = json.listisosresponse.iso;
args.response.success({
data: item
});
}
});
}
},
downloadISO: {
label: 'label.action.download.ISO',
messages: {
confirm: function(args) {
return 'message.action.download.iso';
},
notification: function(args) {
return 'label.action.download.ISO';
},
complete: function(args) {
var url = args.url;
var htmlMsg = _l('message.download.ISO');
var htmlMsg2 = htmlMsg.replace(/#/, url).replace(/00000/, url);
return htmlMsg2;
}
},
action: function(args) {
var apiCmd = "extractIso&mode=HTTP_DOWNLOAD&id=" + args.context.isos[0].id;
if (args.context.isos[0].zoneid != null)
apiCmd += "&zoneid=" + args.context.isos[0].zoneid;
$.ajax({
url: createURL(apiCmd),
dataType: "json",
async: true,
success: function(json) {
var jid = json.extractisoresponse.jobid;
args.response.success({
_custom: {
jobId: jid,
getUpdatedItem: function(json) {
return json.queryasyncjobresultresponse.jobresult.iso;
},
getActionFilter: function() {
return isoActionfilter;
}
}
});
}
});
},
notification: {
poll: pollAsyncJobResult
}
},
shareISO: {
label: 'label.action.share.iso',
messages: {
notification: function (args) {
return 'label.action.share.iso';
}
},
createForm: {
title: 'label.action.share.iso',
desc: '',
fields: {
operation: {
label: 'label.operation',
docID: 'helpUpdateTemplateOperation',
validation: {
required: true
},
select: function (args) {
var items = [];
items.push({
id: "add",
description: "Add"
});
items.push({
id: "remove",
description: "Remove"
});
items.push({
id: "reset",
description: "Reset"
});
args.response.success({
data: items
});
// Select change
args.$select.change(function () {
var $form = $(this).closest('form');
var selectedOperation = $(this).val();
if (selectedOperation === "reset") {
$form.find('[rel=projects]').hide();
$form.find('[rel=sharewith]').hide();
$form.find('[rel=accounts]').hide();
$form.find('[rel=accountlist]').hide();
} else {
// allow.user.view.domain.accounts = true
// Populate List of accounts in domain as dropdown multiselect
$form.find('[rel=sharewith]').css('display', 'inline-block');
if (!isUser() || g_allowUserViewAllDomainAccounts === true) {
$form.find('[rel=projects]').css('display', 'inline-block');
$form.find('[rel=accounts]').css('display', 'inline-block');
$form.find('[rel=accountlist]').hide();
} else {
// If users are not allowed to see accounts in the domain, show input text field for Accounts
// Projects will always be shown as dropdown multiselect
$form.find('[rel=projects]').css('display', 'inline-block');
$form.find('[rel=accountslist]').css('display', 'inline-block');
$form.find('[rel=accounts]').hide();
}
}
});
}
},
shareWith: {
label: 'label.share.with',
docID: 'helpUpdateTemplateShareWith',
validation: {
required: true
},
dependsOn: 'operation',
select: function (args) {
var items = [];
items.push({
id: "account",
description: "Account"
});
items.push({
id: "project",
description: "Project"
});
args.response.success({ data: items });
// Select change
args.$select.change(function () {
var $form = $(this).closest('form');
var sharedWith = $(this).val();
if (args.operation !== "reset") {
if (sharedWith === "project") {
$form.find('[rel=accounts]').hide();
$form.find('[rel=accountlist]').hide();
$form.find('[rel=projects]').css('display', 'inline-block');
} else {
// allow.user.view.domain.accounts = true
// Populate List of accounts in domain as dropdown multiselect
if (!isUser() || g_allowUserViewAllDomainAccounts === true) {
$form.find('[rel=projects]').hide();
$form.find('[rel=accountlist]').hide();
$form.find('[rel=accounts]').css('display', 'inline-block');
} else {
// If users are not allowed to see accounts in the domain, show input text field for Accounts
// Projects will always be shown as dropdown multiselect
$form.find('[rel=projects]').hide();
$form.find('[rel=accounts]').hide();
$form.find('[rel=accountlist]').css('display', 'inline-block');
}
}
}
});
}
},
accountlist: {
label: 'label.accounts',
docID: 'helpUpdateTemplateAccountList'
},
accounts: {
label: 'label.accounts',
docID: 'helpUpdateTemplateAccounts',
dependsOn: 'shareWith',
isMultiple: true,
select: function (args) {
var operation = args.operation;
if (operation !== "reset") {
$.ajax({
url: createURL("listAccounts&listall=true"),
dataType: "json",
async: true,
success: function (jsonAccounts) {
var accountByName = {};
$.each(jsonAccounts.listaccountsresponse.account, function(idx, account) {
// Only add current domain's accounts for add as update template permissions supports that
if (account.domainid === g_domainid && operation === "add") {
accountByName[account.name] = {
projName: account.name,
hasPermission: false
};
}
});
$.ajax({
url: createURL('listIsoPermissions&id=' + args.context.isos[0].id),
dataType: "json",
async: true,
success: function (json) {
items = json.listtemplatepermissionsresponse.templatepermission.account;
$.each(items, function(idx, accountName) {
if (accountByName[accountName]) {
accountByName[accountName].hasPermission = true;
}
});
var accountObjs = [];
if (operation === "add") {
// Skip already permitted accounts
$.each(Object.keys(accountByName), function(idx, accountName) {
if (accountByName[accountName].hasPermission == false) {
accountObjs.push({
name: accountName,
description: accountName
});
}
});
} else if (items != null) {
$.each(items, function(idx, accountName) {
if (accountName !== g_account) {
accountObjs.push({
name: accountName,
description: accountName
});
}
});
}
args.$select.html('');
args.response.success({data: accountObjs});
}
});
}
});
}
}
},
projects: {
label: 'label.projects',
docID: 'helpUpdateTemplateProjectIds',
dependsOn: 'shareWith',
isMultiple: true,
select: function (args) {
var operation = args.operation;
if (operation !== "reset") {
$.ajax({
url: createURL("listProjects&listall=true"),
dataType: "json",
async: true,
success: function (jsonProjects) {
var projectsByIds = {};
$.each(jsonProjects.listprojectsresponse.project, function(idx, project) {
// Only add current domain's projects for add operation as update template permissions supports that
if ((project.domainid === g_domainid && operation === "add") || operation === "remove") {
projectsByIds[project.id] = {
projName: project.name,
hasPermission: false
};
}
});
$.ajax({
url: createURL('listIsoPermissions&id=' + args.context.isos[0].id),
dataType: "json",
async: true,
success: function (json) {
items = json.listtemplatepermissionsresponse.templatepermission.projectids;
$.each(items, function(idx, projectId) {
if (projectsByIds[projectId]) {
projectsByIds[projectId].hasPermission = true;
}
});
var projectObjs = [];
if (operation === "add") {
// Skip already permitted accounts
$.each(Object.keys(projectsByIds), function(idx, projectId) {
if (projectsByIds[projectId].hasPermission == false) {
projectObjs.push({
id: projectId,
description: projectsByIds[projectId].projName
});
}
});
} else if (items != null) {
$.each(items, function(idx, projectId) {
if (projectId !== g_account) {
projectObjs.push({
id: projectId,
description: projectsByIds[projectId] ? projectsByIds[projectId].projName : projectId
});
}
});
}
args.$select.html('');
args.response.success({data: projectObjs});
}
});
}
});
}
}
}
}
},
action: function (args) {
// Load data from form
var data = {
id: args.context.isos[0].id,
op: args.data.operation
};
var selectedOperation = args.data.operation;
if (selectedOperation === "reset") {
// Do not append Project ID or Account to data object
} else {
var projects = args.data.projects;
var accounts = args.data.accounts;
var accountList = args.data.accountlist;
if (accounts !== undefined || (accountList !== undefined && accountList.length > 0)) {
var accountNames = "";
if (accountList !== undefined && accounts === undefined) {
accountNames = accountList;
} else {
if (Object.prototype.toString.call(accounts) === '[object Array]') {
accountNames = accounts.join(",");
} else {
accountNames = accounts;
}
}
$.extend(data, {
accounts: accountNames
});
}
if (projects !== undefined) {
var projectIds = "";
if (Object.prototype.toString.call(projects) === '[object Array]') {
projectIds = projects.join(",");
} else {
projectIds = projects;
}
$.extend(data, {
projectids: projectIds
});
}
}
$.ajax({
url: createURL('updateIsoPermissions'),
data: data,
dataType: "json",
async: false,
success: function (json) {
var item = json.updateisopermissionsresponse.success;
args.response.success({
data: item
});
}
}); //end ajax
}
}
},
tabs: {
details: {
title: 'label.details',
fields: [{
name: {
label: 'label.name',
isEditable: true,
validation: {
required: true
}
}
}, {
id: {
label: 'label.id'
},
displaytext: {
label: 'label.description',
isEditable: true,
validation: {
required: true
}
},
directdownload: {
label: 'label.direct.download',
isBoolean: true,
converter: cloudStack.converters.toBooleanText
},
size: {
label: 'label.size',
converter: function(args) {
if (args == null || args == 0)
return "";
else
return cloudStack.converters.convertBytes(args);
}
},
isextractable: {
label: 'label.extractable.lower',
isBoolean: true,
isEditable: function() {
if (isAdmin())
return true;
else
return false;
},
converter: cloudStack.converters.toBooleanText
},
bootable: {
label: 'label.bootable',
isBoolean: true,
isEditable: true,
converter: cloudStack.converters.toBooleanText
},
ispublic: {
label: 'label.public',
isBoolean: true,
isEditable: true,
converter: cloudStack.converters.toBooleanText
},
isfeatured: {
label: 'label.featured',
isBoolean: true,
isEditable: function() {
if (isAdmin())
return true;
else
return false;
},
converter: cloudStack.converters.toBooleanText
},
crossZones: {
label: 'label.cross.zones',
converter: cloudStack.converters.toBooleanText
},
ostypeid: {
label: 'label.os.type',
isEditable: true,
select: function(args) {
if (ostypeObjs == undefined) {
$.ajax({
url: createURL("listOsTypes"),
dataType: "json",
async: false,
success: function(json) {
ostypeObjs = json.listostypesresponse.ostype;
}
});
}
var items = [];
$(ostypeObjs).each(function() {
items.push({
id: this.id,
description: this.description
});
});
args.response.success({
data: items
});
}
},
domain: {
label: 'label.domain'
},
account: {
label: 'label.account'
},
created: {
label: 'label.created',
converter: cloudStack.converters.toLocalDate
},
url: {
label: 'label.url'
}
}],
tags: cloudStack.api.tags({
resourceType: 'ISO',
contextId: 'isos'
}),
dataProvider: function(args) {
var jsonObj = args.context.isos[0];
var apiCmd = "listIsos&isofilter=self&id=" + jsonObj.id;
if (jsonObj.zoneid != null)
apiCmd = apiCmd + "&zoneid=" + jsonObj.zoneid;
$.ajax({
url: createURL(apiCmd),
dataType: "json",
success: function(json) {
args.response.success({
actionFilter: isoActionfilter,
data: json.listisosresponse.iso[0]
});
}
});
}
},
zones: {
title: 'label.zones',
listView: {
id: 'zones',
fields: {
zonename: {
label: 'label.name'
},
status: {
label: 'label.status'
},
isready: {
label: 'state.Ready',
converter: cloudStack.converters.toBooleanText
}
},
hideSearchBar: true,
dataProvider: function(args) {
var data = {
isofilter: 'self',
id: args.context.isos[0].id
};
listViewDataProvider(args, data);
$.ajax({
url: createURL('listIsos'),
data: data,
dataType: "json",
success: function(json) {
var isos = json.listisosresponse.iso;
var zones = [];
zones = isos;
args.response.success({
actionFilter: isoActionfilter,
data: zones
});
}
});
},
detailView: {
actions: {
copyISO: {
label: 'label.action.copy.ISO',
messages: {
notification: function(args) {
return 'label.copying.iso';
}
},
createForm: {
title: 'label.action.copy.ISO',
desc: 'label.action.copy.ISO',
fields: {
destinationZoneId: {
label: 'label.destination.zone',
validation: {
required: true
},
select: function(args) {
$.ajax({
url: createURL("listZones&available=true"),
dataType: "json",
async: true,
success: function(json) {
var zoneObjs = [];
var items = json.listzonesresponse.zone;
if (items != null) {
for (var i = 0; i < items.length; i++) {
if (items[i].id != args.context.zones[0].zoneid) {
zoneObjs.push({
id: items[i].id,
description: items[i].name
});
}
}
}
args.response.success({
data: zoneObjs
});
}
});
}
}
}
},
action: function(args) {
var data = {
id: args.context.isos[0].id,
destzoneid: args.data.destinationZoneId
};
if (args.context.zones[0].zoneid != undefined) {
$.extend(data, {
sourcezoneid: args.context.zones[0].zoneid
});
}
$.ajax({
url: createURL('copyIso'),
data: data,
success: function(json) {
var jid = json.copytemplateresponse.jobid;
args.response.success({
_custom: {
jobId: jid,
getUpdatedItem: function(json) {
return {}; //nothing in this ISO needs to be updated
},
getActionFilter: function() {
return isoActionfilter;
}
}
});
}
});
},
notification: {
poll: pollAsyncJobResult
}
},
remove: {
label: 'label.action.delete.ISO',
messages: {
confirm: function(args) {
return 'message.action.delete.ISO';
},
notification: function(args) {
return 'label.action.delete.ISO';
}
},
action: function(args) {
var queryParams = "deleteIso&id=" + args.context.isos[0].id;
if (!args.context.isos[0].crossZones){
queryParams += "&zoneid=" + args.context.zones[0].zoneid;
}
$.ajax({
url: createURL(queryParams),
dataType: "json",
async: true,
success: function(json) {
var jid = json.deleteisoresponse.jobid;
args.response.success({
_custom: {
jobId: jid
}
});
}
});
},
notification: {
poll: pollAsyncJobResult
}
}
},
tabs: {
details: {
title: 'label.details',
fields: [{
name: {
label: 'label.name',
isEditable: true,
validation: {
required: true
}
}
}, {
id: {
label: 'label.id'
},
zonename: {
label: 'label.zone.name'
},
zoneid: {
label: 'label.zone.id'
},
isready: {
label: 'state.Ready',
converter: cloudStack.converters.toBooleanText
},
status: {
label: 'label.status'
}
},{
displaytext: {
label: 'label.description',
isEditable: true,
validation: {
required: true
}
},
size: {
label: 'label.size',
converter: function(args) {
if (args == null || args == 0)
return "";
else
return cloudStack.converters.convertBytes(args);
}
},
isextractable: {
label: 'label.extractable.lower',
isBoolean: true,
isEditable: true,
converter: cloudStack.converters.toBooleanText
},
bootable: {
label: 'label.bootable',
converter: cloudStack.converters.toBooleanText
},
ispublic: {
label: 'label.public',
isBoolean: true,
isEditable: true,
converter: cloudStack.converters.toBooleanText
},
isfeatured: {
label: 'label.featured',
isBoolean: true,
isEditable: function() {
if (isAdmin())
return true;
else
return false;
},
converter: cloudStack.converters.toBooleanText
},
ostypeid: {
label: 'label.os.type',
isEditable: true,
select: function(args) {
var ostypeObjs;
$.ajax({
url: createURL("listOsTypes"),
dataType: "json",
async: false,
success: function(json) {
ostypeObjs = json.listostypesresponse.ostype;
}
});
var items = [];
$(ostypeObjs).each(function() {
items.push({
id: this.id,
description: this.description
});
});
args.response.success({
data: items
});
}
},
domain: {
label: 'label.domain'
},
account: {
label: 'label.account'
},
created: {
label: 'label.created',
converter: cloudStack.converters.toLocalDate
}
}],
tags: cloudStack.api.tags({
resourceType: 'ISO',
contextId: 'isos'
}),
dataProvider: function(args) {
var jsonObj = args.context.isos[0];
var apiCmd = "listIsos&isofilter=self&id=" + jsonObj.id;
if (jsonObj.zoneid != null)
apiCmd = apiCmd + "&zoneid=" + args.context.zones[0].zoneid;
$.ajax({
url: createURL(apiCmd),
dataType: "json",
success: function(json) {
args.response.success({
actionFilter: isoActionfilter,
data: json.listisosresponse.iso[0]
});
}
});
}
}
}
}}
}
}
}
}
}
}
};
var templateActionfilter = function(args) {
var jsonObj = args.context.item;
var allowedActions = [];
// "Edit Template", "Copy Template", "Create VM"
if ((isAdmin() == false && !(jsonObj.domainid == g_domainid && jsonObj.account == g_account) && !(jsonObj.domainid == g_domainid && cloudStack.context.projects && jsonObj.projectid == cloudStack.context.projects[0].id)) //if neither root-admin, nor the same account, nor the same project
|| jsonObj.isready == false) {
//do nothing
} else {
allowedActions.push("edit");
allowedActions.push("copyTemplate");
}
// "Download Template" , "Update Template Permissions"
if (((isAdmin() == false && !(jsonObj.domainid == g_domainid && jsonObj.account == g_account) && !(jsonObj.domainid == g_domainid && cloudStack.context.projects && jsonObj.projectid == cloudStack.context.projects[0].id))) //if neither root-admin, nor the same account, nor the same project
|| (jsonObj.isready == false)) {
//do nothing
} else {
if (jsonObj.isextractable){
allowedActions.push("downloadTemplate");
}
allowedActions.push("shareTemplate");
}
// "Delete Template"
//if (((isUser() && jsonObj.ispublic == true && !(jsonObj.domainid == g_domainid && jsonObj.account == g_account)))
if (((isAdmin() == false && !(jsonObj.domainid == g_domainid && jsonObj.account == g_account) && !(jsonObj.domainid == g_domainid && cloudStack.context.projects && jsonObj.projectid == cloudStack.context.projects[0].id))) //if neither root-admin, nor the same account, nor the same project
|| (jsonObj.isready == false && jsonObj.status != null && jsonObj.status.indexOf("Downloaded") != -1) || (jsonObj.account == "system")) {
//do nothing
} else {
allowedActions.push("remove");
}
return allowedActions;
}
var isoActionfilter = function(args) {
var jsonObj = args.context.item;
var allowedActions = [];
if ((isAdmin() == false && !(jsonObj.domainid == g_domainid && jsonObj.account == g_account) && !(jsonObj.domainid == g_domainid && cloudStack.context.projects && jsonObj.projectid == cloudStack.context.projects[0].id)) //if neither root-admin, nor the same account, nor the same project
|| (jsonObj.isready == false) || (jsonObj.domainid == 1 && jsonObj.account == "system")
) {
//do nothing
} else {
allowedActions.push("edit");
allowedActions.push("copyISO");
}
// "Create VM"
// Commenting this out for Beta2 as it does not support the new network.
/*
//if (((isUser() && jsonObj.ispublic == true && !(jsonObj.domainid == g_domainid && jsonObj.account == g_account) && !(jsonObj.domainid == g_domainid && cloudStack.context.projects && jsonObj.projectid == cloudStack.context.projects[0].id)) //if neither root-admin, nor the same account, nor the same project
if (((isAdmin() == false && !(jsonObj.domainid == g_domainid && jsonObj.account == g_account)) //if neither root-admin, nor item owner
|| jsonObj.isready == false)
|| (jsonObj.bootable == false)
|| (jsonObj.domainid == 1 && jsonObj.account == "system")
) {
//do nothing
}
else {
allowedActions.push("createVm");
}
*/
// "Download ISO"
//if (((isUser() && jsonObj.ispublic == true && !(jsonObj.domainid == g_domainid && jsonObj.account == g_account)))
if (((isAdmin() == false && !(jsonObj.domainid == g_domainid && jsonObj.account == g_account) && !(jsonObj.domainid == g_domainid && cloudStack.context.projects && jsonObj.projectid == cloudStack.context.projects[0].id))) //if neither root-admin, nor the same account, nor the same project
|| (jsonObj.isready == false) || (jsonObj.domainid == 1 && jsonObj.account == "system")
) {
//do nothing
} else {
if (jsonObj.isextractable){
allowedActions.push("downloadISO");
}
allowedActions.push("shareISO");
}
// "Delete ISO"
//if (((isUser() && jsonObj.ispublic == true && !(jsonObj.domainid == g_domainid && jsonObj.account == g_account)))
if (((isAdmin() == false && !(jsonObj.domainid == g_domainid && jsonObj.account == g_account) && !(jsonObj.domainid == g_domainid && cloudStack.context.projects && jsonObj.projectid == cloudStack.context.projects[0].id))) //if neither root-admin, nor the same account, nor the same project
|| (jsonObj.isready == false && jsonObj.status != null && jsonObj.status.indexOf("Downloaded") != -1) || (jsonObj.account == "system")
) {
//do nothing
} else {
allowedActions.push("remove");
}
return allowedActions;
}
})(cloudStack, jQuery);