diff --git a/api/src/com/cloud/api/BaseCmd.java b/api/src/com/cloud/api/BaseCmd.java index 2ca70577c14..faa4d5b71eb 100755 --- a/api/src/com/cloud/api/BaseCmd.java +++ b/api/src/com/cloud/api/BaseCmd.java @@ -36,7 +36,7 @@ import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.NetworkService; import com.cloud.network.StorageNetworkService; -import com.cloud.network.VirtualNetworkApplianceService; +import com.cloud.network.VpcVirtualNetworkApplianceService; import com.cloud.network.as.AutoScaleService; import com.cloud.network.firewall.FirewallService; import com.cloud.network.firewall.NetworkACLService; @@ -117,7 +117,7 @@ public abstract class BaseCmd { public static SecurityGroupService _securityGroupService; public static SnapshotService _snapshotService; public static ConsoleProxyService _consoleProxyService; - public static VirtualNetworkApplianceService _routerService; + public static VpcVirtualNetworkApplianceService _routerService; public static ResponseGenerator _responseGenerator; public static EntityManager _entityMgr; public static RulesService _rulesService; @@ -149,7 +149,7 @@ public abstract class BaseCmd { _securityGroupService = locator.getManager(SecurityGroupService.class); _snapshotService = locator.getManager(SnapshotService.class); _consoleProxyService = locator.getManager(ConsoleProxyService.class); - _routerService = locator.getManager(VirtualNetworkApplianceService.class); + _routerService = locator.getManager(VpcVirtualNetworkApplianceService.class); _entityMgr = locator.getManager(EntityManager.class); _rulesService = locator.getManager(RulesService.class); _lbService = locator.getManager(LoadBalancingRulesService.class); 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/VpcVirtualNetworkApplianceService.java b/api/src/com/cloud/network/VpcVirtualNetworkApplianceService.java index 3123cc2432b..eaaecf1a3c0 100644 --- a/api/src/com/cloud/network/VpcVirtualNetworkApplianceService.java +++ b/api/src/com/cloud/network/VpcVirtualNetworkApplianceService.java @@ -20,7 +20,7 @@ import com.cloud.network.router.VirtualRouter; /** * @author Alena Prokharchyk */ -public interface VpcVirtualNetworkApplianceService { +public interface VpcVirtualNetworkApplianceService extends VirtualNetworkApplianceService{ /** * @param router 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/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 { @Inject LoadBalancingRulesManager _lbMgr; @Inject - VirtualNetworkApplianceManager _routerMgr; - @Inject DomainRouterDao _routerDao = null; @Inject protected HostPodDao _podDao = null; diff --git a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java index 5e0328bb671..cae9a4b8e70 100644 --- a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java @@ -128,6 +128,7 @@ import com.cloud.vm.dao.VMInstanceDao; public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplianceManagerImpl implements VpcVirtualNetworkApplianceManager{ private static final Logger s_logger = Logger.getLogger(VpcVirtualNetworkApplianceManagerImpl.class); + String _name; @Inject VpcDao _vpcDao; @Inject @@ -1348,4 +1349,5 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian _s2sVpnMgr.markDisconnectVpnConnByVpc(vpcId); } } + } 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(); diff --git a/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java b/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java index b5fa4ea7aab..ba4d4009317 100755 --- a/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java +++ b/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java @@ -49,7 +49,6 @@ import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.RemoteAccessVpnDao; import com.cloud.network.dao.VpnUserDao; import com.cloud.network.element.RemoteAccessVPNServiceProvider; -import com.cloud.network.router.VirtualNetworkApplianceManager; import com.cloud.network.rules.FirewallManager; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.FirewallRule.Purpose; @@ -87,7 +86,6 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag @Inject VpnUserDao _vpnUsersDao; @Inject RemoteAccessVpnDao _remoteAccessVpnDao; @Inject IPAddressDao _ipAddressDao; - @Inject VirtualNetworkApplianceManager _routerMgr; @Inject AccountManager _accountMgr; @Inject DomainManager _domainMgr; @Inject NetworkManager _networkMgr; diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 545817e8da6..31ec7ec1607 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -121,7 +121,6 @@ import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.HypervisorGuruManager; import com.cloud.network.NetworkManager; -import com.cloud.network.router.VirtualNetworkApplianceManager; import com.cloud.org.Grouping; import com.cloud.org.Grouping.AllocationState; import com.cloud.projects.Project.ListProjectResourcesCriteria; @@ -293,8 +292,6 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag @Inject protected ClusterDao _clusterDao; @Inject - protected VirtualNetworkApplianceManager _routerMgr; - @Inject protected UsageEventDao _usageEventDao; @Inject protected VirtualMachineManager _vmMgr; @@ -732,6 +729,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag StoragePoolVO destPool = findStoragePool(dskCh, dc, pod, clusterId, vm, avoidPools); // Copy the volume from secondary storage to the destination storage pool + stateTransitTo(volume, Event.CopyRequested); VolumeHostVO volumeHostVO = _volumeHostDao.findByVolumeId(volume.getId()); HostVO secStorage = _hostDao.findById(volumeHostVO.getHostId()); String secondaryStorageURL = secStorage.getStorageUrl(); diff --git a/server/src/com/cloud/upgrade/dao/Upgrade218to22.java b/server/src/com/cloud/upgrade/dao/Upgrade218to22.java index c39074bd109..48d063506c0 100644 --- a/server/src/com/cloud/upgrade/dao/Upgrade218to22.java +++ b/server/src/com/cloud/upgrade/dao/Upgrade218to22.java @@ -37,7 +37,7 @@ import com.cloud.consoleproxy.ConsoleProxyManager; import com.cloud.event.EventTypes; import com.cloud.event.EventVO; import com.cloud.event.UsageEventVO; -import com.cloud.network.router.VirtualNetworkApplianceManager; +import com.cloud.network.router.VpcVirtualNetworkApplianceManager; import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.utils.DateUtil; import com.cloud.utils.NumbersUtil; @@ -1404,7 +1404,7 @@ public class Upgrade218to22 implements DbUpgrade { pstmt.close(); int proxyRamSize = NumbersUtil.parseInt(getConfigValue(conn, "consoleproxy.ram.size"), ConsoleProxyManager.DEFAULT_PROXY_VM_RAMSIZE); - int domrRamSize = NumbersUtil.parseInt(getConfigValue(conn, "router.ram.size"), VirtualNetworkApplianceManager.DEFAULT_ROUTER_VM_RAMSIZE); + int domrRamSize = NumbersUtil.parseInt(getConfigValue(conn, "router.ram.size"), VpcVirtualNetworkApplianceManager.DEFAULT_ROUTER_VM_RAMSIZE); int ssvmRamSize = NumbersUtil.parseInt(getConfigValue(conn, "secstorage.vm.ram.size"), SecondaryStorageVmManager.DEFAULT_SS_VM_RAMSIZE); pstmt = conn @@ -1563,7 +1563,7 @@ public class Upgrade218to22 implements DbUpgrade { pstmt.close(); int proxyCpuMhz = NumbersUtil.parseInt(getConfigValue(conn, "consoleproxy.cpu.mhz"), ConsoleProxyManager.DEFAULT_PROXY_VM_CPUMHZ); - int domrCpuMhz = NumbersUtil.parseInt(getConfigValue(conn, "router.cpu.mhz"), VirtualNetworkApplianceManager.DEFAULT_ROUTER_CPU_MHZ); + int domrCpuMhz = NumbersUtil.parseInt(getConfigValue(conn, "router.cpu.mhz"), VpcVirtualNetworkApplianceManager.DEFAULT_ROUTER_CPU_MHZ); int ssvmCpuMhz = NumbersUtil.parseInt(getConfigValue(conn, "secstorage.vm.cpu.mhz"), SecondaryStorageVmManager.DEFAULT_SS_VM_CPUMHZ); pstmt = conn 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' } 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/network.js b/ui/scripts/network.js index 84ee73794a9..31e2c97a4fd 100644 --- a/ui/scripts/network.js +++ b/ui/scripts/network.js @@ -1408,6 +1408,7 @@ args.$tierSelect.change(function() { args.$tierSelect.closest('.list-view').listView('refresh'); }); + args.$tierSelect.closest('.list-view').listView('refresh'); }, listView: $.extend(true, {}, cloudStack.sections.instances, { @@ -3858,10 +3859,22 @@ }, { 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' }, state: { label: 'label.state' }, + restartrequired: { + label: 'label.restart.required', + converter: function(booleanValue) { + if (booleanValue == true) { + return "Yes"; + } + + return "No"; + } + }, id: { label: 'label.id' } } ], 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 = $('