From f837a0431d05cb099c9bf8c851a04d4230779001 Mon Sep 17 00:00:00 2001 From: Murali Reddy Date: Fri, 3 Aug 2012 08:51:34 +0530 Subject: [PATCH 1/9] bug CS-15817 system VM's fail to create in basic zone with EIP/ELB network offering removing the ActionEvent annotation on associate IP, acuquire IP methods on internal methods, so that static NAT for system VM succeeds --- .../api/commands/AssociateIPAddrCmd.java | 2 +- .../api/commands/EnableStaticNatCmd.java | 2 +- api/src/com/cloud/network/NetworkService.java | 2 +- .../com/cloud/network/rules/RulesService.java | 2 +- .../com/cloud/network/NetworkManagerImpl.java | 23 +++++++++++++------ .../cloud/network/rules/RulesManagerImpl.java | 6 ++++- 6 files changed, 25 insertions(+), 12 deletions(-) diff --git a/api/src/com/cloud/api/commands/AssociateIPAddrCmd.java b/api/src/com/cloud/api/commands/AssociateIPAddrCmd.java index 0829223d029..73eaf101395 100644 --- a/api/src/com/cloud/api/commands/AssociateIPAddrCmd.java +++ b/api/src/com/cloud/api/commands/AssociateIPAddrCmd.java @@ -217,7 +217,7 @@ public class AssociateIPAddrCmd extends BaseAsyncCreateCmd { @Override public void create() throws ResourceAllocationException{ try { - IpAddress ip = _networkService.allocateIP(_accountService.getAccount(getEntityOwnerId()), false, getZoneId()); + IpAddress ip = _networkService.allocateIP(_accountService.getAccount(getEntityOwnerId()), getZoneId()); if (ip != null) { this.setEntityId(ip.getId()); } else { diff --git a/api/src/com/cloud/api/commands/EnableStaticNatCmd.java b/api/src/com/cloud/api/commands/EnableStaticNatCmd.java index 5b269fb7321..39f3f00d1d0 100644 --- a/api/src/com/cloud/api/commands/EnableStaticNatCmd.java +++ b/api/src/com/cloud/api/commands/EnableStaticNatCmd.java @@ -104,7 +104,7 @@ public class EnableStaticNatCmd extends BaseCmd{ @Override public void execute() throws ResourceUnavailableException{ try { - boolean result = _rulesService.enableStaticNat(ipAddressId, virtualMachineId, getNetworkId(), false); + boolean result = _rulesService.enableStaticNat(ipAddressId, virtualMachineId, getNetworkId()); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); this.setResponseObject(response); diff --git a/api/src/com/cloud/network/NetworkService.java b/api/src/com/cloud/network/NetworkService.java index e1e35de315b..f79086b65e9 100755 --- a/api/src/com/cloud/network/NetworkService.java +++ b/api/src/com/cloud/network/NetworkService.java @@ -38,7 +38,7 @@ public interface NetworkService { List getIsolatedNetworksOwnedByAccountInZone(long zoneId, Account owner); - IpAddress allocateIP(Account ipOwner, boolean isSystem, long zoneId) throws ResourceAllocationException, + IpAddress allocateIP(Account ipOwner, long zoneId) throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException; boolean releaseIpAddress(long ipAddressId) throws InsufficientAddressCapacityException; diff --git a/api/src/com/cloud/network/rules/RulesService.java b/api/src/com/cloud/network/rules/RulesService.java index 28db9dc385d..60cc7b37fcf 100644 --- a/api/src/com/cloud/network/rules/RulesService.java +++ b/api/src/com/cloud/network/rules/RulesService.java @@ -60,7 +60,7 @@ public interface RulesService { boolean applyPortForwardingRules(long ipAdddressId, Account caller) throws ResourceUnavailableException; - boolean enableStaticNat(long ipAddressId, long vmId, long networkId, boolean isSystemVm) throws NetworkRuleConflictException, ResourceUnavailableException; + boolean enableStaticNat(long ipAddressId, long vmId, long networkId) throws NetworkRuleConflictException, ResourceUnavailableException; PortForwardingRule getPortForwardigRule(long ruleId); diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 7e89c142916..02745b7abc5 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -1013,21 +1013,29 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Override @ActionEvent(eventType = EventTypes.EVENT_NET_IP_ASSIGN, eventDescription = "allocating Ip", create = true) - public IpAddress allocateIP(Account ipOwner, boolean isSystem, long zoneId) + public IpAddress allocateIP(Account ipOwner, long zoneId) + throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException { + return allocateIP(ipOwner, false, zoneId); + } + + private IpAddress allocateIP(Account ipOwner, boolean isSystem, long zoneId) throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException { Account caller = UserContext.current().getCaller(); long callerUserId = UserContext.current().getCallerUserId(); // check permissions _accountMgr.checkAccess(caller, null, false, ipOwner); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Associate IP address called by the user " + callerUserId + " account " + ipOwner.getId()); + } DataCenter zone = _configMgr.getZone(zoneId); - return allocateIp(ipOwner, isSystem, caller, callerUserId, zone); + return allocateIp(ipOwner, isSystem, caller, zone); } @DB - public IpAddress allocateIp(Account ipOwner, boolean isSystem, Account caller, long callerUserId, DataCenter zone) + public IpAddress allocateIp(Account ipOwner, boolean isSystem, Account caller, DataCenter zone) throws ConcurrentOperationException, ResourceAllocationException, InsufficientAddressCapacityException { @@ -1046,9 +1054,6 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag Transaction txn = Transaction.currentTxn(); Account accountToLock = null; try { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Associate IP address called by the user " + callerUserId + " account " + ipOwner.getId()); - } accountToLock = _accountDao.acquireInLockTable(ipOwner.getId()); if (accountToLock == null) { s_logger.warn("Unable to lock account: " + ipOwner.getId()); @@ -6981,7 +6986,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag // allocate ip ip = allocateIP(owner, true, guestNetwork.getDataCenterId()); // apply ip associations - ip = associateIPToNetwork(ip.getId(), networkId); + ip = associateIpToNetwork(ip.getId(), networkId); } catch (ResourceAllocationException ex) { throw new CloudRuntimeException("Failed to allocate system ip due to ", ex); } catch (ConcurrentOperationException ex) { @@ -7143,7 +7148,11 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @ActionEvent(eventType = EventTypes.EVENT_NET_IP_ASSIGN, eventDescription = "associating Ip", async = true) public IpAddress associateIPToNetwork(long ipId, long networkId) throws InsufficientAddressCapacityException, ResourceAllocationException, ResourceUnavailableException, ConcurrentOperationException { + return associateIpToNetwork(ipId, networkId); + } + private IpAddress associateIpToNetwork(long ipId, long networkId) throws InsufficientAddressCapacityException, + ResourceAllocationException, ResourceUnavailableException, ConcurrentOperationException { Network network = _networksDao.findById(networkId); if (network == null) { throw new InvalidParameterValueException("Invalid network id is given", null); diff --git a/server/src/com/cloud/network/rules/RulesManagerImpl.java b/server/src/com/cloud/network/rules/RulesManagerImpl.java index 0d6dd57301f..4d73592ebfb 100755 --- a/server/src/com/cloud/network/rules/RulesManagerImpl.java +++ b/server/src/com/cloud/network/rules/RulesManagerImpl.java @@ -382,7 +382,11 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { @Override @ActionEvent(eventType = EventTypes.EVENT_ENABLE_STATIC_NAT, eventDescription = "enabling static nat") - public boolean enableStaticNat(long ipId, long vmId, long networkId, boolean isSystemVm) + public boolean enableStaticNat(long ipId, long vmId, long networkId) throws NetworkRuleConflictException, ResourceUnavailableException { + return enableStaticNat(ipId, vmId, networkId, false); + } + + private boolean enableStaticNat(long ipId, long vmId, long networkId, boolean isSystemVm) throws NetworkRuleConflictException, ResourceUnavailableException { UserContext ctx = UserContext.current(); Account caller = ctx.getCaller(); From 79b850faad92052f77377b6caf9e0b6167bb0a3c Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Fri, 3 Aug 2012 11:13:36 +0530 Subject: [PATCH 2/9] Categories for AutoScale posted bug: http://bugs.cloudstack.org/browse/CS-15828 for improving upstream API doc --- setup/apidoc/gen_toc.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup/apidoc/gen_toc.py b/setup/apidoc/gen_toc.py index 3ad808b0f83..c5fec38bf90 100644 --- a/setup/apidoc/gen_toc.py +++ b/setup/apidoc/gen_toc.py @@ -120,6 +120,9 @@ known_categories = { 'VPC': 'VPC', 'PrivateGateway': 'VPC', 'StaticRoute': 'VPC', + 'AutoScale': 'AutoScale', + 'Counter': 'AutoScale', + 'Condition': 'AutoScale' } From 44c067cd10e02d750bdf70511c083488c52ef80b Mon Sep 17 00:00:00 2001 From: Pranav Saxena Date: Fri, 3 Aug 2012 15:49:26 +0530 Subject: [PATCH 3/9] CS-15793:Enable static NAT for the public IP address screen is not showing VMs --- ui/scripts/network.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/scripts/network.js b/ui/scripts/network.js index 84ee73794a9..d24a8ea230e 100644 --- a/ui/scripts/network.js +++ b/ui/scripts/network.js @@ -1405,9 +1405,9 @@ args.$tierSelect.hide(); } - args.$tierSelect.change(function() { + // args.$tierSelect.change(function() { args.$tierSelect.closest('.list-view').listView('refresh'); - }); + // }); }, listView: $.extend(true, {}, cloudStack.sections.instances, { From a82ad3b3bcd823b26c3ad2ae9d12812beb24f0c8 Mon Sep 17 00:00:00 2001 From: Nitin Mehta Date: Fri, 3 Aug 2012 16:15:22 +0530 Subject: [PATCH 4/9] bug CS-15200: Introducing state transition when volume is getting copied from secondary storage and it is put into Creating state Reviewed-by: Kishan --- api/src/com/cloud/storage/Volume.java | 7 ++++--- server/src/com/cloud/storage/StorageManagerImpl.java | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/api/src/com/cloud/storage/Volume.java b/api/src/com/cloud/storage/Volume.java index e24bc3e7e56..bc702705aae 100755 --- a/api/src/com/cloud/storage/Volume.java +++ b/api/src/com/cloud/storage/Volume.java @@ -32,7 +32,7 @@ public interface Volume extends ControlledEntity, BasedOn, StateObject Date: Fri, 3 Aug 2012 11:03:56 -0700 Subject: [PATCH 5/9] CS-15793: Fix static NAT select when in a VPC network --- ui/scripts/network.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ui/scripts/network.js b/ui/scripts/network.js index d24a8ea230e..1d750a7d319 100644 --- a/ui/scripts/network.js +++ b/ui/scripts/network.js @@ -1405,9 +1405,10 @@ args.$tierSelect.hide(); } - // args.$tierSelect.change(function() { + args.$tierSelect.change(function() { args.$tierSelect.closest('.list-view').listView('refresh'); - // }); + }); + args.$tierSelect.closest('.list-view').listView('refresh'); }, listView: $.extend(true, {}, cloudStack.sections.instances, { From dc32b71de96d5c0cb9bedeea8fe16586b1a87390 Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Fri, 3 Aug 2012 11:12:31 -0700 Subject: [PATCH 6/9] CS-15809: Show account/domain fields on VPC detail view --- ui/scripts/network.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ui/scripts/network.js b/ui/scripts/network.js index 1d750a7d319..20dc79fc53b 100644 --- a/ui/scripts/network.js +++ b/ui/scripts/network.js @@ -3859,6 +3859,8 @@ }, { displaytext: { label: 'label.description', isEditable: true }, + account: { label: 'label.account' }, + domain: { label: 'label.domain' }, zonename: { label: 'label.zone' }, cidr: { label: 'label.cidr' }, networkdomain: { label: 'label.network.domain' }, From 06a83e0c1ca563501bd1bab571e7fd2db45032a4 Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Fri, 3 Aug 2012 11:21:48 -0700 Subject: [PATCH 7/9] CS-15802: Add VPC filter to instance wizard network select Adds drop-down select to filter networks by VPC. -If no VPC is selected, only show non-VPC isolated networks -If VPC is selected, show tiers from specified VPC. Note that only one tier/network can be checked at a time in this mode, and 'add network' text field is hidden --- ui/scripts/instanceWizard.js | 38 +++++++++-- ui/scripts/ui-custom/instanceWizard.js | 91 +++++++++++++++++++++++++- 2 files changed, 122 insertions(+), 7 deletions(-) diff --git a/ui/scripts/instanceWizard.js b/ui/scripts/instanceWizard.js index c4e2f6a10db..291427ec060 100644 --- a/ui/scripts/instanceWizard.js +++ b/ui/scripts/instanceWizard.js @@ -9,7 +9,7 @@ // See the License for the specific language governing permissions and // limitations under the License. (function($, cloudStack) { - var zoneObjs, hypervisorObjs, featuredTemplateObjs, communityTemplateObjs, myTemplateObjs, featuredIsoObjs, community + var zoneObjs, hypervisorObjs, featuredTemplateObjs, communityTemplateObjs, myTemplateObjs, featuredIsoObjs, community; var selectedZoneObj, selectedTemplateObj, selectedHypervisor, selectedDiskOfferingObj; var step5ContainerType = 'nothing-to-select'; //'nothing-to-select', 'select-network', 'select-security-group' @@ -17,6 +17,17 @@ maxDiskOfferingSize: function() { return g_capabilities.customdiskofferingmaxsize; }, + + // Called in networks list, when VPC drop-down is changed + // -- if vpcID given, return true if in network specified by vpcID + // -- if vpcID == -1, return true if network is not associated with a VPC + vpcFilter: function(data, vpcID) { + return vpcID != -1? + data.vpcid == vpcID : + !data.vpcid; + }, + + // Data providers for each wizard step steps: [ // Step 1: Setup function(args) { @@ -301,11 +312,23 @@ networkData.account = g_account; } - var networkObjs; + var networkObjs, vpcObjs; + + // Get VPCs + $.ajax({ + url: createURL('listVPCs'), + data: isDomainAdmin() ? + { account: args.context.users[0].account, domainid: args.context.users[0].domainid } : + { listAll: true }, + async: false, + success: function(json) { + vpcObjs = json.listvpcsresponse.vpc ? json.listvpcsresponse.vpc : []; + } + }); + $.ajax({ url: createURL('listNetworks'), data: networkData, - dataType: "json", async: false, success: function(json) { networkObjs = json.listnetworksresponse.network ? json.listnetworksresponse.network : []; @@ -337,7 +360,8 @@ myNetworks: [], //not used any more sharedNetworks: networkObjs, securityGroups: [], - networkOfferings: networkOfferingObjs + networkOfferings: networkOfferingObjs, + vpcs: vpcObjs } }); } @@ -370,7 +394,8 @@ myNetworks: [], //not used any more sharedNetworks: [], securityGroups: securityGroupArray, - networkOfferings: [] + networkOfferings: [], + vpcs: [] } }); } @@ -382,7 +407,8 @@ myNetworks: [], //not used any more sharedNetworks: [], securityGroups: [], - networkOfferings: [] + networkOfferings: [], + vpcs: [] } }); } diff --git a/ui/scripts/ui-custom/instanceWizard.js b/ui/scripts/ui-custom/instanceWizard.js index 3d82e484dc9..990747d8c0d 100644 --- a/ui/scripts/ui-custom/instanceWizard.js +++ b/ui/scripts/ui-custom/instanceWizard.js @@ -103,6 +103,14 @@ .click(function() { var $radio = $(this).closest('.select').find('input[type=radio]'); + if ($(this).attr('type') == 'checkbox') { + if ($(this).closest('.select-container').hasClass('single-select')) { + $(this).closest('.select').siblings().find('input[type=checkbox]') + .attr('checked', false); + $(this).closest('.select').find('input[type=radio]').click(); + } + } + if ($radio.is(':checked') && !$(this).is(':checked')) { if (!$radio.closest('.select').index()) { return false; @@ -121,7 +129,8 @@ $('
').addClass('select-desc') .append($('
').addClass('name').html(this[fields.name])) .append($('
').addClass('desc').html(this[fields.desc])) - ); + ) + .data('json-obj', this); $selects.append($select); @@ -139,6 +148,11 @@ if (!$checkbox.is(':checked')) { $checkbox.attr('checked', true); } + + if ($(this).closest('.select-container').hasClass('single-select')) { + $(this).closest('.select').siblings().find('input[type=checkbox]') + .attr('checked', false); + } }) .after( $('
').addClass('name').html(options.secondary.desc) @@ -480,9 +494,81 @@ // Show relevant conditional sub-step if present $step.find('.wizard-step-conditional').hide(); + // Filter network list by VPC ID + var filterNetworkList = function(vpcID) { + var $selects = $step.find('.my-networks .select-container .select'); + var $visibleSelects = $($.grep($selects, function(select) { + var $select = $(select); + + return args.vpcFilter($select.data('json-obj'), vpcID); + })); + var $addNetworkForm = $step.find('.select.new-network'); + var $addNewNetworkCheck = $addNetworkForm.find('input[name=new-network]'); + + // VPC networks cannot be created via instance wizard + if (vpcID != -1) { + $step.find('.my-networks .select-container').addClass('single-select'); + $addNetworkForm.hide(); + + if ($addNewNetworkCheck.is(':checked')) { + $addNewNetworkCheck.click(); + $addNewNetworkCheck.attr('checked', false); + } + } else { + $step.find('.my-networks .select-container').removeClass('single-select'); + $addNetworkForm.show(); + } + + $selects.find('input[type=checkbox]').attr('checked', false); + $selects.hide(); + $visibleSelects.show(); + + // Select first visible item by default + $visibleSelects.filter(':first') + .find('input[type=radio]') + .click(); + + cloudStack.evenOdd($visibleSelects, 'div.select', { + even: function($elem) { + $elem.removeClass('odd'); + $elem.addClass('even'); + }, + odd: function($elem) { + $elem.removeClass('even'); + $elem.addClass('odd'); + } + }); + }; + + var $vpcSelect = $step.find('select[name=vpc-filter]'); + + $vpcSelect.unbind('change'); + $vpcSelect.change(function() { + filterNetworkList($vpcSelect.val()); + }); + return { response: { success: function(args) { + var vpcs = args.data.vpcs; + + // Populate VPC drop-down + $vpcSelect.html(''); + $(vpcs).map(function(index, vpc) { + var $option = $('