UI: Zone wizard update

-Allow for editing of traffic labels within the zone wizard; visible
 by going to the create physical network(s) step and clicking the
 'edit' button under each traffic type.

-Make hypervisor selection part of the create zone step, instead of
 the add cluster step -- this is to allow the physical network UI to
 have the selected hypervisor for the edit traffic labels dialog.

-Show drag-and-drop UI for basic zone setup, so that user can edit
 traffic labels for a basic zone. Note that user can only have one
 physical network here.

-Allow creation of storage traffic in a basic zone configuration, by
 optionally dragging storage traffic type icon to first physical
 network
This commit is contained in:
bfederle 2012-03-20 13:23:20 -07:00
parent 59def829ca
commit c23f1b8882
5 changed files with 533 additions and 135 deletions

View File

@ -7,6 +7,10 @@ label.network.service.providers=Network Service Providers
message.launch.zone=Zone is ready to launch; please proceed to the next step.
error.unable.to.reach.management.server=Unable to reach Management Server
label.internal.name=Internal name
message.configure.all.traffic.types=You have multiple physical networks; please configure labels for each traffic type by clicking on the Edit button.
message.edit.traffic.type=Please specify the traffic label you want associated with this traffic type.
label.edit.traffic.type=Edit traffic type
label.label=Label
label.max.networks=Max. networks
error.invalid.username.password=Invalid username or password
message.enabling.security.group.provider=Enabling Security Group provider

View File

@ -5623,7 +5623,7 @@ label.error {
.multi-wizard.zone-wizard .select-container.multi .drop-container {
background: #DAE2EC;
width: 484px;
height: 65px;
height: 100px;
clear: both;
position: relative;
/*+border-radius:4px;*/
@ -5654,7 +5654,7 @@ label.error {
.multi-wizard.zone-wizard .select-container.multi .drop-container ul li {
float: left;
margin: 0px 0 0 16px;
margin: 2px 17px 0 29px;
}
.multi-wizard.zone-wizard .select-container.multi .drop-container span.empty-message {
@ -5722,11 +5722,14 @@ label.error {
margin: 16px 13px 0 0;
}
.multi-wizard.zone-wizard .traffic-types-drag-area > ul > li.management,
.multi-wizard.zone-wizard .traffic-types-drag-area > ul > li.public {
.multi-wizard.zone-wizard .traffic-types-drag-area > ul > li.required {
display: none;
}
.multi-wizard.zone-wizard .traffic-types-drag-area > ul > li.required.clone {
display: block;
}
.multi-wizard.zone-wizard .traffic-types-drag-area > ul > li ul.container {
width: 60px;
height: 54px;
@ -5781,7 +5784,8 @@ label.error {
position: relative;
left: -8px;
top: -6px;
margin-right: -16px;
margin-right: 0px;
width: 70px !important;
}
.multi-wizard.zone-wizard li.traffic-type-draggable.disabled {
@ -5804,7 +5808,7 @@ label.error {
}
.multi-wizard.zone-wizard .select-container.multi li.traffic-type-draggable.management:hover {
margin-right: -18px;
margin-right: -1px;
}
.multi-wizard.zone-wizard li.traffic-type-draggable.public {
@ -5853,6 +5857,75 @@ label.error {
display: none;
}
/*** Traffic type icon -- edit button*/
.multi-wizard.zone-wizard .traffic-type-draggable .edit-traffic-type {
display: none;
}
.multi-wizard.zone-wizard .drop-container .traffic-type-draggable > .edit-traffic-type {
cursor: pointer;
display: block;
width: 59px;
height: 23px;
padding: 2px 9px 0 12px;
background: url(../images/bg-gradients.png) 0px 53px;
border: 1px solid #C4C4C4;
/*+border-radius:4px;*/
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
-khtml-border-radius: 4px;
border-radius: 4px 4px 4px 4px;
border-top: 1px solid #FFFFFF;
/*+placement:shift -15px 61px;*/
position: relative;
left: -15px;
top: 61px;
}
.multi-wizard.zone-wizard .drop-container .traffic-type-draggable > .edit-traffic-type:hover {
background-position: 0px -105px;
color: #FFFFFF;
/*+box-shadow:inset 0px 2px 1px #727272;*/
-moz-box-shadow: inset 0px 2px 1px #727272;
-webkit-box-shadow: inset 0px 2px 1px #727272;
-o-box-shadow: inset 0px 2px 1px #727272;
box-shadow: inset 0px 2px 1px #727272;
}
.multi-wizard.zone-wizard .drop-container .traffic-type-draggable > .edit-traffic-type:hover span {
color: #FFFFFF;
/*+text-shadow:0px 1px 1px #000000;*/
-moz-text-shadow: 0px 1px 1px #000000;
-webkit-text-shadow: 0px 1px 1px #000000;
-o-text-shadow: 0px 1px 1px #000000;
text-shadow: 0px 1px 1px #000000;
}
.multi-wizard.zone-wizard .drop-container .traffic-type-draggable:hover > .edit-traffic-type {
/*+placement:shift -7px 67px;*/
position: relative;
left: -7px;
top: 67px;
}
.multi-wizard.zone-wizard .drop-container .traffic-type-draggable .edit-traffic-type span {
text-align: center;
font-size: 11px;
font-weight: bold;
color: #4E73A6;
/*+text-shadow:0px 1px #FFFFFF;*/
-moz-text-shadow: 0px 1px #FFFFFF;
-webkit-text-shadow: 0px 1px #FFFFFF;
-o-text-shadow: 0px 1px #FFFFFF;
text-shadow: 0px 1px #FFFFFF;
}
.multi-wizard.zone-wizard .drop-container .traffic-type-draggable .edit-traffic-type span.icon {
float: left;
background: url(../images/sprites.png) -7px -4px;
padding: 7px 11px 0 7px;
}
/*** Configure guest network -- tabs*/
.multi-wizard.zone-wizard .setup-guest-traffic .ui-widget-content {
width: 682px;
@ -8353,13 +8426,11 @@ div.panel.ui-dialog div.list-view div.fixed-header {
background-position: 1px -674px;
}
.migrate .icon,
.migrateToAnotherStorage .icon {
.migrate .icon {
background-position: 0px -125px;
}
.migrate:hover .icon,
.migrateToAnotherStorage:hover .icon {
.migrate:hover .icon {
background-position: 0px -707px;
}

View File

@ -508,7 +508,13 @@
<ul class="container">
<li traffic-type-id="management"
title="Traffic between CloudStack's internal resources, including any components that communicate with the Management Server, such as hosts and CloudStack system VMs"
class="traffic-type-draggable management"></li>
class="traffic-type-draggable management">
<!-- Edit buttton -->
<div class="edit-traffic-type">
<span class="icon">&nbsp;</span>
<span>Edit</span>
</div>
</li>
</ul>
<div class="info">
<div class="title"><fmt:message key="label.management"/></div>
@ -519,7 +525,13 @@
<ul class="container">
<li traffic-type-id="public"
title="Traffic between the internet and virtual machines in the cloud."
class="traffic-type-draggable public"></li>
class="traffic-type-draggable public">
<!-- Edit buttton -->
<div class="edit-traffic-type">
<span class="icon">&nbsp;</span>
<span>Edit</span>
</div>
</li>
</ul>
<div class="info">
<div class="title"><fmt:message key="label.public"/></div>
@ -530,7 +542,13 @@
<ul class="container">
<li traffic-type-id="guest"
title="Traffic between end-user virtual machines"
class="traffic-type-draggable guest clone"></li>
class="traffic-type-draggable guest">
<!-- Edit buttton -->
<div class="edit-traffic-type">
<span class="icon">&nbsp;</span>
<span>Edit</span>
</div>
</li>
</ul>
<div class="info">
<div class="title"><fmt:message key="label.guest"/></div>
@ -541,7 +559,13 @@
<ul class="container">
<li traffic-type-id="storage"
title="Traffic between primary and secondary storage servers, such as VM templates and snapshots"
class="traffic-type-draggable storage"></li>
class="traffic-type-draggable storage">
<!-- Edit buttton -->
<div class="edit-traffic-type">
<span class="icon">&nbsp;</span>
<span>Edit</span>
</div>
</li>
</ul>
<div class="info">
<div class="title"><fmt:message key="label.storage"/></div>
@ -1621,6 +1645,10 @@
<script language="javascript">
dictionary = {
'label.edit.traffic.type': '<fmt:message key="label.edit.traffic.type"/>',
'message.edit.traffic.type': '<fmt:message key="message.edit.traffic.type"/>',
'label.label': '<fmt:message key="label.label"/>',
'message.configure.all.traffic.types': '<fmt:message key="message.configure.all.traffic.types"/>',
'label.max.networks': '<fmt:message key="label.max.networks"/>',
'label.latest.events': '<fmt:message key="label.latest.events"/>',
'state.Enabled': '<fmt:message key="state.Enabled"/>',

View File

@ -45,10 +45,21 @@
function(network) {
var $network = $(network);
var $guestForm = $wizard.find('form[guest-network-id=' + $network.index() + ']');
var trafficTypeConfiguration = {};
$network.find('.traffic-type-draggable').each(function() {
var $trafficType = $(this);
var trafficTypeID = $trafficType.attr('traffic-type-id');
trafficTypeConfiguration[trafficTypeID] = $trafficType.data('traffic-type-data');
});
return {
id: $network.index(),
name: $network.find('.field.name input[type=text]').val(),
// Traffic type list
trafficTypes: $.map(
$network.find('.traffic-type-draggable'),
function(trafficType) {
@ -57,6 +68,10 @@
return $trafficType.attr('traffic-type-id');
}
),
// Traffic type configuration data
trafficTypeConfiguration: trafficTypeConfiguration,
guestConfiguration: $guestForm.size() ?
cloudStack.serializeForm($guestForm) : null
};
@ -93,7 +108,7 @@
var $storageTrafficItem = $(storageTrafficItem);
var storageTrafficData = {};
var fields = [
'gateway',
'gateway',
'netmask',
'vlanid',
'startip',
@ -139,6 +154,30 @@
message: dictionary['message.please.add.at.lease.one.traffic.range']
});
return false;
},
physicalNetworks: function($form) {
var $enabledPhysicalNetworks = $form.filter(':not(.disabled)').filter(function() {
return $(this).find('.traffic-type-draggable').size();
});
var $trafficTypes = $enabledPhysicalNetworks.find('.traffic-type-draggable');
var $configuredTrafficTypes = $trafficTypes.filter(function() {
var $trafficType = $(this);
return $trafficType.data('traffic-type-data') &&
$trafficType.data('traffic-type-data').label.length >= 1;
});
if ($enabledPhysicalNetworks.size() > 1 &&
$configuredTrafficTypes.size() != $trafficTypes.size()) {
cloudStack.dialog.notice({
message: _l('message.configure.all.traffic.types')
});
return false;
}
return true;
}
};
@ -153,6 +192,8 @@
if ($multiEditForm.size()) {
isCustomValidated = customValidation.networkRanges($multiEditForm);
} else if ($physicalNetworks.size()) {
isCustomValidated = customValidation.physicalNetworks($physicalNetworks);
} else {
isCustomValidated = true;
}
@ -160,35 +201,114 @@
return isCustomValidated;
};
var isAdvancedNetwork = function($wizard) {
return getData($wizard, { all: true })['network-model'] == 'Advanced';
};
/**
* Setup physical network wizard UI
*/
var physicalNetwork = {
init: function($wizard) {
// Initialize initial physical networks
for (var i = 0; i < 2; i++) {
var $physicalNetwork = physicalNetwork.add($wizard);
if (i == 0) {
$physicalNetwork.find('.button.remove.physical-network').remove();
}
var $existingPhysicalNetworks = physicalNetwork.getNetworks($wizard);
// Initialize physical networks
if (!$existingPhysicalNetworks.size()) {
physicalNetwork.add($wizard);
} else if (!isAdvancedNetwork($wizard)) {
$existingPhysicalNetworks.filter(':first').siblings().each(function() {
physicalNetwork.remove($(this));
});
}
// First physical network gets required traffic types
$(physicalNetwork.requiredTrafficTypes).each(function () {
var $firstPhysicalNetwork = physicalNetwork.getPhysicalNetworks($wizard).filter(':first');
physicalNetwork.updateNetworks(physicalNetwork.getNetworks($wizard));
physicalNetwork.assignTrafficType(this, $firstPhysicalNetwork);
$wizard.find('.traffic-types-drag-area ul li').removeClass('required disabled clone');
// Setup clone traffic types
$(physicalNetwork.cloneTrafficTypes($wizard)).each(function() {
var trafficTypeID = this;
$wizard.find('.traffic-types-drag-area ul li').filter(function() {
return $(this).hasClass(trafficTypeID);
}).addClass('clone');
});
// Setup required traffic types
$(physicalNetwork.requiredTrafficTypes($wizard)).each(function () {
var trafficTypeID = this;
var $firstPhysicalNetwork = physicalNetwork.getNetworks($wizard).filter(':first');
// First physical network gets required traffic types
physicalNetwork.assignTrafficType(trafficTypeID, $firstPhysicalNetwork);
$wizard.find('.traffic-types-drag-area ul li').filter(function() {
return $(this).hasClass(trafficTypeID);
}).addClass('required');
});
// Setup disabled traffic types
$(physicalNetwork.disabledTrafficTypes($wizard)).each(function() {
var trafficTypeID = this;
var $trafficType = physicalNetwork.getTrafficType(this, $wizard);
physicalNetwork.unassignTrafficType($trafficType);
$wizard.find('.traffic-types-drag-area ul li').filter(function() {
return $(this).hasClass(trafficTypeID);
}).addClass('disabled');
});
},
/**
* Required traffic type IDs for proper validation
* Traffic type edit dialog
*/
requiredTrafficTypes: [
'management',
'public',
'guest'
],
editTrafficTypeDialog: function($trafficType) {
var trafficData = $trafficType.data('traffic-type-data') ?
$trafficType.data('traffic-type-data') : {};
var hypervisor = getData($trafficType.closest('.zone-wizard')).zone.hypervisor;
cloudStack.dialog.createForm({
form: {
title: _l('label.edit.traffic.type'),
desc: _l('message.edit.traffic.type'),
fields: {
label: { label: hypervisor + ' ' + _l('label.label'), defaultValue: trafficData.label }
}
},
after: function(args) {
$trafficType.data('traffic-type-data', args.data);
}
});
},
/**
* Get required traffic type IDs for proper validation
*/
requiredTrafficTypes: function($wizard) {
return cloudStack.zoneWizard.requiredTrafficTypes({
data: getData($wizard)
});
},
/**
* Get required traffic type IDs for proper validation
*/
disabledTrafficTypes: function($wizard) {
return cloudStack.zoneWizard.disabledTrafficTypes({
data: getData($wizard)
});
},
/**
* Get clone-type traffic type IDs for proper validation
*/
cloneTrafficTypes: function($wizard) {
return cloudStack.zoneWizard.cloneTrafficTypes({
data: getData($wizard)
});
},
/**
* Physical network step: Renumber network form items
@ -261,7 +381,7 @@
*
* @param $container Physical network step - main container
*/
getPhysicalNetworks: function($container) {
getNetworks: function($container) {
return $container.find('.select-container.multi');
},
@ -271,7 +391,7 @@
* @param $trafficType
*/
isTrafficTypeClone: function($trafficType) {
return $trafficType.hasClass('clone');
return physicalNetwork.getOriginalTrafficContainer($trafficType).parent().hasClass('clone');
},
/**
@ -280,11 +400,13 @@
* @param trafficTypeID ID of desired traffic type
* @param $physicalNetwork Physical network elem
*/
assignTrafficType: function(trafficTypeID, $physicalNetwork) {
assignTrafficType: function(trafficTypeID, $physicalNetwork, data) {
var $container = physicalNetwork.getMainContainer($physicalNetwork);
var $trafficType = physicalNetwork.getTrafficType(trafficTypeID, $container);
var $dropArea = $physicalNetwork.find('.drop-container ul');
if ($physicalNetwork.find('.traffic-type-draggable[traffic-type-id=' + trafficTypeID + ']').size()) return false;
if (physicalNetwork.isTrafficTypeClone($trafficType)) {
if (!physicalNetwork.getTrafficType(trafficTypeID, $physicalNetwork).size()) {
$trafficType = $trafficType.clone()
@ -298,7 +420,11 @@
$trafficType.appendTo($dropArea);
}
physicalNetwork.update($.merge($physicalNetwork, $physicalNetwork.siblings()));
if (data) {
$trafficType.data('traffic-type-data', data);
}
physicalNetwork.updateNetworks($.merge($physicalNetwork, $physicalNetwork.siblings()));
return $trafficType;
},
@ -310,25 +436,26 @@
* @param $container Physical network wizard step container
* @param $physicalNetwork (optional) Specific physical network to remove from -- only for clones
*/
unassignTrafficType: function(trafficTypeID, $container, $physicalNetwork) {
var $trafficType = physicalNetwork.getTrafficType(trafficTypeID, $container);
unassignTrafficType: function($trafficType) {
var $wizard = $trafficType.closest('.zone-wizard');
var $originalContainer = physicalNetwork.getOriginalTrafficContainer($trafficType);
var $physicalNetworks = physicalNetwork.getNetworks($wizard);
var trafficTypeID = $trafficType.attr('traffic-type-id');
if (physicalNetwork.isTrafficTypeClone($trafficType)) {
// Multiple traffic type elems present -- only get from physical network(s)
if ($physicalNetwork) {
$trafficType = physicalNetwork.getTrafficType(trafficTypeID, $physicalNetwork);
} else {
$trafficType = physicalNetwork.getTrafficType(trafficTypeID, physicalNetwork.getPhysicalNetworks($container));
}
$trafficType.remove();
} else {
// Just 1 traffic type elem present
if (!physicalNetwork.isTrafficTypeClone($trafficType) &&
$.inArray(trafficTypeID, physicalNetwork.requiredTrafficTypes($wizard)) == -1) {
$trafficType.appendTo($originalContainer);
}
} else {
physicalNetwork.assignTrafficType(
trafficTypeID,
$physicalNetworks.filter(':first')
);
physicalNetwork.update(physicalNetwork.getPhysicalNetworks($container));
if (physicalNetwork.isTrafficTypeClone($trafficType) &&
$physicalNetworks.find('.traffic-type-draggable[traffic-type-id=' + trafficTypeID + ']').size() > 1) {
$trafficType.remove();
}
}
return $trafficType;
},
@ -336,7 +463,11 @@
/**
* Returns true if new physical network item needs to be added
*/
needNew: function($containers) {
needsNewNetwork: function($containers) {
// Basic zones do not have multiple physical networks
if (!isAdvancedNetwork($containers.closest('.zone-wizard')))
return false;
var $emptyContainers = $containers.filter(function() {
return !$(this).find('li').size();
});
@ -347,9 +478,11 @@
/**
* Cleanup physical network containers
*/
update: function($containers) {
updateNetworks: function($containers) {
var $mainContainer = physicalNetwork.getMainContainer($containers);
var $allPhysicalNetworks = physicalNetwork.getPhysicalNetworks($mainContainer);
var $allPhysicalNetworks = physicalNetwork.getNetworks($mainContainer);
var containerTotal = isAdvancedNetwork($containers.closest('.zone-wizard')) ?
2 : 1;
$allPhysicalNetworks.each(function() {
var $ul = $(this).find('.drop-container ul');
@ -366,7 +499,7 @@
$containers.each(function() {
var $currentContainer = $(this);
if (!$currentContainer.find('li').size() &&
$containers.size() > 2) {
$containers.size() > containerTotal) {
$currentContainer.remove();
}
});
@ -374,10 +507,12 @@
$containers = $containers.closest('.setup-physical-network')
.find('.select-container.multi');
if (physicalNetwork.needNew($containers)) {
if (physicalNetwork.needsNewNetwork($containers)) {
physicalNetwork.add($mainContainer.parent());
}
$containers.filter(':first').find('.remove.physical-network').remove();
return $containers;
},
@ -396,7 +531,9 @@
stop: function(event, ui) {
$(this).removeClass('disabled');
}
},
cancel: '.edit-traffic-type'
};
},
@ -439,19 +576,20 @@
var $ul = $(this).find('ul');
$ul.removeClass('active');
physicalNetwork.update($(this).closest('.select-container.multi'));
physicalNetwork.updateNetworks($(this).closest('.select-container.multi'));
},
drop: function(event, ui) {
var trafficTypeID = ui.draggable.attr('traffic-type-id');
var $physicalNetwork = $(this).closest('.select-container.multi');
var trafficTypeData = ui.draggable.data('traffic-type-data');
if (trafficTypeID == 'guest' &&
ui.draggable.closest('.select-container.multi').size()) {
ui.draggable.remove();
}
physicalNetwork.assignTrafficType(trafficTypeID, $physicalNetwork);
physicalNetwork.assignTrafficType(trafficTypeID, $physicalNetwork, trafficTypeData);
}
});
@ -463,26 +601,24 @@
// Initialize new default network form elem
$physicalNetworkItem.append(
$deleteButton,
$icon,
$nameField,
$idField,
$dropContainer
);
// Only advanced zones can remove physical network
if (isAdvancedNetwork($wizard)) {
$physicalNetworkItem.prepend($deleteButton);
}
$physicalNetworkItem.hide().appendTo($container).fadeIn('fast');
$physicalNetworkItem.find('.name input').val('Physical Network ' + parseInt($physicalNetworkItem.index() + 1));
physicalNetwork.renumberFormItems($container);
// Remove network action
$physicalNetworkItem.find('.button.remove.physical-network').click(function() {
$physicalNetworkItem.find('li.traffic-type-draggable').each(function() {
var trafficTypeID = $(this).attr('traffic-type-id');
physicalNetwork.assignTrafficType(trafficTypeID, $physicalNetworkItem.prev());
});
$physicalNetworkItem.find('li.traffic-type-draggable.clone').remove();
physicalNetwork.update($physicalNetworkItem.parent().find('.multi'));
physicalNetwork.remove($physicalNetworkItem);
});
$physicalNetworkItem.addClass('disabled'); // Since there are no traffic types yet
@ -492,33 +628,24 @@
/**
* Physical network step: Remove specified network element
*
* @param $physicalNetworkItem Physical network container to remove
*/
remove: function($item) {
var $container = $item.closest('.setup-physical-network .content.input-area form');
remove: function($physicalNetworkItem) {
var $container = $physicalNetworkItem.closest('.setup-physical-network .content.input-area form');
var $trafficTypes = $physicalNetworkItem.find('li.traffic-type-draggable');
if (!$item.siblings().size()) {
cloudStack.dialog.notice({
message: dictionary['message.you.must.have.at.least.one.physical.network']
});
} else if ($item.find('input[type=radio]:checked').size()) {
cloudStack.dialog.notice({
message: dictionary['message.please.select.a.different.public.and.management.network.before.removing']
});
} else {
// Put any traffic type symbols back in original container
$item.find('li.traffic-type-draggable').each(function() {
var $draggable = $(this);
var $originalContainer = $('.traffic-types-drag-area:visible > ul > li')
.filter(function() {
return $(this).hasClass($draggable.attr('traffic-type-id'));
});
$trafficTypes.each(function() {
var trafficTypeID = $(this).attr('traffic-type-id');
$draggable.appendTo($item.prev());
});
$item.remove();
}
physicalNetwork.assignTrafficType(
trafficTypeID,
$physicalNetworkItem.prev()
);
});
$trafficTypes.filter('.clone').remove();
physicalNetwork.updateNetworks($physicalNetworkItem.parent().find('.multi'));
$container.validate('refresh');
}
};
@ -528,7 +655,7 @@
*/
var guestTraffic = {
init: function($wizard, args) {
var $physicalNetworks = physicalNetwork.getPhysicalNetworks($wizard);
var $physicalNetworks = physicalNetwork.getNetworks($wizard);
var $tabs = guestTraffic.makeTabs($physicalNetworks, args);
var $container = guestTraffic.getMainContainer($wizard);
@ -688,7 +815,7 @@
if (isError) {
$li.prev().addClass('error');
}
};
args.action({
@ -844,6 +971,9 @@
guestTraffic.remove($wizard);
}
break;
case 'setupPhysicalNetwork':
physicalNetwork.init($wizard);
}
if ($uiCustom.size()) {
@ -1021,6 +1151,16 @@
return false;
}
// Edit traffic type button
var $editTrafficTypeButton = $target.closest('.drop-container .traffic-type-draggable .edit-traffic-type');
var $trafficType = $editTrafficTypeButton.closest('.traffic-type-draggable');
if ($editTrafficTypeButton.size()) {
physicalNetwork.editTrafficTypeDialog($trafficType);
return false;
}
return true;
});
@ -1035,27 +1175,12 @@
// For removing traffic types from physical network
$wizard.find('.traffic-types-drag-area').droppable({
drop: function(event, ui) {
var trafficTypeID = ui.draggable.attr('traffic-type-id');
if (!physicalNetwork.isTrafficTypeClone(ui.draggable)) {
if ($.inArray(trafficTypeID, physicalNetwork.requiredTrafficTypes) == -1) {
physicalNetwork.unassignTrafficType(trafficTypeID, $wizard);
} else {
physicalNetwork.assignTrafficType(
trafficTypeID,
$wizard.find('.select-container.multi:first')
);
}
} else if (!ui.draggable.closest('.traffic-types-drag-area').size()) {
ui.draggable.remove();
}
physicalNetwork.unassignTrafficType(ui.draggable);
return true;
}
});
physicalNetwork.init($wizard);
showStep(1);
return $wizard.dialog({

View File

@ -6,8 +6,78 @@
var selectedNetworkOfferingHavingNetscaler = false;
var returnedPublicVlanIpRanges = []; //public VlanIpRanges returned by API
var configurationUseLocalStorage = false;
// Makes URL string for traffic label
var trafficLabelParam = function(trafficTypeID, data, physicalNetworkID) {
var zoneType = data.zone.networkType;
var hypervisor = data.zone.hypervisor;
physicalNetworkID = zoneType == 'Advanced' ? physicalNetworkID : 0;
var physicalNetwork = data.physicalNetworks ? data.physicalNetworks[physicalNetworkID] : null;
var trafficConfig = physicalNetwork ? physicalNetwork.trafficTypeConfiguration[trafficTypeID] : null;
var trafficLabel = trafficConfig ? trafficConfig.label : null;
var hypervisorAttr, trafficLabelStr;
switch(hypervisor) {
case 'XenServer':
hypervisorAttr = 'xennetworklabel';
break;
case 'KVM':
hypervisorAttr = 'kvmnetworklabel';
break;
case 'VMWare':
hypervisorAttr = 'vmwarenetworklabel';
break;
case 'BareMetal':
hypervisorAttr = 'baremetalnetworklabel';
break;
case 'Ovm':
hypervisorAttr = 'ovmnetworklabel';
break;
}
trafficLabelStr = trafficLabel ? '&' + hypervisorAttr + '=' + trafficLabel : '';
return trafficLabelStr;
};
cloudStack.zoneWizard = {
// Return required traffic types, for configure physical network screen
requiredTrafficTypes: function(args) {
if (args.data.zone.networkType == 'Basic' && (selectedNetworkOfferingHavingEIP ||
selectedNetworkOfferingHavingELB)) {
return [
'management',
'guest'
];
} else {
return [
'management',
'guest',
'public'
];
}
},
disabledTrafficTypes: function(args) {
if (args.data.zone.networkType == 'Basic' && (selectedNetworkOfferingHavingEIP ||
selectedNetworkOfferingHavingELB)) {
return [
'public'
];
} else {
return [];
}
},
cloneTrafficTypes: function(args) {
if (args.data.zone.networkType == 'Advanced') {
return ['guest'];
} else {
return [];
}
},
customUI: {
publicTrafficIPRange: function(args) {
var multiEditData = [];
@ -137,7 +207,7 @@
},
setupPhysicalNetwork: function(args) {
return args.data['network-model'] == 'Advanced';
return true; // Both basic & advanced zones show physical network UI
},
configureGuestTraffic: function(args) {
@ -148,10 +218,9 @@
},
configureStorageTraffic: function(args) {
return args.data['network-model'] == 'Advanced' &&
$.grep(args.groupedData.physicalNetworks, function(network) {
return $.inArray('storage', network.trafficTypes) > -1;
}).length;
return $.grep(args.groupedData.physicalNetworks, function(network) {
return $.inArray('storage', network.trafficTypes) > -1;
}).length;
},
addHost: function(args) {
@ -227,6 +296,29 @@
label: 'label.internal.dns.2',
desc: 'message.tooltip.internal.dns.2'
},
hypervisor: {
label: 'label.hypervisor',
validation: { required: true },
select: function(args) {
$.ajax({
url: createURL('listHypervisors'),
data: { listAll: true },
success: function(json) {
args.response.success({
data: $.map(
json.listhypervisorsresponse.hypervisor,
function(hypervisor) {
return {
id: hypervisor.name,
description: hypervisor.name
};
}
)
});
}
});
}
},
networkOfferingId: {
label: 'label.network.offering',
select: function(args) {
@ -473,6 +565,9 @@
hypervisor: {
label: 'label.hypervisor',
select: function(args) {
// Disable select -- selection is made on zone setup step
args.$select.attr('disabled', 'disabled');
$.ajax({
url: createURL("listHypervisors"),
dataType: "json",
@ -484,6 +579,8 @@
items.push({id: this.name, description: this.name})
});
args.response.success({data: items});
args.$select.val(args.context.zones[0].hypervisor);
args.$select.change();
}
});
@ -710,11 +807,14 @@
validation: { required: true },
select: function(args) {
var selectedClusterObj = {
hypervisortype: args.context.zones[0].hypervisor
hypervisortype: $.isArray(args.context.zones[0].hypervisor) ?
// We want the cluster's hypervisor type
args.context.zones[0].hypervisor[1] : args.context.zones[0].hypervisor
};
if(selectedClusterObj == null)
if(selectedClusterObj == null) {
return;
}
if(selectedClusterObj.hypervisortype == "KVM") {
var items = [];
@ -1079,11 +1179,11 @@
$("body").stopTime(timerKey);
if (result.jobstatus == 1) {
var returnedBasicPhysicalNetwork = result.jobresult.physicalnetwork;
var label = returnedBasicPhysicalNetwork.id + trafficLabelParam('guest', data);
var returnedTrafficTypes = [];
$.ajax({
url: createURL("addTrafficType&trafficType=Guest&physicalnetworkid=" + returnedBasicPhysicalNetwork.id),
url: createURL("addTrafficType&trafficType=Guest&physicalnetworkid=" + label),
dataType: "json",
success: function(json) {
var jobId = json.addtraffictyperesponse.jobid;
@ -1126,8 +1226,10 @@
}
});
label = trafficLabelParam('management', data);
$.ajax({
url: createURL("addTrafficType&trafficType=Management&physicalnetworkid=" + returnedBasicPhysicalNetwork.id),
url: createURL("addTrafficType&trafficType=Management&physicalnetworkid=" + returnedBasicPhysicalNetwork.id + label),
dataType: "json",
success: function(json) {
var jobId = json.addtraffictyperesponse.jobid;
@ -1170,9 +1272,59 @@
}
});
if(selectedNetworkOfferingHavingSG == true && selectedNetworkOfferingHavingEIP == true && selectedNetworkOfferingHavingELB == true) {
// Storage traffic
if (data.physicalNetworks &&
$.inArray('storage', data.physicalNetworks[0].trafficTypes) > -1) {
label = trafficLabelParam('storage', data);
$.ajax({
url: createURL("addTrafficType&trafficType=Public&physicalnetworkid=" + returnedBasicPhysicalNetwork.id),
url: createURL('addTrafficType&physicalnetworkid=' + returnedBasicPhysicalNetwork.id + '&trafficType=Storage' + label),
dataType: "json",
success: function(json) {
var jobId = json.addtraffictyperesponse.jobid;
var timerKey = "addTrafficTypeJob_" + jobId;
$("body").everyTime(2000, timerKey, 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 {
$("body").stopTime(timerKey);
if (result.jobstatus == 1) {
returnedTrafficTypes.push(result.jobresult.traffictype);
if(returnedTrafficTypes.length == requestedTrafficTypeCount) { //all requested traffic types have been added
returnedBasicPhysicalNetwork.returnedTrafficTypes = returnedTrafficTypes;
stepFns.configurePhysicalNetwork({
data: $.extend(args.data, {
returnedBasicPhysicalNetwork: returnedBasicPhysicalNetwork
})
});
}
}
else if (result.jobstatus == 2) {
alert("Failed to add Management traffic type to basic zone. Error: " + _s(result.jobresult.errortext));
}
}
},
error: function(XMLHttpResponse) {
var errorMsg = parseXMLHttpResponse(XMLHttpResponse);
alert("Failed to add Management traffic type to basic zone. Error: " + errorMsg);
}
});
});
}
});
}
if (selectedNetworkOfferingHavingSG == true && selectedNetworkOfferingHavingEIP == true && selectedNetworkOfferingHavingELB == true) {
label = trafficLabelParam('public', data);
$.ajax({
url: createURL("addTrafficType&trafficType=Public&physicalnetworkid=" + returnedBasicPhysicalNetwork.id + label),
dataType: "json",
success: function(json) {
var jobId = json.addtraffictyperesponse.jobid;
@ -1231,7 +1383,7 @@
});
}
else if(args.data.zone.networkType == "Advanced") {
$(args.data.physicalNetworks).each(function(){
$(args.data.physicalNetworks).each(function(index) {
var thisPhysicalNetwork = this;
$.ajax({
url: createURL("createPhysicalNetwork&zoneid=" + args.data.returnedZone.id + "&name=" + todb(thisPhysicalNetwork.name)),
@ -1255,20 +1407,29 @@
returnedPhysicalNetwork.originalId = thisPhysicalNetwork.id;
var returnedTrafficTypes = [];
var label; // Traffic type label
$(thisPhysicalNetwork.trafficTypes).each(function(){
var thisTrafficType = this;
var apiCmd = "addTrafficType&physicalnetworkid=" + returnedPhysicalNetwork.id;
if(thisTrafficType == "public")
if(thisTrafficType == "public") {
apiCmd += "&trafficType=Public";
else if(thisTrafficType == "management")
label = trafficLabelParam('public', data, index);
}
else if(thisTrafficType == "management") {
apiCmd += "&trafficType=Management";
else if(thisTrafficType == "guest")
label = trafficLabelParam('management', data, index);
}
else if(thisTrafficType == "guest") {
apiCmd += "&trafficType=Guest";
else if(thisTrafficType == "storage")
label = trafficLabelParam('guest', data, index);
}
else if(thisTrafficType == "storage") {
apiCmd += "&trafficType=Storage";
label = trafficLabelParam('storage', data, index);
}
$.ajax({
url: createURL(apiCmd),
url: createURL(apiCmd + label),
dataType: "json",
success: function(json) {
var jobId = json.addtraffictyperesponse.jobid;
@ -2030,9 +2191,15 @@
});
}
else { //basic zone without public traffic type , skip to next step
stepFns.configureGuestTraffic({
data: args.data
});
if (data.physicalNetworks && $.inArray('storage', data.physicalNetworks[0].trafficTypes) > -1) {
stepFns.configureStorageTraffic({
data: args.data
});
} else {
stepFns.configureGuestTraffic({
data: args.data
});
}
}
},
@ -2046,8 +2213,7 @@
var targetNetwork = $.grep(args.data.physicalNetworks, function(net) {
return $.inArray('storage', net.trafficTypes) > -1; });
if (args.data.zone.networkType == 'Basic' ||
!targetNetwork.length) {
if (!targetNetwork.length) {
return complete({});
}
@ -2233,7 +2399,11 @@
},
addCluster: function(args) {
message(dictionary['message.creating.cluster']);
message(dictionary['message.creating.cluster']);
// Have cluster use zone's hypervisor
args.data.cluster.hypervisor = args.data.zone.hypervisor ?
args.data.zone.hypervisor : args.data.cluster.hypervisor;
var array1 = [];
array1.push("&zoneId=" + args.data.returnedZone.id);
@ -2303,7 +2473,7 @@
array1.push("&zoneid=" + args.data.returnedZone.id);
array1.push("&podid=" + args.data.returnedPod.id);
array1.push("&clusterid=" + args.data.returnedCluster.id);
array1.push("&hypervisor=" + todb(args.data.cluster.hypervisor));
array1.push("&hypervisor=" + todb(args.data.returnedCluster.hypervisortype));
var clustertype = args.data.returnedCluster.clustertype;
array1.push("&clustertype=" + todb(clustertype));
array1.push("&hosttags=" + todb(args.data.host.hosttags));