From f1ac568a912df647a397dc47e5842e4ab7609987 Mon Sep 17 00:00:00 2001 From: anthony Date: Thu, 5 Jul 2012 11:53:04 -0700 Subject: [PATCH 01/16] VPC : check if dns1 is null --- .../network/router/VirtualNetworkApplianceManagerImpl.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index b5aed7e089b..2488c680db2 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -1717,7 +1717,9 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian * to return DNS server rather than * virtual router itself. */ if (dnsProvided || dhcpProvided) { - buf.append(" dns1=").append(defaultDns1); + if (defaultDns1 != null) { + buf.append(" dns1=").append(defaultDns1); + } if (defaultDns2 != null) { buf.append(" dns2=").append(defaultDns2); } From 212baba7b1b5fb6429d7e3aa6e496a5440e1a210 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Thu, 5 Jul 2012 13:14:52 -0700 Subject: [PATCH 02/16] cloudstack 3.0 UI - VPC - implement "Add new tier" action. --- ui/scripts/vpc.js | 109 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 81 insertions(+), 28 deletions(-) diff --git a/ui/scripts/vpc.js b/ui/scripts/vpc.js index b8beeaa5aa7..23b424decab 100644 --- a/ui/scripts/vpc.js +++ b/ui/scripts/vpc.js @@ -380,35 +380,84 @@ return state == 'Running' ? ['start'] : ['stop']; }, - actions: { - // Add new tier + actions: { add: { - label: 'Add new tier to VPC', - action: function(args) { - setTimeout(function() { - args.response.success({ - data: { - name: args.data.name, - cidr: args.data.cidr, - state: 'Stopped' - } - }); - }, 500); - }, - - createForm: { - title: 'Add new tier', - desc: 'Please fill in the following to add a new VPC tier.', - fields: { - name: { label: 'label.name', validation: { required: true } }, - cidr: { label: 'label.cidr', validation: { required: true } } - } - }, - - notification: { - poll: function(args) { args.complete(); } - } - }, + label: 'Add new tier', + createForm: { + title: 'Add new tier', + fields: { + name: { label: 'label.name', + validation: { required: true } + }, + networkOfferingId: { + label: 'label.network.offering', + validation: { required: true }, + dependsOn: 'zoneId', + select: function(args) { + $.ajax({ + url: createURL('listNetworkOfferings'), + data: { + forvpc: true, + zoneid: args.zoneId, + guestiptype: 'Isolated', + supportedServices: 'SourceNat', + specifyvlan: false, + state: 'Enabled' + }, + success: function(json) { + var networkOfferings = json.listnetworkofferingsresponse.networkoffering; + args.response.success({ + data: $.map(networkOfferings, function(zone) { + return { + id: zone.id, + description: zone.name + }; + }) + }); + } + }); + } + }, + gateway: { + label: 'label.gateway', + validation: { required: true } + }, + netmask: { + label: 'label.netmask', + validation: { required: true } + }, + } + }, + action: function(args) { + var dataObj = { + vpcid: args.context.vpc[0].id, + zoneId: args.context.vpc[0].zoneid, + networkOfferingId: args.data.networkOfferingId, + name: args.data.name, + displayText: args.data.name, + gateway: args.data.gateway, + netmask: args.data.netmask + }; + + $.ajax({ + url: createURL('createNetwork'), + dataType: 'json', + data: dataObj, + success: function(json) { + args.response.success({ + data: json.createnetworkresponse.network + }); + }, + error: function(XMLHttpResponse) { + args.response.error(parseXMLHttpResponse(XMLHttpResponse)); + } + }); + }, + messages: { + notification: function() { return 'Add new tier'; } + } + }, + start: { label: 'Start tier', shortLabel: 'Start', @@ -419,6 +468,7 @@ poll: function(args) { args.complete({ data: { state: 'Running' } }); } } }, + stop: { label: 'Stop tier', shortLabel: 'Stop', @@ -429,6 +479,7 @@ poll: function(args) { args.complete({ data: { state: 'Stopped' } }); } } }, + addVM: { label: 'Add VM to tier', shortLabel: 'Add VM', @@ -439,11 +490,13 @@ poll: pollAsyncJobResult } }, + acl: { label: 'Configure ACL for tier', shortLabel: 'ACL', multiEdit: aclMultiEdit }, + remove: { label: 'Remove tier', action: function(args) { From 26afe3a96c36ed13bc71db46becc4eb444faa4f0 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Thu, 5 Jul 2012 13:16:57 -0700 Subject: [PATCH 03/16] cloudstack 3.0 UI - instance wizard - network offering dropdown - populate only network offerings that are not for VPC. --- ui/scripts/instanceWizard.js | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/ui/scripts/instanceWizard.js b/ui/scripts/instanceWizard.js index 9d4a151f086..9d3347a3677 100644 --- a/ui/scripts/instanceWizard.js +++ b/ui/scripts/instanceWizard.js @@ -286,15 +286,18 @@ networkObjs = json.listnetworksresponse.network ? json.listnetworksresponse.network : []; } }); - - - var apiCmd = "listNetworkOfferings&guestiptype=Isolated&supportedServices=sourceNat&state=Enabled&specifyvlan=false&zoneid=" + args.currentData.zoneid ; - var array1 = []; - var guestTrafficTypeTotal = 0; - + $.ajax({ - url: createURL(apiCmd + array1.join("")), //get the network offering for isolated network with sourceNat + url: createURL("listNetworkOfferings"), dataType: "json", + data: { + forvpc: false, + zoneid: args.currentData.zoneid, + guestiptype: 'Isolated', + supportedServices: 'SourceNat', + specifyvlan: false, + state: 'Enabled' + }, async: false, success: function(json) { networkOfferingObjs = json.listnetworkofferingsresponse.networkoffering; From a39a08a40d040d326709ca733264d15d1e80c805 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Thu, 5 Jul 2012 13:19:07 -0700 Subject: [PATCH 04/16] cloudstack 3.0 UI: ui-custom VPC - add error handling to addTierDialog(). --- ui/scripts/ui-custom/vpc.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ui/scripts/ui-custom/vpc.js b/ui/scripts/ui-custom/vpc.js index c598c0880a6..84d0abe58b7 100644 --- a/ui/scripts/ui-custom/vpc.js +++ b/ui/scripts/ui-custom/vpc.js @@ -504,7 +504,11 @@ $loading.remove(); } ); - } + }, + error: function(errorMsg) { + cloudStack.dialog.notice({ message: _s(errorMsg) }); + $loading.remove(); + } } }); } From 2699e2c508177c12daddc9dd52f98c5a1afb30d5 Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Thu, 5 Jul 2012 13:33:46 -0700 Subject: [PATCH 05/16] VPC: CS-15447 - fail vpc creation when vpc provider is not enabled at least in one physical network in the target zone --- .../com/cloud/network/NetworkManagerImpl.java | 6 +++--- .../com/cloud/network/vpc/VpcManagerImpl.java | 19 ++++++++++++++++++- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index e135264d3a4..14c48b6c3cb 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -2084,7 +2084,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag List providersToImplement = getNetworkProviders(network.getId()); for (NetworkElement element : _networkElements) { if (providersToImplement.contains(element.getProvider())) { - if (!isProviderEnabledInPhysicalNetwork(getPhysicalNetworkId(network), "VirtualRouter")) { + if (!isProviderEnabledInPhysicalNetwork(getPhysicalNetworkId(network), element.getProvider().getName())) { // The physicalNetworkId will not get translated into a uuid by the reponse serializer, // because the serializer would look up the NetworkVO class's table and retrieve the // network id instead of the physical network id. @@ -3521,7 +3521,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag for (NetworkElement element : _networkElements) { if (providersToShutdown.contains(element.getProvider())) { try { - if (!isProviderEnabledInPhysicalNetwork(getPhysicalNetworkId(network), "VirtualRouter")) { + if (!isProviderEnabledInPhysicalNetwork(getPhysicalNetworkId(network), element.getProvider().getName())) { s_logger.warn("Unable to complete shutdown of the network elements due to element: " + element.getName() + " either doesn't exist or not enabled in the physical network " + getPhysicalNetworkId(network)); success = false; @@ -3608,7 +3608,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag for (NetworkElement element : _networkElements) { if (providersToDestroy.contains(element.getProvider())) { try { - if (!isProviderEnabledInPhysicalNetwork(getPhysicalNetworkId(network), "VirtualRouter")) { + if (!isProviderEnabledInPhysicalNetwork(getPhysicalNetworkId(network), element.getProvider().getName())) { s_logger.warn("Unable to complete destroy of the network elements due to element: " + element.getName() + " either doesn't exist or not enabled in the physical network " + getPhysicalNetworkId(network)); success = false; diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java index 12529134032..1697864323f 100644 --- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java +++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java @@ -56,6 +56,7 @@ import com.cloud.network.Networks.TrafficType; import com.cloud.network.PhysicalNetwork; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.PhysicalNetworkDao; import com.cloud.network.element.VpcProvider; import com.cloud.network.vpc.VpcOffering.State; import com.cloud.network.vpc.Dao.PrivateIpDao; @@ -132,6 +133,8 @@ public class VpcManagerImpl implements VpcManager, Manager{ NetworkOfferingServiceMapDao _ntwkOffServiceDao ; @Inject VpcOfferingServiceMapDao _vpcOffServiceDao; + @Inject + PhysicalNetworkDao _pNtwkDao; private final ScheduledExecutorService _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("VpcChecker")); @@ -502,7 +505,7 @@ public class VpcManagerImpl implements VpcManager, Manager{ if (networkDomain == null) { networkDomain = "cs" + Long.toHexString(owner.getId()) + _ntwkMgr.getDefaultNetworkDomain(); } - } + } return createVpc(zoneId, vpcOffId, owner, vpcName, displayText, cidr, networkDomain); } @@ -511,6 +514,20 @@ public class VpcManagerImpl implements VpcManager, Manager{ public Vpc createVpc(long zoneId, long vpcOffId, Account vpcOwner, String vpcName, String displayText, String cidr, String networkDomain) { + //the provider has to be enabled at least in one network in the zone + boolean providerEnabled = false; + for (PhysicalNetwork pNtwk : _pNtwkDao.listByZone(zoneId)) { + if (_ntwkMgr.isProviderEnabledInPhysicalNetwork(pNtwk.getId(), Provider.VPCVirtualRouter.getName())) { + providerEnabled = true; + break; + } + } + + if (!providerEnabled) { + throw new InvalidParameterValueException("Provider " + Provider.VPCVirtualRouter.getName() + + " should be enabled in at least one physical network of the zone specified"); + } + //Validate CIDR if (!NetUtils.isValidCIDR(cidr)) { throw new InvalidParameterValueException("Invalid CIDR specified " + cidr); From 2195f3ad838047f2492b58395820ce27db7b6be8 Mon Sep 17 00:00:00 2001 From: Murali Reddy Date: Thu, 5 Jul 2012 13:45:29 -0700 Subject: [PATCH 06/16] VPC : CS-15424 default route & gateway is missing for private network in VPC virtual router on Vmware reviewd by : Anthony adding route configuration through eth0 when VPC router --- patches/systemvm/debian/config/etc/init.d/cloud-early-config | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/patches/systemvm/debian/config/etc/init.d/cloud-early-config b/patches/systemvm/debian/config/etc/init.d/cloud-early-config index 2e6d3c3bca7..21324cbbac5 100755 --- a/patches/systemvm/debian/config/etc/init.d/cloud-early-config +++ b/patches/systemvm/debian/config/etc/init.d/cloud-early-config @@ -596,7 +596,10 @@ EOF fi if [ -n "$MGMTNET" -a -n "$LOCAL_GW" ] then - ip route add $MGMTNET via $LOCAL_GW dev eth1 + if [ "$hyp" == "vmware" ] + then + ip route add $MGMTNET via $LOCAL_GW dev eth0 + fi fi ip route delete default From d8cdb89721bab3ed9f77270a142b0c84eaa08246 Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Thu, 5 Jul 2012 13:52:11 -0700 Subject: [PATCH 07/16] VPC: added field networkacl_service_provided to physical_network_service_providers table --- .../network/PhysicalNetworkServiceProvider.java | 2 ++ .../dao/PhysicalNetworkServiceProviderVO.java | 13 +++++++++++++ setup/db/create-schema.sql | 1 + 3 files changed, 16 insertions(+) diff --git a/api/src/com/cloud/network/PhysicalNetworkServiceProvider.java b/api/src/com/cloud/network/PhysicalNetworkServiceProvider.java index 109db0d7ee4..195640678e2 100644 --- a/api/src/com/cloud/network/PhysicalNetworkServiceProvider.java +++ b/api/src/com/cloud/network/PhysicalNetworkServiceProvider.java @@ -60,4 +60,6 @@ public interface PhysicalNetworkServiceProvider { List getEnabledServices(); String getUuid(); + + boolean isNetworkAclServiceProvided(); } diff --git a/server/src/com/cloud/network/dao/PhysicalNetworkServiceProviderVO.java b/server/src/com/cloud/network/dao/PhysicalNetworkServiceProviderVO.java index 3e5694100c6..0fac443037e 100644 --- a/server/src/com/cloud/network/dao/PhysicalNetworkServiceProviderVO.java +++ b/server/src/com/cloud/network/dao/PhysicalNetworkServiceProviderVO.java @@ -87,6 +87,9 @@ public class PhysicalNetworkServiceProviderVO implements PhysicalNetworkServiceP @Column(name = "security_group_service_provided") boolean securitygroupServiceProvided; + @Column(name = "networkacl_service_provided") + boolean networkAclServiceProvided; + @Column(name=GenericDao.REMOVED_COLUMN) Date removed; @@ -261,6 +264,7 @@ public class PhysicalNetworkServiceProviderVO implements PhysicalNetworkServiceP this.setPortForwardingServiceProvided(services.contains(Service.PortForwarding)); this.setUserdataServiceProvided(services.contains(Service.UserData)); this.setSecuritygroupServiceProvided(services.contains(Service.SecurityGroup)); + this.setNetworkAclServiceProvided(services.contains(Service.NetworkACL)); } @Override @@ -301,4 +305,13 @@ public class PhysicalNetworkServiceProviderVO implements PhysicalNetworkServiceP } return services; } + + @Override + public boolean isNetworkAclServiceProvided() { + return networkAclServiceProvided; + } + + public void setNetworkAclServiceProvided(boolean networkAclServiceProvided) { + this.networkAclServiceProvided = networkAclServiceProvided; + } } diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index c2eafd661f7..b33459ad2f4 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -2003,6 +2003,7 @@ CREATE TABLE `cloud`.`physical_network_service_providers` ( `port_forwarding_service_provided` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is Port Forwarding service provided', `user_data_service_provided` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is UserData service provided', `security_group_service_provided` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is SG service provided', + `networkacl_service_provided` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is Network ACL service provided', `removed` datetime COMMENT 'date removed if not null', PRIMARY KEY (`id`), CONSTRAINT `fk_pnetwork_service_providers__physical_network_id` FOREIGN KEY (`physical_network_id`) REFERENCES `physical_network`(`id`) ON DELETE CASCADE, From a44843af69591e397e73b32ddfaa90dd310985dc Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Thu, 5 Jul 2012 14:04:34 -0700 Subject: [PATCH 08/16] VPC: added "forVpc" (boolean) parameter to listRouters call - filter by the fact if router belongs to VPC or not --- api/src/com/cloud/api/commands/ListRoutersCmd.java | 7 +++++++ server/src/com/cloud/server/ManagementServerImpl.java | 11 ++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/api/src/com/cloud/api/commands/ListRoutersCmd.java b/api/src/com/cloud/api/commands/ListRoutersCmd.java index 0fb4dcc65c9..32dc0695fa6 100644 --- a/api/src/com/cloud/api/commands/ListRoutersCmd.java +++ b/api/src/com/cloud/api/commands/ListRoutersCmd.java @@ -66,6 +66,9 @@ public class ListRoutersCmd extends BaseListProjectAndAccountResourcesCmd { @IdentityMapper(entityTableName="vpc") @Parameter(name=ApiConstants.VPC_ID, type=CommandType.LONG, description="List networks by VPC") private Long vpcId; + + @Parameter(name=ApiConstants.FOR_VPC, type=CommandType.BOOLEAN, description="if true is passed for this parameter, list only VPC routers") + private Boolean forVpc; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -102,6 +105,10 @@ public class ListRoutersCmd extends BaseListProjectAndAccountResourcesCmd { public Long getVpcId() { return vpcId; } + + public Boolean getForVpc() { + return forVpc; + } ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 40b9265318f..2f0f334ea9a 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -1601,6 +1601,7 @@ public class ManagementServerImpl implements ManagementServer { String keyword = cmd.getKeyword(); Long networkId = cmd.getNetworkId(); Long vpcId = cmd.getVpcId(); + Boolean forVpc = cmd.getForVpc(); Account caller = UserContext.current().getCaller(); List permittedAccounts = new ArrayList(); @@ -1622,6 +1623,14 @@ public class ManagementServerImpl implements ManagementServer { sb.and("podId", sb.entity().getPodIdToDeployIn(), SearchCriteria.Op.EQ); sb.and("hostId", sb.entity().getHostId(), SearchCriteria.Op.EQ); sb.and("vpcId", sb.entity().getVpcId(), SearchCriteria.Op.EQ); + + if (forVpc != null) { + if (forVpc) { + sb.and("forVpc", sb.entity().getVpcId(), SearchCriteria.Op.NNULL); + } else { + sb.and("forVpc", sb.entity().getVpcId(), SearchCriteria.Op.NULL); + } + } if (networkId != null) { SearchBuilder nicSearch = _nicDao.createSearchBuilder(); @@ -1632,7 +1641,7 @@ public class ManagementServerImpl implements ManagementServer { sb.join("nicSearch", nicSearch, sb.entity().getId(), nicSearch.entity().getInstanceId(), JoinBuilder.JoinType.INNER); } - + SearchCriteria sc = sb.create(); _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); From c258664a69d613a223d1044049e26e6cd2422e7f Mon Sep 17 00:00:00 2001 From: anthony Date: Thu, 5 Jul 2012 14:21:15 -0700 Subject: [PATCH 09/16] VPC : CS-15463 allow input traffic for established connection --- patches/systemvm/debian/config/etc/init.d/cloud-early-config | 2 +- patches/systemvm/debian/config/etc/iptables/iptables-vpcrouter | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/patches/systemvm/debian/config/etc/init.d/cloud-early-config b/patches/systemvm/debian/config/etc/init.d/cloud-early-config index 21324cbbac5..b141110a80e 100755 --- a/patches/systemvm/debian/config/etc/init.d/cloud-early-config +++ b/patches/systemvm/debian/config/etc/init.d/cloud-early-config @@ -560,7 +560,7 @@ setup_vpcrouter() { fi cat > /etc/network/interfaces << EOF -auto lo $1 +auto lo iface lo inet loopback EOF setup_interface "0" $ETH0_IP $ETH0_MASK $GW diff --git a/patches/systemvm/debian/config/etc/iptables/iptables-vpcrouter b/patches/systemvm/debian/config/etc/iptables/iptables-vpcrouter index 8e3069bc033..f60a1e41234 100644 --- a/patches/systemvm/debian/config/etc/iptables/iptables-vpcrouter +++ b/patches/systemvm/debian/config/etc/iptables/iptables-vpcrouter @@ -11,7 +11,8 @@ COMMIT -A INPUT -d 225.0.0.50/32 -j ACCEPT -A INPUT -p icmp -j ACCEPT -A INPUT -i lo -j ACCEPT --A INPUT -i eth0 -p tcp --dport 3922 -j ACCEPT +-A INPUT -i eth0 -p tcp -m state --state NEW --dport 3922 -j ACCEPT +-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT COMMIT *mangle From 24023fd14d4233bbf01649e89f470d0aa64cd09d Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Thu, 5 Jul 2012 15:20:22 -0700 Subject: [PATCH 10/16] VPC: don't allow vpcs for the same account with overlapping cidrs --- server/src/com/cloud/network/vpc/VpcManagerImpl.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java index 1697864323f..1ad63f1ffa6 100644 --- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java +++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java @@ -543,6 +543,15 @@ public class VpcManagerImpl implements VpcManager, Manager{ } + //don't allow overlapping CIDRS for the VPCs of the same account + List vpcs = getVpcsForAccount(vpcOwner.getId()); + for (Vpc vpc : vpcs) { + if (NetUtils.isNetworksOverlap(cidr, vpc.getCidr())) { + throw new InvalidParameterValueException("Account already has vpc with cidr " + vpc.getCidr() + + " that overlaps the cidr specified: " + cidr); + } + } + VpcVO vpc = new VpcVO (zoneId, vpcName, displayText, vpcOwner.getId(), vpcOwner.getDomainId(), vpcOffId, cidr, networkDomain); vpc = _vpcDao.persist(vpc); From 21cdd08948725c519e88d7486c4ee27167e3967a Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Thu, 5 Jul 2012 15:28:30 -0700 Subject: [PATCH 11/16] VPC: don't allow vm to be a part of more than one VPC --- server/src/com/cloud/vm/UserVmManagerImpl.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 1ea462c72d2..aa384702e26 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -2341,6 +2341,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager List> networks = new ArrayList>(); short defaultNetworkNumber = 0; boolean securityGroupEnabled = false; + boolean vpcNetwork = false; for (NetworkVO network : networkList) { if (network.getDataCenterId() != zone.getId()) { throw new InvalidParameterValueException("Network id=" + network.getId() + " doesn't belong to zone " + zone.getId()); @@ -2368,6 +2369,14 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager if (_networkMgr.isSecurityGroupSupportedInNetwork(network)) { securityGroupEnabled = true; } + + //vm can't be a part of more than 1 VPC network + if (network.getVpcId() != null) { + if (vpcNetwork) { + throw new InvalidParameterValueException("Vm can't be a part of more than 1 VPC network"); + } + vpcNetwork = true; + } } if (securityGroupIdList != null && !securityGroupIdList.isEmpty() && !securityGroupEnabled) { From a0a5e25e323ad72619ef5c287ac3922f7e43b27b Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Thu, 5 Jul 2012 15:43:46 -0700 Subject: [PATCH 12/16] CS-15456: Prohibit creating more than one VPN gateway of VPC --- .../network/dao/Site2SiteVpnGatewayDao.java | 1 + .../dao/Site2SiteVpnGatewayDaoImpl.java | 21 +++++++++++++++++++ .../network/vpn/Site2SiteVpnManagerImpl.java | 5 +++++ 3 files changed, 27 insertions(+) diff --git a/server/src/com/cloud/network/dao/Site2SiteVpnGatewayDao.java b/server/src/com/cloud/network/dao/Site2SiteVpnGatewayDao.java index e9dcbbfbeb0..c1d075e2768 100644 --- a/server/src/com/cloud/network/dao/Site2SiteVpnGatewayDao.java +++ b/server/src/com/cloud/network/dao/Site2SiteVpnGatewayDao.java @@ -7,4 +7,5 @@ import com.cloud.utils.db.GenericDao; public interface Site2SiteVpnGatewayDao extends GenericDao { Site2SiteVpnGatewayVO findByIpAddrId(long id); + List listByVpcId(long vpcId); } diff --git a/server/src/com/cloud/network/dao/Site2SiteVpnGatewayDaoImpl.java b/server/src/com/cloud/network/dao/Site2SiteVpnGatewayDaoImpl.java index feab33a992f..4963d827ec9 100644 --- a/server/src/com/cloud/network/dao/Site2SiteVpnGatewayDaoImpl.java +++ b/server/src/com/cloud/network/dao/Site2SiteVpnGatewayDaoImpl.java @@ -6,21 +6,35 @@ import javax.ejb.Local; import org.apache.log4j.Logger; +import com.cloud.network.IPAddressVO; import com.cloud.network.Site2SiteVpnGatewayVO; +import com.cloud.utils.component.ComponentLocator; +import com.cloud.utils.component.Inject; import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.JoinBuilder.JoinType; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; @Local(value={Site2SiteVpnGatewayDao.class}) public class Site2SiteVpnGatewayDaoImpl extends GenericDaoBase implements Site2SiteVpnGatewayDao { + protected final IPAddressDaoImpl _addrDao = ComponentLocator.inject(IPAddressDaoImpl.class); + private static final Logger s_logger = Logger.getLogger(Site2SiteVpnGatewayDaoImpl.class); private final SearchBuilder AllFieldsSearch; + private final SearchBuilder VpcSearch; + private final SearchBuilder AddrSearch; protected Site2SiteVpnGatewayDaoImpl() { AllFieldsSearch = createSearchBuilder(); AllFieldsSearch.and("addrId", AllFieldsSearch.entity().getAddrId(), SearchCriteria.Op.EQ); AllFieldsSearch.done(); + + VpcSearch = createSearchBuilder(); + AddrSearch = _addrDao.createSearchBuilder(); + AddrSearch.and("vpcId", AddrSearch.entity().getVpcId(), SearchCriteria.Op.EQ); + VpcSearch.join("addrSearch", AddrSearch, AddrSearch.entity().getId(), VpcSearch.entity().getAddrId(), JoinType.INNER); + VpcSearch.done(); } @Override @@ -29,4 +43,11 @@ public class Site2SiteVpnGatewayDaoImpl extends GenericDaoBase listByVpcId(long vpcId) { + SearchCriteria sc = VpcSearch.create(); + sc.setJoinParameters("addrSearch", "vpcId", vpcId); + return listBy(sc); + } } diff --git a/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java b/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java index 0104d09c27a..56934e91981 100644 --- a/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java +++ b/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java @@ -80,12 +80,17 @@ public class Site2SiteVpnManagerImpl implements Site2SiteVpnService, Manager { public Site2SiteVpnGateway createVpnGateway(CreateVpnGatewayCmd cmd) { Long ipId = cmd.getPublicIpId(); IpAddress ip = _networkMgr.getIp(ipId); + Long vpcId = ip.getVpcId(); if (ip.getVpcId() == null) { throw new InvalidParameterValueException("The VPN gateway cannot create with ip not belong to VPC"); } if (_vpnGatewayDao.findByIpAddrId(ipId) != null) { throw new InvalidParameterValueException("The VPN gateway with ip ID " + ipId + " already existed!"); } + List gws = _vpnGatewayDao.listByVpcId(vpcId); + if (gws != null && gws.size() != 0) { + throw new InvalidParameterValueException("The VPN gateway of VPC " + vpcId + " already existed!"); + } Site2SiteVpnGatewayVO gw = new Site2SiteVpnGatewayVO(ipId); _vpnGatewayDao.persist(gw); return gw; From 78e1d37e8f88879479e8fdd1958d1df0787236d9 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Thu, 5 Jul 2012 15:18:50 -0700 Subject: [PATCH 13/16] cloudstack 3.0 UI - VPC - add zone wizard - enable VpcVirtualRouter element, enable VpcVirtualRouter provider for advanced zone. --- ui/scripts/zoneWizard.js | 118 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 114 insertions(+), 4 deletions(-) diff --git a/ui/scripts/zoneWizard.js b/ui/scripts/zoneWizard.js index 5843001dce4..f5f09c29cf9 100644 --- a/ui/scripts/zoneWizard.js +++ b/ui/scripts/zoneWizard.js @@ -1226,7 +1226,7 @@ }, action: function(args) { - var advZoneConfiguredPhysicalNetworkCount = 0; //for multiple physical networks in advanced zone + var advZoneConfiguredVirtualRouterCount = 0; //for multiple physical networks in advanced zone. Each physical network has 2 virtual routers: regular one and VPC one. var success = args.response.success; var error = args.response.error; @@ -1874,7 +1874,7 @@ if (result.jobstatus == 1) { //alert("updatePhysicalNetwork succeeded."); - // get network service provider ID of Virtual Router + // ***** Virtual Router ***** (begin) ***** var virtualRouterProviderId; $.ajax({ url: createURL("listNetworkServiceProviders&name=VirtualRouter&physicalNetworkId=" + thisPhysicalNetwork.id), @@ -1947,8 +1947,8 @@ clearInterval(enableVirtualRouterProviderIntervalID); if (result.jobstatus == 1) { //Virtual Router Provider has been enabled successfully - advZoneConfiguredPhysicalNetworkCount++; - if(advZoneConfiguredPhysicalNetworkCount == args.data.returnedPhysicalNetworks.length) { //not call addPod() until all physical networks get configured + advZoneConfiguredVirtualRouterCount++; + if(advZoneConfiguredVirtualRouterCount == (args.data.returnedPhysicalNetworks.length * 2)) { //not call addPod() until virtualRouter and vpcVirtualRouter of all physical networks get configured stepFns.addPod({ data: args.data }); @@ -1981,6 +1981,116 @@ }, 3000); } }); + // ***** Virtual Router ***** (end) ***** + + // ***** VPC Virtual Router ***** (begin) ***** + var vpcVirtualRouterProviderId; + $.ajax({ + url: createURL("listNetworkServiceProviders&name=VpcVirtualRouter&physicalNetworkId=" + thisPhysicalNetwork.id), + dataType: "json", + async: false, + success: function(json) { + var items = json.listnetworkserviceprovidersresponse.networkserviceprovider; + if(items != null && items.length > 0) { + vpcVirtualRouterProviderId = items[0].id; + } + } + }); + if(vpcVirtualRouterProviderId == null) { + alert("error: listNetworkServiceProviders API doesn't return VpcVirtualRouter provider ID"); + return; + } + + var vpcVirtualRouterElementId; + $.ajax({ + url: createURL("listVirtualRouterElements&nspid=" + vpcVirtualRouterProviderId), + dataType: "json", + async: false, + success: function(json) { + var items = json.listvirtualrouterelementsresponse.virtualrouterelement; + if(items != null && items.length > 0) { + vpcVirtualRouterElementId = items[0].id; + } + } + }); + if(vpcVirtualRouterElementId == null) { + alert("error: listVirtualRouterElements API doesn't return VPC Virtual Router Element Id"); + return; + } + + $.ajax({ + url: createURL("configureVirtualRouterElement&enabled=true&id=" + vpcVirtualRouterElementId), + dataType: "json", + async: false, + success: function(json) { + var jobId = json.configurevirtualrouterelementresponse.jobid; + var enableVpcVirtualRouterElementIntervalID = 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(enableVpcVirtualRouterElementIntervalID); + + if (result.jobstatus == 1) { //configureVirtualRouterElement succeeded + $.ajax({ + url: createURL("updateNetworkServiceProvider&state=Enabled&id=" + vpcVirtualRouterProviderId), + dataType: "json", + async: false, + success: function(json) { + var jobId = json.updatenetworkserviceproviderresponse.jobid; + var enableVpcVirtualRouterProviderIntervalID = 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(enableVpcVirtualRouterProviderIntervalID); + + if (result.jobstatus == 1) { //Virtual Router Provider has been enabled successfully + advZoneConfiguredVirtualRouterCount++; + if(advZoneConfiguredVirtualRouterCount == (args.data.returnedPhysicalNetworks.length * 2)) { //not call addPod() until virtualRouter and vpcVirtualRouter of all physical networks get configured + stepFns.addPod({ + data: args.data + }); + } + } + else if (result.jobstatus == 2) { + alert("failed to enable VPC Virtual Router Provider. Error: " + _s(result.jobresult.errortext)); + } + } + }, + error: function(XMLHttpResponse) { + var errorMsg = parseXMLHttpResponse(XMLHttpResponse); + alert("updateNetworkServiceProvider failed. Error: " + errorMsg); + } + }); + }, 3000); + } + }); + } + else if (result.jobstatus == 2) { + alert("configureVirtualRouterElement failed. Error: " + _s(result.jobresult.errortext)); + } + } + }, + error: function(XMLHttpResponse) { + var errorMsg = parseXMLHttpResponse(XMLHttpResponse); + alert("configureVirtualRouterElement failed. Error: " + errorMsg); + } + }); + }, 3000); + } + }); + // ***** VPC Virtual Router ***** (end) ***** } else if (result.jobstatus == 2) { alert("updatePhysicalNetwork failed. Error: " + _s(result.jobresult.errortext)); From c3215d1c1f8af4fe04c296516a3a16e94c04a4b6 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Thu, 5 Jul 2012 15:51:51 -0700 Subject: [PATCH 14/16] cloudstack 3.0 UI - VPC - infrasture page - network service providers - add "VPC Virtual Router". --- ui/scripts/system.js | 536 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 458 insertions(+), 78 deletions(-) diff --git a/ui/scripts/system.js b/ui/scripts/system.js index 2cba42bbd5b..2f6fd844b55 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -1909,26 +1909,13 @@ supportedServices: { label: 'label.supported.services' } } ], - dataProvider: function(args) { - $.ajax({ - url: createURL("listNetworkServiceProviders&id=" + nspMap["virtualRouter"].id), - dataType: "json", - async: true, - success: function(json) { - var items = json.listnetworkserviceprovidersresponse.networkserviceprovider; - for(var i = 0; i < items.length; i++) { - if(items[i].name == "VirtualRouter" ) { - nspMap["virtualRouter"] = items[i]; - args.response.success({ - actionFilter: virtualRouterProviderActionFilter, - data: $.extend(nspMap["virtualRouter"], { - supportedServices: nspMap["virtualRouter"].servicelist.join(', ') - }) - }); - break; - } - } - } + dataProvider: function(args) { + refreshNspData("VirtualRouter"); + args.response.success({ + actionFilter: virtualRouterProviderActionFilter, + data: $.extend(nspMap["virtualRouter"], { + supportedServices: nspMap["virtualRouter"].servicelist.join(', ') + }) }); } }, @@ -1970,6 +1957,9 @@ $.ajax({ url: createURL("listRouters&zoneid=" + selectedZoneObj.id + "&listAll=true&page=" + args.page + "&pagesize=" + pageSize + array1.join("")), dataType: 'json', + data: { + forvpc: false + }, async: true, success: function(json) { var items = json.listroutersresponse.router; @@ -1984,6 +1974,9 @@ $.ajax({ url: createURL("listRouters&zoneid=" + selectedZoneObj.id + "&listAll=true&page=" + args.page + "&pagesize=" + pageSize + array1.join("") + "&projectid=-1"), dataType: 'json', + data: { + forvpc: false + }, async: true, success: function(json) { var items = json.listroutersresponse.router; @@ -2108,64 +2101,7 @@ poll: pollAsyncJobResult } }, - - /* - changeService: { - label: 'label.change.service.offering', - createForm: { - title: 'label.change.service.offering', - desc: '', - fields: { - serviceOfferingId: { - label: 'label.compute.offering', - select: function(args) { - $.ajax({ - url: createURL("listServiceOfferings&issystem=true&systemvmtype=domainrouter"), - dataType: "json", - async: true, - success: function(json) { - var serviceofferings = json.listserviceofferingsresponse.serviceoffering; - var items = []; - $(serviceofferings).each(function() { - if(this.id != args.context.routers[0].serviceofferingid) { - items.push({id: this.id, description: this.displaytext}); - } - }); - args.response.success({data: items}); - } - }); - } - } - } - }, - messages: { - notification: function(args) { - return 'label.change.service.offering'; - } - }, - action: function(args) { - $.ajax({ - url: createURL("changeServiceForRouter&id=" + args.context.routers[0].id + "&serviceofferingid=" + args.data.serviceOfferingId), - dataType: "json", - async: true, - success: function(json) { - var jsonObj = json.changeserviceforrouterresponse.domainrouter; - args.response.success({data: jsonObj}); - }, - error: function(XMLHttpResponse) { - var errorMsg = parseXMLHttpResponse(XMLHttpResponse); - args.response.error(errorMsg); - } - }); - }, - notification: { - poll: function(args) { - args.complete(); - } - } - }, - */ - + migrate: { label: 'label.action.migrate.router', createForm: { @@ -2381,7 +2317,441 @@ } } }, + + vpcVirtualRouter: { + id: 'vpcVirtualRouterProviders', + label: 'VPC Virtual Router', + isMaximized: true, + type: 'detailView', + fields: { + name: { label: 'label.name' }, + ipaddress: { label: 'label.ip.address' }, + state: { label: 'label.status', indicator: { 'Enabled': 'on' } } + }, + tabs: { + network: { + title: 'label.network', + fields: [ + { + name: { label: 'label.name' } + }, + { + id: { label: 'label.id' }, + state: { label: 'label.state' }, + physicalnetworkid: { label: 'label.physical.network.ID' }, + destinationphysicalnetworkid: { label: 'label.destination.physical.network.id' }, + supportedServices: { label: 'label.supported.services' } + } + ], + dataProvider: function(args) { + refreshNspData("VpcVirtualRouter"); + args.response.success({ + actionFilter: virtualRouterProviderActionFilter, + data: $.extend(nspMap["vpcVirtualRouter"], { + supportedServices: nspMap["vpcVirtualRouter"].servicelist.join(', ') + }) + }); + } + }, + instances: { + title: 'label.instances', + listView: { + label: 'label.virtual.appliances', + id: 'routers', + fields: { + name: { label: 'label.name' }, + zonename: { label: 'label.zone' }, + state: { + converter: function(str) { + // For localization + return str; + }, + label: 'label.status', + indicator: { + 'Running': 'on', + 'Stopped': 'off', + 'Error': 'off' + } + } + }, + dataProvider: function(args) { + var array1 = []; + if(args.filterBy != null) { + if(args.filterBy.search != null && args.filterBy.search.by != null && args.filterBy.search.value != null) { + switch(args.filterBy.search.by) { + case "name": + if(args.filterBy.search.value.length > 0) + array1.push("&keyword=" + args.filterBy.search.value); + break; + } + } + } + + $.ajax({ + url: createURL("listRouters&zoneid=" + selectedZoneObj.id + "&listAll=true&page=" + args.page + "&pagesize=" + pageSize + array1.join("")), + dataType: 'json', + data: { + forvpc: true + }, + async: true, + success: function(json) { + var items = json.listroutersresponse.router; + args.response.success({ + actionFilter: routerActionfilter, + data: items + }); + } + }); + + // Get project routers + $.ajax({ + url: createURL("listRouters&zoneid=" + selectedZoneObj.id + "&listAll=true&page=" + args.page + "&pagesize=" + pageSize + array1.join("") + "&projectid=-1"), + dataType: 'json', + data: { + forvpc: true + }, + async: true, + success: function(json) { + var items = json.listroutersresponse.router; + args.response.success({ + actionFilter: routerActionfilter, + data: items + }); + } + }); + }, + detailView: { + name: 'Virtual applicance details', + actions: { + start: { + label: 'label.action.start.router', + messages: { + confirm: function(args) { + return 'message.action.start.router'; + }, + notification: function(args) { + return 'label.action.start.router'; + } + }, + action: function(args) { + $.ajax({ + url: createURL('startRouter&id=' + args.context.routers[0].id), + dataType: 'json', + async: true, + success: function(json) { + var jid = json.startrouterresponse.jobid; + args.response.success({ + _custom: { + jobId: jid, + getUpdatedItem: function(json) { + return json.queryasyncjobresultresponse.jobresult.domainrouter; + }, + getActionFilter: function() { + return routerActionfilter; + } + } + }); + } + }); + }, + notification: { + poll: pollAsyncJobResult + } + }, + + stop: { + label: 'label.action.stop.router', + createForm: { + title: 'label.action.stop.router', + desc: 'message.action.stop.router', + fields: { + forced: { + label: 'force.stop', + isBoolean: true, + isChecked: false + } + } + }, + messages: { + notification: function(args) { + return 'label.action.stop.router'; + } + }, + action: function(args) { + var array1 = []; + array1.push("&forced=" + (args.data.forced == "on")); + $.ajax({ + url: createURL('stopRouter&id=' + args.context.routers[0].id + array1.join("")), + dataType: 'json', + async: true, + success: function(json) { + var jid = json.stoprouterresponse.jobid; + args.response.success({ + _custom: { + jobId: jid, + getUpdatedItem: function(json) { + return json.queryasyncjobresultresponse.jobresult.domainrouter; + }, + getActionFilter: function() { + return routerActionfilter; + } + } + }); + } + }); + }, + notification: { + poll: pollAsyncJobResult + } + }, + + 'remove': { + label: 'label.destroy.router', + messages: { + confirm: function(args) { + return 'message.confirm.destroy.router'; + }, + notification: function(args) { + return 'label.destroy.router'; + } + }, + action: function(args) { + $.ajax({ + url: createURL("destroyRouter&id=" + args.context.routers[0].id), + dataType: "json", + async: true, + success: function(json) { + var jid = json.destroyrouterresponse.jobid; + args.response.success({ + _custom: { + jobId: jid + } + }); + } + }); + }, + notification: { + poll: pollAsyncJobResult + } + }, + + migrate: { + label: 'label.action.migrate.router', + createForm: { + title: 'label.action.migrate.router', + desc: '', + fields: { + hostId: { + label: 'label.host', + validation: { required: true }, + select: function(args) { + $.ajax({ + url: createURL("listHosts&VirtualMachineId=" + args.context.routers[0].id), + //url: createURL("listHosts"), //for testing only, comment it out before checking in. + dataType: "json", + async: true, + success: function(json) { + var hostObjs = json.listhostsresponse.host; + var items = []; + $(hostObjs).each(function() { + items.push({id: this.id, description: (this.name + ": " +(this.hasEnoughCapacity? "Available" : "Full"))}); + }); + args.response.success({data: items}); + } + }); + }, + error: function(XMLHttpResponse) { + var errorMsg = parseXMLHttpResponse(XMLHttpResponse); + args.response.error(errorMsg); + } + } + } + }, + messages: { + notification: function(args) { + return 'label.action.migrate.router'; + } + }, + action: function(args) { + $.ajax({ + url: createURL("migrateSystemVm&hostid=" + args.data.hostId + "&virtualmachineid=" + args.context.routers[0].id), + dataType: "json", + async: true, + success: function(json) { + var jid = json.migratesystemvmresponse.jobid; + args.response.success({ + _custom: { + jobId: jid, + getUpdatedItem: function(json) { + //return json.queryasyncjobresultresponse.jobresult.systemvminstance; //not all properties returned in systemvminstance + $.ajax({ + url: createURL("listRouters&id=" + json.queryasyncjobresultresponse.jobresult.systemvminstance.id), + dataType: "json", + async: false, + success: function(json) { + var items = json.listroutersresponse.router; + if(items != null && items.length > 0) { + return items[0]; + } + } + }); + }, + getActionFilter: function() { + return routerActionfilter; + } + } + }); + } + }); + }, + notification: { + poll: pollAsyncJobResult + } + }, + + viewConsole: { + label: 'label.view.console', + action: { + externalLink: { + url: function(args) { + return clientConsoleUrl + '?cmd=access&vm=' + args.context.routers[0].id; + }, + title: function(args) { + return args.context.routers[0].id.substr(0,8); //title in window.open() can't have space nor longer than 8 characters. Otherwise, IE browser will have error. + }, + width: 820, + height: 640 + } + } + } + }, + tabs: { + details: { + title: 'label.details', + preFilter: function(args) { + var hiddenFields = []; + if (!args.context.routers[0].project) { + hiddenFields.push('project'); + hiddenFields.push('projectid'); + } + if(selectedZoneObj.networktype == 'Basic') { + hiddenFields.push('publicip'); //In Basic zone, guest IP is public IP. So, publicip is not returned by listRouters API. Only guestipaddress is returned by listRouters API. + } + return hiddenFields; + }, + fields: [ + { + name: { label: 'label.name' }, + project: { label: 'label.project' } + }, + { + id: { label: 'label.id' }, + projectid: { label: 'label.project.id' }, + state: { label: 'label.state' }, + publicip: { label: 'label.public.ip' }, + guestipaddress: { label: 'label.guest.ip' }, + linklocalip: { label: 'label.linklocal.ip' }, + hostname: { label: 'label.host' }, + serviceofferingname: { label: 'label.compute.offering' }, + networkdomain: { label: 'label.network.domain' }, + domain: { label: 'label.domain' }, + account: { label: 'label.account' }, + created: { label: 'label.created', converter: cloudStack.converters.toLocalDate }, + isredundantrouter: { + label: 'label.redundant.router', + converter: cloudStack.converters.toBooleanText + }, + redundantRouterState: { label: 'label.redundant.state' } + } + ], + dataProvider: function(args) { + $.ajax({ + url: createURL("listRouters&id=" + args.context.routers[0].id), + dataType: 'json', + async: true, + success: function(json) { + var jsonObj = json.listroutersresponse.router[0]; + addExtraPropertiesToRouterInstanceObject(jsonObj); + args.response.success({ + actionFilter: routerActionfilter, + data: jsonObj + }); + } + }); + } + } + } + } + } + } + }, + actions: { + enable: { + label: 'label.enable.provider', + action: function(args) { + $.ajax({ + url: createURL("updateNetworkServiceProvider&id=" + nspMap["vpcVirtualRouter"].id + "&state=Enabled"), + dataType: "json", + success: function(json) { + var jid = json.updatenetworkserviceproviderresponse.jobid; + args.response.success( + {_custom: + { + jobId: jid, + getUpdatedItem: function(json) { + $(window).trigger('cloudStack.fullRefresh'); + } + } + } + ); + } + }); + }, + messages: { + confirm: function(args) { + return 'message.confirm.enable.provider'; + }, + notification: function() { + return 'label.enable.provider'; + } + }, + notification: { poll: pollAsyncJobResult } + }, + disable: { + label: 'label.disable.provider', + action: function(args) { + $.ajax({ + url: createURL("updateNetworkServiceProvider&id=" + nspMap["vpcVirtualRouter"].id + "&state=Disabled"), + dataType: "json", + success: function(json) { + var jid = json.updatenetworkserviceproviderresponse.jobid; + args.response.success( + {_custom: + { + jobId: jid, + getUpdatedItem: function(json) { + $(window).trigger('cloudStack.fullRefresh'); + } + } + } + ); + } + }); + }, + messages: { + confirm: function(args) { + return 'message.confirm.disable.provider'; + }, + notification: function() { + return 'label.disable.provider'; + } + }, + notification: { poll: pollAsyncJobResult } + } + } + }, + // NetScaler provider detail view netscaler: { type: 'detailView', @@ -9174,6 +9544,9 @@ case "VirtualRouter": nspMap["virtualRouter"] = items[i]; break; + case "VpcVirtualRouter": + nspMap["vpcVirtualRouter"] = items[i]; + break; case "Netscaler": nspMap["netscaler"] = items[i]; break; @@ -9215,6 +9588,13 @@ ); } else if(selectedZoneObj.networktype == "Advanced"){ + nspHardcodingArray.push( + { + id: 'vpcVirtualRouter', + name: 'VPC Virtual Router', + state: nspMap.vpcVirtualRouter ? nspMap.vpcVirtualRouter.state : 'Disabled' + } + ); nspHardcodingArray.push( { id: 'f5', From f8aa415a978042312adeb0f71ea54a3ded9223b8 Mon Sep 17 00:00:00 2001 From: frank Date: Thu, 5 Jul 2012 16:02:51 -0700 Subject: [PATCH 15/16] CloudStack CS-15455 There are no iptable rules configured to open awsapi port (7080) for external world. resolved fixed reviewed-by:edison --- python/lib/cloudutils/serviceConfig.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/lib/cloudutils/serviceConfig.py b/python/lib/cloudutils/serviceConfig.py index 539e26ae732..4ab08a21ba7 100755 --- a/python/lib/cloudutils/serviceConfig.py +++ b/python/lib/cloudutils/serviceConfig.py @@ -699,7 +699,7 @@ class firewallConfigServer(firewallConfigBase): if self.syscfg.env.svrMode == "myCloud": self.ports = "443 8080 8250 8443 9090".split() else: - self.ports = "8080 8250 9090".split() + self.ports = "8080 7080 8250 9090".split() class ubuntuFirewallConfigServer(firewallConfigServer): def allowPort(self, port): From 96a3b496c863ad244ea300289cc618095df910df Mon Sep 17 00:00:00 2001 From: frank Date: Thu, 5 Jul 2012 16:18:24 -0700 Subject: [PATCH 16/16] CloudStack CS-15448 java.io.FileNotFoundException: /usr/share/cloud/management/webapps7080/awsapi/WEB-INF/classes/xes.keystore (Permission denied) resolved fixed reviewed-by: edison --- cloud.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud.spec b/cloud.spec index 9824b9ac776..6b551b7144f 100644 --- a/cloud.spec +++ b/cloud.spec @@ -633,7 +633,7 @@ fi %config(noreplace) %attr(0640,root,%{name}) %{_sysconfdir}/%{name}/usage/db.properties %files aws-api -%defattr(0644,cloud,cloud,0755) +%defattr(0666,cloud,cloud,0755) %{_datadir}/cloud/bridge/conf/* %{_datadir}/cloud/bridge/lib/* %{_datadir}/cloud/bridge/webapps/*