diff --git a/agent/src/com/cloud/agent/resource/computing/LibvirtComputingResource.java b/agent/src/com/cloud/agent/resource/computing/LibvirtComputingResource.java index 7d7987412a7..26cb3dcc719 100755 --- a/agent/src/com/cloud/agent/resource/computing/LibvirtComputingResource.java +++ b/agent/src/com/cloud/agent/resource/computing/LibvirtComputingResource.java @@ -235,7 +235,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements private String _createTmplPath; private String _heartBeatPath; private String _securityGroupPath; - private String _networkUsagePath; + private String _routerProxyPath; private String _host; private String _dcId; private String _pod; @@ -539,11 +539,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements "Unable to find the security_group.py"); } - _networkUsagePath = Script.findScript("scripts/network/domr/", - "networkUsage.sh"); - if (_networkUsagePath == null) { + _routerProxyPath = Script.findScript("scripts/network/domr/", + "routerProxy.sh"); + if (_routerProxyPath == null) { throw new ConfigurationException( - "Unable to find the networkUsage.sh"); + "Unable to find the routerProxy.sh"); } String value = (String) params.get("developer"); @@ -2168,7 +2168,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements protected String networkUsage(final String privateIpAddress, final String option, final String vif) { - Script getUsage = new Script(_networkUsagePath, s_logger); + Script getUsage = new Script(_routerProxyPath, s_logger); + getUsage.add("netusage.sh"); + getUsage.add(privateIpAddress); if (option.equals("get")) { getUsage.add("-g"); } else if (option.equals("create")) { @@ -2181,7 +2183,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements getUsage.add("-d", vif); } - getUsage.add("-i", privateIpAddress); + final OutputInterpreter.OneLineParser usageParser = new OutputInterpreter.OneLineParser(); String result = getUsage.execute(usageParser); if (result != null) { diff --git a/api/src/com/cloud/agent/api/PlugNicAnswer.java b/api/src/com/cloud/agent/api/PlugNicAnswer.java new file mode 100644 index 00000000000..3a76240ef22 --- /dev/null +++ b/api/src/com/cloud/agent/api/PlugNicAnswer.java @@ -0,0 +1,24 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.agent.api; + +/** + * @author Alena Prokharchyk + */ +public class PlugNicAnswer extends Answer{ + public PlugNicAnswer() {} + + public PlugNicAnswer(PlugNicCommand cmd, boolean success, String result) { + super(cmd, success, result); + } +} diff --git a/api/src/com/cloud/agent/api/PlugNicCommand.java b/api/src/com/cloud/agent/api/PlugNicCommand.java new file mode 100644 index 00000000000..4222e4c4369 --- /dev/null +++ b/api/src/com/cloud/agent/api/PlugNicCommand.java @@ -0,0 +1,46 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.agent.api; + +import com.cloud.agent.api.to.NicTO; +import com.cloud.agent.api.to.VirtualMachineTO; + +/** + * @author Alena Prokharchyk + */ +public class PlugNicCommand extends Command { + + VirtualMachineTO vm; + NicTO nic; + + public VirtualMachineTO getVirtualMachine() { + return vm; + } + + public NicTO getNic() { + return nic; + } + + @Override + public boolean executeInSequence() { + return true; + } + + protected PlugNicCommand() { + } + + public PlugNicCommand(VirtualMachineTO vm, NicTO nic) { + this.vm = vm; + this.nic = nic; + } +} diff --git a/api/src/com/cloud/agent/api/SetSourceNatAnswer.java b/api/src/com/cloud/agent/api/SetSourceNatAnswer.java new file mode 100644 index 00000000000..089f1f72f56 --- /dev/null +++ b/api/src/com/cloud/agent/api/SetSourceNatAnswer.java @@ -0,0 +1,24 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.agent.api; + +/** + * @author Alena Prokharchyk + */ +public class SetSourceNatAnswer extends Answer{ + public SetSourceNatAnswer() {} + + public SetSourceNatAnswer(PlugNicCommand cmd, boolean success, String result) { + super(cmd, success, result); + } +} diff --git a/api/src/com/cloud/agent/api/SetupGuestNetworkAnswer.java b/api/src/com/cloud/agent/api/SetupGuestNetworkAnswer.java new file mode 100644 index 00000000000..e20a9c5ccc8 --- /dev/null +++ b/api/src/com/cloud/agent/api/SetupGuestNetworkAnswer.java @@ -0,0 +1,24 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.agent.api; + +/** + * @author Alena Prokharchyk + */ +public class SetupGuestNetworkAnswer extends Answer{ + public SetupGuestNetworkAnswer() {} + + public SetupGuestNetworkAnswer(SetupGuestNetworkCommand cmd, boolean success, String result) { + super(cmd, success, result); + } +} diff --git a/api/src/com/cloud/agent/api/SetupGuestNetworkCommand.java b/api/src/com/cloud/agent/api/SetupGuestNetworkCommand.java new file mode 100644 index 00000000000..1245e6eb4f8 --- /dev/null +++ b/api/src/com/cloud/agent/api/SetupGuestNetworkCommand.java @@ -0,0 +1,67 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.agent.api; + +import com.cloud.agent.api.routing.NetworkElementCommand; +import com.cloud.agent.api.to.NicTO; + +/** + * @author Alena Prokharchyk + */ +public class SetupGuestNetworkCommand extends NetworkElementCommand{ + String dhcpRange; + String networkDomain; + String defaultDns1 = null; + String defaultDns2 = null; + boolean isRedundant = false; + Integer priority; + boolean add = true; + NicTO nic; + + public NicTO getNic() { + return nic; + } + + public String getDefaultDns1() { + return defaultDns1; + } + + public String getDefaultDns2() { + return defaultDns2; + } + + public String getNetworkDomain() { + return networkDomain; + } + + @Override + public boolean executeInSequence() { + return true; + } + + protected SetupGuestNetworkCommand() { + } + + + public SetupGuestNetworkCommand(String dhcpRange, String networkDomain, boolean isRedundant, Integer priority, + String defaultDns1, String defaultDns2, boolean add, NicTO nic) { + this.dhcpRange = dhcpRange; + this.networkDomain = networkDomain; + this.defaultDns1 = defaultDns1; + this.defaultDns2 = defaultDns2; + this.isRedundant = isRedundant; + this.priority = priority; + this.add = add; + this.nic = nic; + } +} diff --git a/api/src/com/cloud/agent/api/UnPlugNicAnswer.java b/api/src/com/cloud/agent/api/UnPlugNicAnswer.java new file mode 100644 index 00000000000..cd87c722697 --- /dev/null +++ b/api/src/com/cloud/agent/api/UnPlugNicAnswer.java @@ -0,0 +1,24 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.agent.api; + +/** + * @author Alena Prokharchyk + */ +public class UnPlugNicAnswer extends Answer{ + public UnPlugNicAnswer() {} + + public UnPlugNicAnswer(UnPlugNicCommand cmd, boolean success, String result) { + super(cmd, success, result); + } +} diff --git a/api/src/com/cloud/agent/api/UnPlugNicCommand.java b/api/src/com/cloud/agent/api/UnPlugNicCommand.java new file mode 100644 index 00000000000..26d9441092f --- /dev/null +++ b/api/src/com/cloud/agent/api/UnPlugNicCommand.java @@ -0,0 +1,45 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.agent.api; + +import com.cloud.agent.api.to.NicTO; +import com.cloud.agent.api.to.VirtualMachineTO; + +/** + * @author Alena Prokharchyk + */ +public class UnPlugNicCommand extends Command{ + VirtualMachineTO vm; + NicTO nic; + + public VirtualMachineTO getVirtualMachine() { + return vm; + } + + public NicTO getNic() { + return nic; + } + + @Override + public boolean executeInSequence() { + return true; + } + + protected UnPlugNicCommand() { + } + + public UnPlugNicCommand(VirtualMachineTO vm, NicTO nic) { + this.vm = vm; + this.nic = nic; + } +} diff --git a/api/src/com/cloud/agent/api/routing/IpAssocVpcCommand.java b/api/src/com/cloud/agent/api/routing/IpAssocVpcCommand.java new file mode 100644 index 00000000000..7ab57b4f5c3 --- /dev/null +++ b/api/src/com/cloud/agent/api/routing/IpAssocVpcCommand.java @@ -0,0 +1,28 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.agent.api.routing; + +import com.cloud.agent.api.to.IpAddressTO; + +/** + * @author Alena Prokharchyk + */ +public class IpAssocVpcCommand extends IpAssocCommand{ + protected IpAssocVpcCommand() { + super(); + } + + public IpAssocVpcCommand(IpAddressTO[] ips) { + super(ips); + } +} diff --git a/api/src/com/cloud/agent/api/routing/NetworkElementCommand.java b/api/src/com/cloud/agent/api/routing/NetworkElementCommand.java index b2d882baee6..db86bb48eb9 100644 --- a/api/src/com/cloud/agent/api/routing/NetworkElementCommand.java +++ b/api/src/com/cloud/agent/api/routing/NetworkElementCommand.java @@ -27,6 +27,7 @@ public abstract class NetworkElementCommand extends Command { public static final String ROUTER_IP = "router.ip"; public static final String ROUTER_GUEST_IP = "router.guest.ip"; public static final String ZONE_NETWORK_TYPE = "zone.network.type"; + public static final String GUEST_BRIDGE = "guest.bridge"; protected NetworkElementCommand() { super(); diff --git a/api/src/com/cloud/agent/api/routing/SetFirewallRulesCommand.java b/api/src/com/cloud/agent/api/routing/SetFirewallRulesCommand.java index 210acc35e65..f5011aa860f 100644 --- a/api/src/com/cloud/agent/api/routing/SetFirewallRulesCommand.java +++ b/api/src/com/cloud/agent/api/routing/SetFirewallRulesCommand.java @@ -17,8 +17,6 @@ import java.util.List; import java.util.Set; import com.cloud.agent.api.to.FirewallRuleTO; -import com.cloud.agent.api.to.LoadBalancerTO; -import com.cloud.utils.StringUtils; /** * diff --git a/api/src/com/cloud/agent/api/routing/SetSourceNatCommand.java b/api/src/com/cloud/agent/api/routing/SetSourceNatCommand.java new file mode 100644 index 00000000000..59d48565229 --- /dev/null +++ b/api/src/com/cloud/agent/api/routing/SetSourceNatCommand.java @@ -0,0 +1,41 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.agent.api.routing; + +import com.cloud.agent.api.to.IpAddressTO; + +/** + * @author Alena Prokharchyk + */ +public class SetSourceNatCommand extends NetworkElementCommand{ + IpAddressTO ipAddress; + boolean add; + + protected SetSourceNatCommand() { + } + + public SetSourceNatCommand(IpAddressTO ip, boolean add) { + this.ipAddress = ip; + this.add = add; + } + + @Override + public boolean executeInSequence() { + return false; + } + + public IpAddressTO getIpAddress() { + return ipAddress; + } + +} diff --git a/api/src/com/cloud/agent/api/to/IpAddressTO.java b/api/src/com/cloud/agent/api/to/IpAddressTO.java index 40770bff1ed..b5f2c30cea9 100644 --- a/api/src/com/cloud/agent/api/to/IpAddressTO.java +++ b/api/src/com/cloud/agent/api/to/IpAddressTO.java @@ -32,7 +32,8 @@ public class IpAddressTO { private TrafficType trafficType; private String networkName; - public IpAddressTO(long accountId, String ipAddress, boolean add, boolean firstIP, boolean sourceNat, String vlanId, String vlanGateway, String vlanNetmask, String vifMacAddress, String guestIp, Integer networkRate, boolean isOneToOneNat) { + public IpAddressTO(long accountId, String ipAddress, boolean add, boolean firstIP, boolean sourceNat, String vlanId, + String vlanGateway, String vlanNetmask, String vifMacAddress, String guestIp, Integer networkRate, boolean isOneToOneNat) { this.accountId = accountId; this.publicIp = ipAddress; this.add = add; diff --git a/api/src/com/cloud/agent/api/to/NetworkTO.java b/api/src/com/cloud/agent/api/to/NetworkTO.java index 788e367a2dd..6a7ec1394a9 100644 --- a/api/src/com/cloud/agent/api/to/NetworkTO.java +++ b/api/src/com/cloud/agent/api/to/NetworkTO.java @@ -173,5 +173,4 @@ public class NetworkTO { public boolean isSecurityGroupEnabled() { return this.isSecurityGroupEnabled; } - } diff --git a/api/src/com/cloud/api/ApiConstants.java b/api/src/com/cloud/api/ApiConstants.java index 57fee53e17f..94e8bbc71b1 100755 --- a/api/src/com/cloud/api/ApiConstants.java +++ b/api/src/com/cloud/api/ApiConstants.java @@ -356,6 +356,9 @@ public class ApiConstants { public static final String RESOURCE_IDS = "resourceids"; public static final String RESOURCE_ID = "resourceid"; public static final String CUSTOMER = "customer"; + public static final String VPC_OFF_ID = "vpcofferingid"; + public static final String NETWORK = "network"; + public static final String VPC_ID = "vpcid"; public enum HostDetails { all, capacity, events, stats, min; diff --git a/api/src/com/cloud/api/BaseCmd.java b/api/src/com/cloud/api/BaseCmd.java index 4110d19733c..5e926213534 100755 --- a/api/src/com/cloud/api/BaseCmd.java +++ b/api/src/com/cloud/api/BaseCmd.java @@ -40,6 +40,7 @@ import com.cloud.network.firewall.FirewallService; import com.cloud.network.lb.LoadBalancingRulesService; import com.cloud.network.rules.RulesService; import com.cloud.network.security.SecurityGroupService; +import com.cloud.network.vpc.VpcService; import com.cloud.network.vpn.RemoteAccessVpnService; import com.cloud.projects.Project; import com.cloud.projects.ProjectService; @@ -125,6 +126,7 @@ public abstract class BaseCmd { public static IdentityService _identityService; public static StorageNetworkService _storageNetworkService; public static TaggedResourceService _taggedResourceService; + public static VpcService _vpcService; static void setComponents(ResponseGenerator generator) { ComponentLocator locator = ComponentLocator.getLocator(ManagementService.Name); @@ -153,6 +155,7 @@ public abstract class BaseCmd { _identityService = locator.getManager(IdentityService.class); _storageNetworkService = locator.getManager(StorageNetworkService.class); _taggedResourceService = locator.getManager(TaggedResourceService.class); + _vpcService = locator.getManager(VpcService.class); } public abstract void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException; diff --git a/api/src/com/cloud/api/ResponseGenerator.java b/api/src/com/cloud/api/ResponseGenerator.java index 009b3c8fe3b..309c52c5986 100755 --- a/api/src/com/cloud/api/ResponseGenerator.java +++ b/api/src/com/cloud/api/ResponseGenerator.java @@ -71,6 +71,8 @@ import com.cloud.api.response.UserVmResponse; import com.cloud.api.response.VirtualRouterProviderResponse; import com.cloud.api.response.VlanIpRangeResponse; import com.cloud.api.response.VolumeResponse; +import com.cloud.api.response.VpcOfferingResponse; +import com.cloud.api.response.VpcResponse; import com.cloud.api.response.VpnUsersResponse; import com.cloud.api.response.ZoneResponse; import com.cloud.async.AsyncJob; @@ -104,6 +106,8 @@ import com.cloud.network.rules.StickinessPolicy; import com.cloud.network.security.SecurityGroup; import com.cloud.network.security.SecurityGroupRules; import com.cloud.network.security.SecurityRule; +import com.cloud.network.vpc.Vpc; +import com.cloud.network.vpc.VpcOffering; import com.cloud.offering.DiskOffering; import com.cloud.offering.NetworkOffering; import com.cloud.offering.ServiceOffering; @@ -286,4 +290,15 @@ public interface ResponseGenerator { ResourceTagResponse createResourceTagResponse(ResourceTag resourceTag); + /** + * @param offering + * @return + */ + VpcOfferingResponse createVpcOfferingResponse(VpcOffering offering); + + /** + * @param vpc + * @return + */ + VpcResponse createVpcResponse(Vpc vpc); } diff --git a/api/src/com/cloud/api/commands/AssociateIPAddrCmd.java b/api/src/com/cloud/api/commands/AssociateIPAddrCmd.java index 63d94f93b05..1d9f4698414 100644 --- a/api/src/com/cloud/api/commands/AssociateIPAddrCmd.java +++ b/api/src/com/cloud/api/commands/AssociateIPAddrCmd.java @@ -37,6 +37,7 @@ import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.IpAddress; import com.cloud.network.Network; +import com.cloud.network.vpc.Vpc; import com.cloud.user.Account; import com.cloud.user.UserContext; @@ -49,25 +50,35 @@ public class AssociateIPAddrCmd extends BaseAsyncCreateCmd { //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// - @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="the account to associate with this IP address") + @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, + description="the account to associate with this IP address") private String accountName; @IdentityMapper(entityTableName="domain") - @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="the ID of the domain to associate with this IP address") + @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, + description="the ID of the domain to associate with this IP address") private Long domainId; @IdentityMapper(entityTableName="data_center") - @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, description="the ID of the availability zone you want to acquire an public IP address from") + @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, + description="the ID of the availability zone you want to acquire an public IP address from") private Long zoneId; @IdentityMapper(entityTableName="networks") - @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.LONG, description="The network this ip address should be associated to.") + @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.LONG, + description="The network this ip address should be associated to.") private Long networkId; @IdentityMapper(entityTableName="projects") - @Parameter(name=ApiConstants.PROJECT_ID, type=CommandType.LONG, description="Deploy vm for the project") + @Parameter(name=ApiConstants.PROJECT_ID, type=CommandType.LONG, + description="Deploy vm for the project") private Long projectId; + @IdentityMapper(entityTableName="vpc") + @Parameter(name=ApiConstants.VPC_ID, type=CommandType.LONG, description="the VPC you want the ip address to " + + "be associated with") + private Long vpcId; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -90,26 +101,50 @@ public class AssociateIPAddrCmd extends BaseAsyncCreateCmd { return UserContext.current().getCaller().getDomainId(); } - private Long getZoneId() { + private long getZoneId() { + if (zoneId != null) { return zoneId; + } else if (vpcId != null) { + Vpc vpc = _entityMgr.findById(Vpc.class, vpcId); + if (vpc != null) { + return vpc.getZoneId(); + } + } else if (networkId != null) { + Network ntwk = _entityMgr.findById(Network.class, networkId); + if (ntwk != null) { + return ntwk.getDataCenterId(); + } + } + + throw new InvalidParameterValueException("Unable to figure out zone to assign ip to"); + } + + public Long getVpcId() { + return vpcId; } public Long getNetworkId() { + if (vpcId != null) { + return null; + } + if (networkId != null) { return networkId; } Long zoneId = getZoneId(); if (zoneId == null) { - throw new InvalidParameterValueException("Either networkId or zoneId has to be specified"); + return null; } DataCenter zone = _configService.getZone(zoneId); if (zone.getNetworkType() == NetworkType.Advanced) { - List networks = _networkService.getIsolatedNetworksOwnedByAccountInZone(getZoneId(), _accountService.getAccount(getEntityOwnerId())); + List networks = _networkService.getIsolatedNetworksOwnedByAccountInZone(getZoneId(), + _accountService.getAccount(getEntityOwnerId())); if (networks.size() == 0) { String domain = _domainService.getDomain(getDomainId()).getName(); - throw new InvalidParameterValueException("Account name=" + getAccountName() + " domain=" + domain + " doesn't have virtual networks in zone=" + zone.getName()); + throw new InvalidParameterValueException("Account name=" + getAccountName() + " domain=" + domain + + " doesn't have virtual networks in zone=" + zone.getName()); } if (networks.size() < 1) { @@ -122,7 +157,8 @@ public class AssociateIPAddrCmd extends BaseAsyncCreateCmd { } else { Network defaultGuestNetwork = _networkService.getExclusiveGuestNetwork(zoneId); if (defaultGuestNetwork == null) { - throw new InvalidParameterValueException("Unable to find a default Guest network for account " + getAccountName() + " in domain id=" + getDomainId()); + throw new InvalidParameterValueException("Unable to find a default Guest network for account " + + getAccountName() + " in domain id=" + getDomainId()); } else { return defaultGuestNetwork.getId(); } @@ -168,7 +204,7 @@ public class AssociateIPAddrCmd extends BaseAsyncCreateCmd { @Override public void create() throws ResourceAllocationException{ try { - IpAddress ip = _networkService.allocateIP(getNetworkId(), _accountService.getAccount(getEntityOwnerId())); + IpAddress ip = _networkService.allocateIP(_accountService.getAccount(getEntityOwnerId()), false, getZoneId()); if (ip != null) { this.setEntityId(ip.getId()); } else { @@ -185,9 +221,14 @@ public class AssociateIPAddrCmd extends BaseAsyncCreateCmd { } @Override - public void execute() throws ResourceUnavailableException, ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException { + public void execute() throws ResourceUnavailableException, ResourceAllocationException, + ConcurrentOperationException, InsufficientCapacityException { UserContext.current().setEventDetails("Ip Id: " + getEntityId()); - IpAddress result = _networkService.associateIP(getEntityId()); + + IpAddress result = null; + + result = _networkService.associateIP(getEntityId(), getNetworkId(), getVpcId()); + if (result != null) { IPAddressResponse ipResponse = _responseGenerator.createIPAddressResponse(result); ipResponse.setResponseName(getCommandName()); diff --git a/api/src/com/cloud/api/commands/CreateFirewallRuleCmd.java b/api/src/com/cloud/api/commands/CreateFirewallRuleCmd.java index 24093d6be48..14ba4f3ab28 100644 --- a/api/src/com/cloud/api/commands/CreateFirewallRuleCmd.java +++ b/api/src/com/cloud/api/commands/CreateFirewallRuleCmd.java @@ -72,6 +72,11 @@ public class CreateFirewallRuleCmd extends BaseAsyncCreateCmd implements Firewal @Parameter(name = ApiConstants.TYPE, type = CommandType.STRING, description = "type of firewallrule: system/user") private String type; + @IdentityMapper(entityTableName="networks") + @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.LONG, + description="The network of the vm the Firewall rule will be created for") + private Long networkId; + // /////////////////////////////////////////////////// // ///////////////// Accessors /////////////////////// // /////////////////////////////////////////////////// @@ -187,7 +192,19 @@ public class CreateFirewallRuleCmd extends BaseAsyncCreateCmd implements Firewal @Override public long getNetworkId() { - throw new UnsupportedOperationException("Not yet implemented"); + IpAddress ip = _entityMgr.findById(IpAddress.class, getIpAddressId()); + Long ntwkId = null; + + if (ip.getAssociatedWithNetworkId() != null) { + ntwkId = ip.getAssociatedWithNetworkId(); + } else { + ntwkId = networkId; + } + if (ntwkId == null) { + throw new InvalidParameterValueException("Unable to create firewall rule for the ipAddress id=" + ipAddressId + + " as ip is not associated with any network and no networkId is passed in"); + } + return ntwkId; } @Override diff --git a/api/src/com/cloud/api/commands/CreateLoadBalancerRuleCmd.java b/api/src/com/cloud/api/commands/CreateLoadBalancerRuleCmd.java index 0c052d3422a..b4aed0b68c3 100644 --- a/api/src/com/cloud/api/commands/CreateLoadBalancerRuleCmd.java +++ b/api/src/com/cloud/api/commands/CreateLoadBalancerRuleCmd.java @@ -167,9 +167,12 @@ public class CreateLoadBalancerRuleCmd extends BaseAsyncCreateCmd /*implements } } else { IpAddress ipAddr = _networkService.getIp(publicIpId); - return ipAddr.getAssociatedWithNetworkId(); + if (ipAddr.getAssociatedWithNetworkId() != null) { + return ipAddr.getAssociatedWithNetworkId(); + } else { + throw new InvalidParameterValueException("Ip address id=" + publicIpId + " is not associated with any network"); + } } - } public Integer getPublicPort() { diff --git a/api/src/com/cloud/api/commands/CreateNetworkCmd.java b/api/src/com/cloud/api/commands/CreateNetworkCmd.java index 7058165396c..a9e1291a782 100644 --- a/api/src/com/cloud/api/commands/CreateNetworkCmd.java +++ b/api/src/com/cloud/api/commands/CreateNetworkCmd.java @@ -58,16 +58,19 @@ public class CreateNetworkCmd extends BaseCmd { @Parameter(name=ApiConstants.PHYSICAL_NETWORK_ID, type=CommandType.LONG, description="the Physical Network ID the network belongs to") private Long physicalNetworkId; - @Parameter(name=ApiConstants.GATEWAY, type=CommandType.STRING, description="the gateway of the network") + @Parameter(name=ApiConstants.GATEWAY, type=CommandType.STRING, description="the gateway of the network. Required " + + "for Shared networks and Isolated networks when it belongs to VPC") private String gateway; - @Parameter(name=ApiConstants.NETMASK, type=CommandType.STRING, description="the netmask of the network") + @Parameter(name=ApiConstants.NETMASK, type=CommandType.STRING, description="the netmask of the network. Required " + + "for Shared networks and Isolated networks when it belongs to VPC") private String netmask; @Parameter(name=ApiConstants.START_IP, type=CommandType.STRING, description="the beginning IP address in the network IP range") private String startIp; - @Parameter(name=ApiConstants.END_IP, type=CommandType.STRING, description="the ending IP address in the network IP range. If not specified, will be defaulted to startIP") + @Parameter(name=ApiConstants.END_IP, type=CommandType.STRING, description="the ending IP address in the network IP" + + " range. If not specified, will be defaulted to startIP") private String endIp; @Parameter(name=ApiConstants.VLAN, type=CommandType.STRING, description="the ID or VID of the network") @@ -76,7 +79,9 @@ public class CreateNetworkCmd extends BaseCmd { @Parameter(name=ApiConstants.NETWORK_DOMAIN, type=CommandType.STRING, description="network domain") private String networkDomain; - @Parameter(name=ApiConstants.ACL_TYPE, type=CommandType.STRING, description="Access control type; supported values are account and domain. In 3.0 all shared networks should have aclType=Domain, and all Isolated networks - Account. Account means that only the account owner can use the network, domain - all accouns in the domain can use the network") + @Parameter(name=ApiConstants.ACL_TYPE, type=CommandType.STRING, description="Access control type; supported values" + + " are account and domain. In 3.0 all shared networks should have aclType=Domain, and all Isolated networks" + + " - Account. Account means that only the account owner can use the network, domain - all accouns in the domain can use the network") private String aclType; @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="account who will own the network") @@ -90,9 +95,13 @@ public class CreateNetworkCmd extends BaseCmd { @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="domain ID of the account owning a network") private Long domainId; - @Parameter(name=ApiConstants.SUBDOMAIN_ACCESS, type=CommandType.BOOLEAN, description="Defines whether to allow subdomains to use networks dedicated to their parent domain(s). Should be used with aclType=Domain, defaulted to allow.subdomain.network.access global config if not specified") + @Parameter(name=ApiConstants.SUBDOMAIN_ACCESS, type=CommandType.BOOLEAN, description="Defines whether to allow" + + " subdomains to use networks dedicated to their parent domain(s). Should be used with aclType=Domain, defaulted to allow.subdomain.network.access global config if not specified") private Boolean subdomainAccess; + @IdentityMapper(entityTableName="vpc") + @Parameter(name=ApiConstants.VPC_ID, type=CommandType.LONG, description="the VPC network belongs to") + private Long vpcId; ///////////////////////////////////////////////////// @@ -154,7 +163,11 @@ public class CreateNetworkCmd extends BaseCmd { return subdomainAccess; } - public Long getZoneId() { + public Long getVpcId() { + return vpcId; + } + + public Long getZoneId() { Long physicalNetworkId = getPhysicalNetworkId(); if (physicalNetworkId == null && zoneId == null) { @@ -204,7 +217,7 @@ public class CreateNetworkCmd extends BaseCmd { @Override public void execute() throws InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException{ - Network result = _networkService.createNetwork(this); + Network result = _networkService.createGuestNetwork(this); if (result != null) { NetworkResponse response = _responseGenerator.createNetworkResponse(result); response.setResponseName(getCommandName()); diff --git a/api/src/com/cloud/api/commands/CreatePhysicalNetworkCmd.java b/api/src/com/cloud/api/commands/CreatePhysicalNetworkCmd.java index 220b4155de7..d2d43ce6a49 100644 --- a/api/src/com/cloud/api/commands/CreatePhysicalNetworkCmd.java +++ b/api/src/com/cloud/api/commands/CreatePhysicalNetworkCmd.java @@ -55,13 +55,15 @@ public class CreatePhysicalNetworkCmd extends BaseAsyncCreateCmd { @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="domain ID of the account owning a physical network") private Long domainId; - @Parameter(name=ApiConstants.BROADCAST_DOMAIN_RANGE, type=CommandType.STRING, description="the broadcast domain range for the physical network[Pod or Zone]. In Acton release it can be Zone only in Advance zone, and Pod in Basic") + @Parameter(name=ApiConstants.BROADCAST_DOMAIN_RANGE, type=CommandType.STRING, description="the broadcast domain " + + "range for the physical network[Pod or Zone]. In Acton release it can be Zone only in Advance zone, and Pod in Basic") private String broadcastDomainRange; @Parameter(name=ApiConstants.TAGS, type=CommandType.LIST, collectionType=CommandType.STRING, description="Tag the physical network") private List tags; - @Parameter(name=ApiConstants.ISOLATION_METHODS, type=CommandType.LIST, collectionType=CommandType.STRING, description="the isolation method for the physical network[VLAN/L3/GRE]") + @Parameter(name=ApiConstants.ISOLATION_METHODS, type=CommandType.LIST, collectionType=CommandType.STRING, + description="the isolation method for the physical network[VLAN/L3/GRE]") private List isolationMethods; @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, required=true, description="the name of the physical network") diff --git a/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java b/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java index 8acd1e18764..8bf3af82c2f 100644 --- a/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java +++ b/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java @@ -47,27 +47,40 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P // /////////////////////////////////////////////////// @IdentityMapper(entityTableName = "user_ip_address") - @Parameter(name = ApiConstants.IP_ADDRESS_ID, type = CommandType.LONG, required = true, description = "the IP address id of the port forwarding rule") + @Parameter(name = ApiConstants.IP_ADDRESS_ID, type = CommandType.LONG, required = true, + description = "the IP address id of the port forwarding rule") private Long ipAddressId; - @Parameter(name = ApiConstants.PRIVATE_START_PORT, type = CommandType.INTEGER, required = true, description = "the starting port of port forwarding rule's private port range") + @Parameter(name = ApiConstants.PRIVATE_START_PORT, type = CommandType.INTEGER, required = true, + description = "the starting port of port forwarding rule's private port range") private Integer privateStartPort; - @Parameter(name = ApiConstants.PROTOCOL, type = CommandType.STRING, required = true, description = "the protocol for the port fowarding rule. Valid values are TCP or UDP.") + @Parameter(name = ApiConstants.PROTOCOL, type = CommandType.STRING, required = true, + description = "the protocol for the port fowarding rule. Valid values are TCP or UDP.") private String protocol; - @Parameter(name = ApiConstants.PUBLIC_START_PORT, type = CommandType.INTEGER, required = true, description = "the starting port of port forwarding rule's public port range") + @Parameter(name = ApiConstants.PUBLIC_START_PORT, type = CommandType.INTEGER, required = true, + description = "the starting port of port forwarding rule's public port range") private Integer publicStartPort; @IdentityMapper(entityTableName = "vm_instance") - @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID, type = CommandType.LONG, required = true, description = "the ID of the virtual machine for the port forwarding rule") + @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID, type = CommandType.LONG, required = true, + description = "the ID of the virtual machine for the port forwarding rule") private Long virtualMachineId; - @Parameter(name = ApiConstants.CIDR_LIST, type = CommandType.LIST, collectionType = CommandType.STRING, description = "the cidr list to forward traffic from") + @Parameter(name = ApiConstants.CIDR_LIST, type = CommandType.LIST, collectionType = CommandType.STRING, + description = "the cidr list to forward traffic from") private List cidrlist; - @Parameter(name = ApiConstants.OPEN_FIREWALL, type = CommandType.BOOLEAN, description = "if true, firewall rule for source/end pubic port is automatically created; if false - firewall rule has to be created explicitely. Has value true by default") + @Parameter(name = ApiConstants.OPEN_FIREWALL, type = CommandType.BOOLEAN, + description = "if true, firewall rule for source/end pubic port is automatically created; " + + "if false - firewall rule has to be created explicitely. Has value true by default") private Boolean openFirewall; + + @IdentityMapper(entityTableName="networks") + @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.LONG, + description="The network of the vm the Port Forwarding rule will be created for") + private Long networkId; // /////////////////////////////////////////////////// // ///////////////// Accessors /////////////////////// @@ -93,7 +106,8 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P public List getSourceCidrList() { if (cidrlist != null) { - throw new InvalidParameterValueException("Parameter cidrList is deprecated; if you need to open firewall rule for the specific cidr, please refer to createFirewallRule command"); + throw new InvalidParameterValueException("Parameter cidrList is deprecated; if you need to open firewall " + + "rule for the specific cidr, please refer to createFirewallRule command"); } return null; } @@ -189,7 +203,19 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P @Override public long getNetworkId() { - throw new UnsupportedOperationException("Not yet implemented"); + IpAddress ip = _entityMgr.findById(IpAddress.class, getIpAddressId()); + Long ntwkId = null; + + if (ip.getAssociatedWithNetworkId() != null) { + ntwkId = ip.getAssociatedWithNetworkId(); + } else { + ntwkId = networkId; + } + if (ntwkId == null) { + throw new InvalidParameterValueException("Unable to create port forwarding rule for the ipAddress id=" + ipAddressId + + " as ip is not associated with any network and no networkId is passed in"); + } + return ntwkId; } @Override @@ -201,7 +227,7 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P } return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are -// tracked + // tracked } @Override @@ -232,7 +258,6 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P @Override public void create() { - // cidr list parameter is deprecated if (cidrlist != null) { throw new InvalidParameterValueException("Parameter cidrList is deprecated; if you need to open firewall rule for the specific cidr, please refer to createFirewallRule command"); diff --git a/api/src/com/cloud/api/commands/CreatePrivateNetworkCmd.java b/api/src/com/cloud/api/commands/CreatePrivateNetworkCmd.java new file mode 100644 index 00000000000..276c1fb8e24 --- /dev/null +++ b/api/src/com/cloud/api/commands/CreatePrivateNetworkCmd.java @@ -0,0 +1,195 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.api.commands; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseAsyncCreateCmd; +import com.cloud.api.BaseCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.NetworkResponse; +import com.cloud.event.EventTypes; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.network.Network; +import com.cloud.user.UserContext; + +@Implementation(description="Creates a private network", responseObject=NetworkResponse.class) +public class CreatePrivateNetworkCmd extends BaseAsyncCreateCmd { + public static final Logger s_logger = Logger.getLogger(CreatePrivateNetworkCmd.class.getName()); + + private static final String s_name = "createnetworkresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, required=true, description="the name of the network") + private String name; + + @Parameter(name=ApiConstants.DISPLAY_TEXT, type=CommandType.STRING, required=true, description="the display text of the network") + private String displayText; + + @IdentityMapper(entityTableName="physical_network") + @Parameter(name=ApiConstants.PHYSICAL_NETWORK_ID, type=CommandType.LONG, required=true, description="the Physical Network ID the network belongs to") + private Long physicalNetworkId; + + @Parameter(name=ApiConstants.GATEWAY, type=CommandType.STRING, required=true, description="the gateway of the network") + private String gateway; + + @Parameter(name=ApiConstants.NETMASK, type=CommandType.STRING, required=true, description="the netmask of the network") + private String netmask; + + @Parameter(name=ApiConstants.START_IP, type=CommandType.STRING, required=true, description="the beginning IP address in the network IP range") + private String startIp; + + @Parameter(name=ApiConstants.END_IP, type=CommandType.STRING, description="the ending IP address in the network IP" + + " range. If not specified, will be defaulted to startIP") + private String endIp; + + @Parameter(name=ApiConstants.VLAN, type=CommandType.STRING, required=true, description="the ID or VID of the network") + private String vlan; + + @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="account who will own the network") + private String accountName; + + @IdentityMapper(entityTableName="projects") + @Parameter(name=ApiConstants.PROJECT_ID, type=CommandType.LONG, description="an optional project for the ssh key") + private Long projectId; + + @IdentityMapper(entityTableName="domain") + @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="domain ID of the account owning a network") + private Long domainId; + + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public String getGateway() { + return gateway; + } + + public String getVlan() { + return vlan; + } + + public String getAccountName() { + return accountName; + } + + public Long getDomainId() { + return domainId; + } + + public String getNetmask() { + return netmask; + } + + public String getStartIp() { + return startIp; + } + + public String getNetworkName() { + return name; + } + + public String getDisplayText() { + return displayText; + } + + public Long getProjectId() { + return projectId; + } + + public long getPhysicalNetworkId() { + return physicalNetworkId; + } + + public String getEndIp() { + return endIp; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + @Override + public String getCommandName() { + return s_name; + } + + + @Override + public void create() throws ResourceAllocationException { + Network result = null; + try { + result = _networkService.createPrivateNetwork(getNetworkName(), getDisplayText(), getPhysicalNetworkId(), getVlan(), + getStartIp(), getEndIp(), getGateway(), getNetmask(), getEntityOwnerId()); + } catch (InsufficientCapacityException ex){ + s_logger.info(ex); + s_logger.trace(ex); + throw new ServerApiException(BaseCmd.INSUFFICIENT_CAPACITY_ERROR, ex.getMessage()); + } catch (ConcurrentOperationException ex) { + s_logger.warn("Exception: ", ex); + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, ex.getMessage()); + } + + if (result != null) { + this.setEntityId(result.getId()); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create a Private network"); + } + } + + @Override + public void execute() throws InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException{ + Network result = _networkService.getNetwork(getEntityId()); + if (result != null) { + NetworkResponse response = _responseGenerator.createNetworkResponse(result); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create private network"); + } + } + + @Override + public long getEntityOwnerId() { + Long accountId = finalyzeAccountId(accountName, domainId, projectId, true); + if (accountId == null) { + return UserContext.current().getCaller().getId(); + } + return accountId; + } + + @Override + public String getEventType() { + return EventTypes.EVENT_NETWORK_CREATE; + } + + @Override + public String getEventDescription() { + return "creating private network"; + + } + + @Override + public String getEntityTable() { + return "networks"; + } +} diff --git a/api/src/com/cloud/api/commands/CreateRemoteAccessVpnCmd.java b/api/src/com/cloud/api/commands/CreateRemoteAccessVpnCmd.java index b6e13878f46..b783adf781a 100644 --- a/api/src/com/cloud/api/commands/CreateRemoteAccessVpnCmd.java +++ b/api/src/com/cloud/api/commands/CreateRemoteAccessVpnCmd.java @@ -58,6 +58,11 @@ public class CreateRemoteAccessVpnCmd extends BaseAsyncCreateCmd { @Parameter(name = ApiConstants.OPEN_FIREWALL, type = CommandType.BOOLEAN, description = "if true, firewall rule for source/end pubic port is automatically created; if false - firewall rule has to be created explicitely. Has value true by default") private Boolean openFirewall; + @IdentityMapper(entityTableName="networks") + @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.LONG, + description="The network of the ip the VPN be created for") + private Long networkId; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -125,10 +130,26 @@ public class CreateRemoteAccessVpnCmd extends BaseAsyncCreateCmd { return EventTypes.EVENT_REMOTE_ACCESS_VPN_CREATE; } + public long getNetworkId() { + IpAddress ip = _entityMgr.findById(IpAddress.class, getPublicIpId()); + Long ntwkId = null; + + if (ip.getAssociatedWithNetworkId() != null) { + ntwkId = ip.getAssociatedWithNetworkId(); + } else { + ntwkId = networkId; + } + if (ntwkId == null) { + throw new InvalidParameterValueException("Unable to create remote access vpn for the ipAddress id=" + getPublicIpId() + + " as ip is not associated with any network and no networkId is passed in"); + } + return ntwkId; + } + @Override public void create() { try { - RemoteAccessVpn vpn = _ravService.createRemoteAccessVpn(publicIpId, ipRange, getOpenFirewall()); + RemoteAccessVpn vpn = _ravService.createRemoteAccessVpn(publicIpId, ipRange, getOpenFirewall(), getNetworkId()); if (vpn != null) { this.setEntityId(vpn.getServerAddressId()); } else { diff --git a/api/src/com/cloud/api/commands/CreateVPCCmd.java b/api/src/com/cloud/api/commands/CreateVPCCmd.java new file mode 100644 index 00000000000..11c8ad6b2d9 --- /dev/null +++ b/api/src/com/cloud/api/commands/CreateVPCCmd.java @@ -0,0 +1,181 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.api.commands; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseAsyncCreateCmd; +import com.cloud.api.BaseCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.VpcResponse; +import com.cloud.event.EventTypes; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.vpc.Vpc; +import com.cloud.user.UserContext; + +/** + * @author Alena Prokharchyk + */ +public class CreateVPCCmd extends BaseAsyncCreateCmd{ + public static final Logger s_logger = Logger.getLogger(CreateVPCCmd.class.getName()); + private static final String s_name = "createvpcresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="the account associated with the VPC. " + + "Must be used with the domainId parameter.") + private String accountName; + + @IdentityMapper(entityTableName="domain") + @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="the domain ID associated with the VPC. " + + "If used with the account parameter returns the VPC associated with the account for the specified domain.") + private Long domainId; + + @IdentityMapper(entityTableName="data_center") + @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, required=true, description="the ID of the availability zone") + private Long zoneId; + + @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, required=true, description="the name of the VPC") + private String vpcName; + + @Parameter(name=ApiConstants.DISPLAY_TEXT, type=CommandType.STRING, required=true, description="the display text of " + + "the VPC") + private String displayText; + + @Parameter(name=ApiConstants.CIDR, type=CommandType.STRING, required=true, description="the cidr of the VPC. All VPC " + + "guest networks' cidrs should be within this CIDR") + private String cidr; + + + @IdentityMapper(entityTableName="vpc_offerings") + @Parameter(name=ApiConstants.VPC_OFF_ID, type=CommandType.LONG, required=true, description="the ID of the VPC offering") + private Long vpcOffering; + + @Parameter(name=ApiConstants.NETWORK_DOMAIN, type=CommandType.STRING, description="network domain") + private String networkDomain; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public String getAccountName() { + return accountName; + } + + public Long getDomainId() { + return domainId; + } + + public Long getZoneId() { + return zoneId; + } + + public String getVpcName() { + return vpcName; + } + + public String getCidr() { + return cidr; + } + + public String getDisplayText() { + return displayText; + } + + public Long getVpcOffering() { + return vpcOffering; + } + + public String getNetworkDomain() { + return networkDomain; + } + + @Override + public void create() throws ResourceAllocationException { + Vpc vpc = _vpcService.createVpc(getZoneId(), getVpcOffering(), getEntityOwnerId(), getVpcName(), getDisplayText(), + getCidr(), getNetworkDomain()); + if (vpc != null) { + this.setEntityId(vpc.getId()); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create a VPC"); + } + } + + @Override + public void execute() { + Vpc vpc = null; + try { + if (_vpcService.startVpc(this.getEntityId())) { + vpc = _vpcService.getVpc(getEntityId()); + } + } catch (ResourceUnavailableException ex) { + s_logger.warn("Exception: ", ex); + throw new ServerApiException(BaseCmd.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage()); + } catch (ConcurrentOperationException ex) { + s_logger.warn("Exception: ", ex); + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, ex.getMessage()); + } catch (InsufficientCapacityException ex) { + s_logger.info(ex); + s_logger.trace(ex); + throw new ServerApiException(BaseCmd.INSUFFICIENT_CAPACITY_ERROR, ex.getMessage()); + } + + if (vpc != null) { + VpcResponse response = _responseGenerator.createVpcResponse(vpc); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create VPC"); + } + } + + @Override + public String getEntityTable() { + return "vpc"; + } + + + @Override + public String getEventType() { + return EventTypes.EVENT_VPC_CREATE; + } + + + @Override + public String getEventDescription() { + return "creating VPC. Id: " + getEntityId(); + } + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + Long accountId = finalyzeAccountId(accountName, domainId, null, true); + if (accountId == null) { + return UserContext.current().getCaller().getId(); + } + + return accountId; + } +} diff --git a/api/src/com/cloud/api/commands/CreateVPCOfferingCmd.java b/api/src/com/cloud/api/commands/CreateVPCOfferingCmd.java new file mode 100644 index 00000000000..b8411810f6d --- /dev/null +++ b/api/src/com/cloud/api/commands/CreateVPCOfferingCmd.java @@ -0,0 +1,116 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.api.commands; + +import java.util.List; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseAsyncCreateCmd; +import com.cloud.api.BaseCmd; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.VpcOfferingResponse; +import com.cloud.event.EventTypes; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.network.vpc.VpcOffering; +import com.cloud.user.Account; + +/** + * @author Alena Prokharchyk + */ +public class CreateVPCOfferingCmd extends BaseAsyncCreateCmd{ + public static final Logger s_logger = Logger.getLogger(CreateVPCOfferingCmd.class.getName()); + private static final String _name = "createvpcofferingresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, required=true, description="the name of the vpc offering") + private String vpcOfferingName; + + @Parameter(name=ApiConstants.DISPLAY_TEXT, type=CommandType.STRING, required=true, description="the display text of " + + "the vpc offering") + private String displayText; + + @Parameter(name=ApiConstants.SUPPORTED_SERVICES, type=CommandType.LIST, required=true, collectionType=CommandType.STRING, + description="services supported by the vpc offering") + private List supportedServices; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public String getVpcOfferingName() { + return vpcOfferingName; + } + + public String getDisplayText() { + return displayText; + } + + public List getSupportedServices() { + return supportedServices; + } + + + @Override + public void create() throws ResourceAllocationException { + VpcOffering vpcOff = _vpcService.createVpcOffering(getVpcOfferingName(), getDisplayText(), getSupportedServices()); + if (vpcOff != null) { + this.setEntityId(vpcOff.getId()); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create a VPC offering"); + } + } + + @Override + public void execute() { + VpcOffering vpc = _vpcService.getVpcOffering(this.getEntityId()); + if (vpc != null) { + VpcOfferingResponse response = _responseGenerator.createVpcOfferingResponse(vpc); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create VPC offering"); + } + } + + @Override + public String getEntityTable() { + return "vpc_offerings"; + } + + @Override + public String getEventType() { + return EventTypes.EVENT_VPC_OFFERING_CREATE; + } + + @Override + public String getEventDescription() { + return "creating VPC offering. Id: " + getEntityId(); + } + + @Override + public String getCommandName() { + return _name; + } + + @Override + public long getEntityOwnerId() { + return Account.ACCOUNT_ID_SYSTEM; + } + +} diff --git a/api/src/com/cloud/api/commands/CreateVirtualRouterElementCmd.java b/api/src/com/cloud/api/commands/CreateVirtualRouterElementCmd.java index 48c6c4e19a3..ef5f8e8e4c7 100644 --- a/api/src/com/cloud/api/commands/CreateVirtualRouterElementCmd.java +++ b/api/src/com/cloud/api/commands/CreateVirtualRouterElementCmd.java @@ -26,6 +26,7 @@ import com.cloud.api.response.VirtualRouterProviderResponse; import com.cloud.event.EventTypes; import com.cloud.exception.ResourceAllocationException; import com.cloud.network.VirtualRouterProvider; +import com.cloud.network.VirtualRouterProvider.VirtualRouterProviderType; import com.cloud.network.element.VirtualRouterElementService; import com.cloud.user.Account; import com.cloud.user.UserContext; @@ -92,7 +93,7 @@ public class CreateVirtualRouterElementCmd extends BaseAsyncCreateCmd { @Override public void create() throws ResourceAllocationException { - VirtualRouterProvider result = _service.addElement(getNspId()); + VirtualRouterProvider result = _service.addElement(getNspId(), VirtualRouterProviderType.VirtualRouter); if (result != null) { setEntityId(result.getId()); } else { diff --git a/api/src/com/cloud/api/commands/DeleteVPCCmd.java b/api/src/com/cloud/api/commands/DeleteVPCCmd.java new file mode 100644 index 00000000000..5a80f29dce1 --- /dev/null +++ b/api/src/com/cloud/api/commands/DeleteVPCCmd.java @@ -0,0 +1,104 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.api.commands; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseAsyncCmd; +import com.cloud.api.BaseCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.SuccessResponse; +import com.cloud.event.EventTypes; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.vpc.Vpc; +import com.cloud.user.Account; + +/** + * @author Alena Prokharchyk + */ +public class DeleteVPCCmd extends BaseAsyncCmd{ + public static final Logger s_logger = Logger.getLogger(DeleteVPCCmd.class.getName()); + private static final String s_name = "deletevpcresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @IdentityMapper(entityTableName="vpc") + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="the ID of the VPC") + private Long id; + + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public String getEventType() { + return EventTypes.EVENT_VPC_DELETE; + } + + @Override + public String getEventDescription() { + return "Deleting VPC id=" + getId(); + } + + @Override + public void execute() { + try { + boolean result = _vpcService.deleteVpc(getId()); + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to delete VPC"); + } + }catch (ResourceUnavailableException ex) { + s_logger.warn("Exception: ", ex); + throw new ServerApiException(BaseCmd.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage()); + } catch (ConcurrentOperationException ex) { + s_logger.warn("Exception: ", ex); + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, ex.getMessage()); + } + } + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + Vpc vpc = _entityMgr.findById(Vpc.class, getId()); + if (vpc != null) { + return vpc.getAccountId(); + } + + return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked + } + +} diff --git a/api/src/com/cloud/api/commands/DeleteVPCOfferingCmd.java b/api/src/com/cloud/api/commands/DeleteVPCOfferingCmd.java new file mode 100644 index 00000000000..b32b17ba3ab --- /dev/null +++ b/api/src/com/cloud/api/commands/DeleteVPCOfferingCmd.java @@ -0,0 +1,89 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.api.commands; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseAsyncCmd; +import com.cloud.api.BaseCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.SuccessResponse; +import com.cloud.event.EventTypes; +import com.cloud.user.Account; + +/** + * @author Alena Prokharchyk + */ +public class DeleteVPCOfferingCmd extends BaseAsyncCmd{ + public static final Logger s_logger = Logger.getLogger(DeleteVPCOfferingCmd.class.getName()); + private static final String s_name = "deletevpcofferingresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @IdentityMapper(entityTableName="vpc_offerings") + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="the ID of the VPC offering") + private Long id; + + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + return Account.ACCOUNT_ID_SYSTEM; + } + + @Override + public void execute(){ + boolean result = _vpcService.deleteVpcOffering(getId()); + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to delete VPC offering"); + } + } + + @Override + public String getEventType(){ + return EventTypes.EVENT_VPC_OFFERING_DELETE; + } + + + @Override + public String getEventDescription() { + return "Deleting VPC offering id=" + getId(); + } + + +} diff --git a/api/src/com/cloud/api/commands/DisassociateIPAddrCmd.java b/api/src/com/cloud/api/commands/DisassociateIPAddrCmd.java index afdc7d7ff47..ea19ea319c6 100644 --- a/api/src/com/cloud/api/commands/DisassociateIPAddrCmd.java +++ b/api/src/com/cloud/api/commands/DisassociateIPAddrCmd.java @@ -41,7 +41,8 @@ public class DisassociateIPAddrCmd extends BaseAsyncCmd { ///////////////////////////////////////////////////// @IdentityMapper(entityTableName="user_ip_address") - @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="the id of the public ip address to disassociate") + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="the id of the public ip address" + + " to disassociate") private Long id; // unexposed parameter needed for events logging @@ -67,8 +68,8 @@ public class DisassociateIPAddrCmd extends BaseAsyncCmd { @Override public void execute() throws InsufficientAddressCapacityException{ - UserContext.current().setEventDetails("Ip Id: "+getIpAddressId()); - boolean result = _networkService.disassociateIpAddress(id); + UserContext.current().setEventDetails("Ip Id: " + getIpAddressId()); + boolean result = _networkService.releaseIpAddress(getIpAddressId()); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); this.setResponseObject(response); diff --git a/api/src/com/cloud/api/commands/EnableStaticNatCmd.java b/api/src/com/cloud/api/commands/EnableStaticNatCmd.java index 9e649ec9d08..8c0c9ac5a65 100644 --- a/api/src/com/cloud/api/commands/EnableStaticNatCmd.java +++ b/api/src/com/cloud/api/commands/EnableStaticNatCmd.java @@ -21,8 +21,10 @@ import com.cloud.api.Implementation; import com.cloud.api.Parameter; import com.cloud.api.ServerApiException; import com.cloud.api.response.SuccessResponse; +import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.NetworkRuleConflictException; import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.IpAddress; import com.cloud.user.Account; import com.cloud.uservm.UserVm; @@ -37,13 +39,20 @@ public class EnableStaticNatCmd extends BaseCmd{ ///////////////////////////////////////////////////// @IdentityMapper(entityTableName="user_ip_address") - @Parameter(name=ApiConstants.IP_ADDRESS_ID, type=CommandType.LONG, required=true, description="the public IP address id for which static nat feature is being enabled") + @Parameter(name=ApiConstants.IP_ADDRESS_ID, type=CommandType.LONG, required=true, description="the public IP " + + "address id for which static nat feature is being enabled") private Long ipAddressId; @IdentityMapper(entityTableName="vm_instance") - @Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.LONG, required=true, description="the ID of the virtual machine for enabling static nat feature") + @Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.LONG, required=true, description="the ID of " + + "the virtual machine for enabling static nat feature") private Long virtualMachineId; + @IdentityMapper(entityTableName="networks") + @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.LONG, + description="The network of the vm the static nat will be enabled for.") + private Long networkId; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -56,6 +65,22 @@ public class EnableStaticNatCmd extends BaseCmd{ return virtualMachineId; } + public long getNetworkId() { + IpAddress ip = _entityMgr.findById(IpAddress.class, getIpAddressId()); + Long ntwkId = null; + + if (ip.getAssociatedWithNetworkId() != null) { + ntwkId = ip.getAssociatedWithNetworkId(); + } else { + ntwkId = networkId; + } + if (ntwkId == null) { + throw new InvalidParameterValueException("Unable to enable static nat for the ipAddress id=" + ipAddressId + + " as ip is not associated with any network and no networkId is passed in"); + } + return ntwkId; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// @@ -78,7 +103,7 @@ public class EnableStaticNatCmd extends BaseCmd{ @Override public void execute() throws ResourceUnavailableException{ try { - boolean result = _rulesService.enableStaticNat(ipAddressId, virtualMachineId, false); + boolean result = _rulesService.enableStaticNat(ipAddressId, virtualMachineId, getNetworkId(), false); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); this.setResponseObject(response); diff --git a/api/src/com/cloud/api/commands/ListNetworksCmd.java b/api/src/com/cloud/api/commands/ListNetworksCmd.java index e7bea4d2d2f..182bf815a02 100644 --- a/api/src/com/cloud/api/commands/ListNetworksCmd.java +++ b/api/src/com/cloud/api/commands/ListNetworksCmd.java @@ -62,11 +62,15 @@ public class ListNetworksCmd extends BaseListProjectAndAccountResourcesCmd { @Parameter(name=ApiConstants.SUPPORTED_SERVICES, type=CommandType.LIST, collectionType=CommandType.STRING, description="list network offerings supporting certain services") private List supportedServices; - @Parameter(name=ApiConstants.RESTART_REQUIRED, type=CommandType.BOOLEAN, description="list network offerings by restartRequired option") + @Parameter(name=ApiConstants.RESTART_REQUIRED, type=CommandType.BOOLEAN, description="list networks by restartRequired") private Boolean restartRequired; @Parameter(name=ApiConstants.SPECIFY_IP_RANGES, type=CommandType.BOOLEAN, description="true if need to list only networks which support specifying ip ranges") private Boolean specifyIpRanges; + + @IdentityMapper(entityTableName="vpc") + @Parameter(name=ApiConstants.VPC_ID, type=CommandType.LONG, description="List networks by VPC") + private Long vpcId; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -112,7 +116,11 @@ public class ListNetworksCmd extends BaseListProjectAndAccountResourcesCmd { return specifyIpRanges; } - ///////////////////////////////////////////////////// + public Long getVpcId() { + return vpcId; + } + + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// @Override diff --git a/api/src/com/cloud/api/commands/ListPublicIpAddressesCmd.java b/api/src/com/cloud/api/commands/ListPublicIpAddressesCmd.java index d853d65f5fd..60add46ff46 100644 --- a/api/src/com/cloud/api/commands/ListPublicIpAddressesCmd.java +++ b/api/src/com/cloud/api/commands/ListPublicIpAddressesCmd.java @@ -74,6 +74,10 @@ public class ListPublicIpAddressesCmd extends BaseListProjectAndAccountResources @Parameter(name=ApiConstants.IS_STATIC_NAT, type=CommandType.BOOLEAN, description="list only static nat ip addresses") private Boolean isStaticNat; + + @IdentityMapper(entityTableName="vpc") + @Parameter(name=ApiConstants.VPC_ID, type=CommandType.LONG, description="List ips belonging to the VPC") + private Long vpcId; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -118,6 +122,10 @@ public class ListPublicIpAddressesCmd extends BaseListProjectAndAccountResources return isStaticNat; } + public Long getVpcId() { + return vpcId; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/com/cloud/api/commands/ListRoutersCmd.java b/api/src/com/cloud/api/commands/ListRoutersCmd.java index 2e713e66988..0fb4dcc65c9 100644 --- a/api/src/com/cloud/api/commands/ListRoutersCmd.java +++ b/api/src/com/cloud/api/commands/ListRoutersCmd.java @@ -18,7 +18,6 @@ import java.util.List; import org.apache.log4j.Logger; import com.cloud.api.ApiConstants; -import com.cloud.api.BaseCmd.CommandType; import com.cloud.api.BaseListProjectAndAccountResourcesCmd; import com.cloud.api.IdentityMapper; import com.cloud.api.Implementation; @@ -63,6 +62,10 @@ public class ListRoutersCmd extends BaseListProjectAndAccountResourcesCmd { @IdentityMapper(entityTableName="networks") @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.LONG, description="list by network id") private Long networkId; + + @IdentityMapper(entityTableName="vpc") + @Parameter(name=ApiConstants.VPC_ID, type=CommandType.LONG, description="List networks by VPC") + private Long vpcId; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -95,6 +98,10 @@ public class ListRoutersCmd extends BaseListProjectAndAccountResourcesCmd { public Long getNetworkId() { return networkId; } + + public Long getVpcId() { + return vpcId; + } ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// diff --git a/api/src/com/cloud/api/commands/ListVPCOfferingsCmd.java b/api/src/com/cloud/api/commands/ListVPCOfferingsCmd.java new file mode 100644 index 00000000000..adb96354105 --- /dev/null +++ b/api/src/com/cloud/api/commands/ListVPCOfferingsCmd.java @@ -0,0 +1,113 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.api.commands; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseListCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Parameter; +import com.cloud.api.response.ListResponse; +import com.cloud.api.response.VpcOfferingResponse; +import com.cloud.network.vpc.VpcOffering; + +/** + * @author Alena Prokharchyk + */ +public class ListVPCOfferingsCmd extends BaseListCmd{ + public static final Logger s_logger = Logger.getLogger(ListVPCOfferingsCmd.class.getName()); + private static final String _name = "listvpcofferingsresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + @IdentityMapper(entityTableName="vpc_offerings") + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, description="list VPC offerings by id") + private Long id; + + @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, description="list VPC offerings by name") + private String vpcOffName; + + @Parameter(name=ApiConstants.DISPLAY_TEXT, type=CommandType.STRING, description="list VPC offerings by display text") + private String displayText; + + @Parameter(name=ApiConstants.IS_DEFAULT, type=CommandType.BOOLEAN, description="true if need to list only default " + + "VPC offerings. Default value is false") + private Boolean isDefault; + + @Parameter(name=ApiConstants.SUPPORTED_SERVICES, type=CommandType.LIST, collectionType=CommandType.STRING, + description="list VPC offerings supporting certain services") + private List supportedServices; + + @Parameter(name=ApiConstants.STATE, type=CommandType.STRING, description="list VPC offerings by state") + private String state; + + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + public Long getId() { + return id; + } + + public String getVpcOffName() { + return vpcOffName; + } + + public String getDisplayText() { + return displayText; + } + + public Boolean getIsDefault() { + return isDefault; + } + + public List getSupportedServices() { + return supportedServices; + } + + public String getState() { + return state; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public void execute(){ + List offerings = _vpcService.listVpcOfferings(getId(), getVpcOffName(), getDisplayText(), + getSupportedServices(), isDefault, this.getKeyword(), getState(), this.getStartIndex(), this.getPageSizeVal()); + ListResponse response = new ListResponse(); + List offeringResponses = new ArrayList(); + for (VpcOffering offering : offerings) { + VpcOfferingResponse offeringResponse = _responseGenerator.createVpcOfferingResponse(offering); + offeringResponses.add(offeringResponse); + } + + response.setResponses(offeringResponses); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } + + + @Override + public String getCommandName() { + return _name; + } + +} diff --git a/api/src/com/cloud/api/commands/ListVPCsCmd.java b/api/src/com/cloud/api/commands/ListVPCsCmd.java new file mode 100644 index 00000000000..5d1a090725d --- /dev/null +++ b/api/src/com/cloud/api/commands/ListVPCsCmd.java @@ -0,0 +1,155 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.api.commands; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseListAccountResourcesCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Parameter; +import com.cloud.api.response.ListResponse; +import com.cloud.api.response.VpcResponse; +import com.cloud.network.vpc.Vpc; + +/** + * @author Alena Prokharchyk + */ +public class ListVPCsCmd extends BaseListAccountResourcesCmd{ + public static final Logger s_logger = Logger.getLogger(ListVPCsCmd.class.getName()); + private static final String s_name = "listvpcsresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + @IdentityMapper(entityTableName="vpc") + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, description="list VPC by id") + private Long id; + + @IdentityMapper(entityTableName="data_center") + @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, description="list by zone") + private Long zoneId; + + @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, description="list by name of the VPC") + private String vpcName; + + @Parameter(name=ApiConstants.DISPLAY_TEXT, type=CommandType.STRING, description="List by display text of " + + "the VPC") + private String displayText; + + @Parameter(name=ApiConstants.CIDR, type=CommandType.STRING, description="list by cidr of the VPC. All VPC " + + "guest networks' cidrs should be within this CIDR") + private String cidr; + + @IdentityMapper(entityTableName="vpc_offerings") + @Parameter(name=ApiConstants.VPC_OFF_ID, type=CommandType.LONG, description="list by ID of the VPC offering") + private Long VpcOffId; + + @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="list by account associated with the VPC. " + + "Must be used with the domainId parameter.") + private String accountName; + + @IdentityMapper(entityTableName="domain") + @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="list by domain ID associated with the VPC. " + + "If used with the account parameter returns the VPC associated with the account for the specified domain.") + private Long domainId; + + @Parameter(name=ApiConstants.SUPPORTED_SERVICES, type=CommandType.LIST, collectionType=CommandType.STRING, + description="list VPC supporting certain services") + private List supportedServices; + + @Parameter(name=ApiConstants.STATE, type=CommandType.STRING, description="list VPCs by state") + private String state; + + @Parameter(name=ApiConstants.RESTART_REQUIRED, type=CommandType.BOOLEAN, description="list VPCs by restartRequired option") + private Boolean restartRequired; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public String getAccountName() { + return accountName; + } + + public Long getDomainId() { + return domainId; + } + + public Long getZoneId() { + return zoneId; + } + + public String getVpcName() { + return vpcName; + } + + public String getCidr() { + return cidr; + } + + public String getDisplayText() { + return displayText; + } + + public Long getVpcOffId() { + return VpcOffId; + } + + public Long getId() { + return id; + } + + public List getSupportedServices() { + return supportedServices; + } + + public String getState() { + return state; + } + + public Boolean getRestartRequired() { + return restartRequired; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public void execute() { + List vpcs = _vpcService.listVpcs(getId(), getVpcName(), getDisplayText(), + getSupportedServices(), getCidr(), getVpcOffId(), getState(), getAccountName(), getDomainId(), + this.getKeyword(), this.getStartIndex(), this.getPageSizeVal(), getZoneId(), this.isRecursive(), + this.listAll(), getRestartRequired()); + ListResponse response = new ListResponse(); + List offeringResponses = new ArrayList(); + for (Vpc vpc : vpcs) { + VpcResponse offeringResponse = _responseGenerator.createVpcResponse(vpc); + offeringResponses.add(offeringResponse); + } + + response.setResponses(offeringResponses); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } + + @Override + public String getCommandName() { + return s_name; + } + +} diff --git a/api/src/com/cloud/api/commands/RestartVPCCmd.java b/api/src/com/cloud/api/commands/RestartVPCCmd.java new file mode 100644 index 00000000000..a2ce626659b --- /dev/null +++ b/api/src/com/cloud/api/commands/RestartVPCCmd.java @@ -0,0 +1,95 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +package com.cloud.api.commands; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseAsyncCmd; +import com.cloud.api.BaseCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.SuccessResponse; +import com.cloud.event.EventTypes; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.vpc.Vpc; +import com.cloud.user.Account; + +/** + * @author Alena Prokharchyk + */ +public class RestartVPCCmd extends BaseAsyncCmd{ + public static final Logger s_logger = Logger.getLogger(RestartVPCCmd.class.getName()); + private static final String _name = "restartvpcresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @IdentityMapper(entityTableName="vpc") + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, description="the id of the VPC") + private Long id; + + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + @Override + public String getCommandName() { + return _name; + } + + @Override + public long getEntityOwnerId() { + Vpc vpc = _entityMgr.findById(Vpc.class, getId()); + if (vpc != null) { + return vpc.getAccountId(); + } + + return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked + } + + @Override + public void execute(){ + try { + boolean result = _vpcService.restartVpc(getId()); + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to restart VPC"); + } + } catch (ResourceUnavailableException ex) { + s_logger.warn("Exception: ", ex); + throw new ServerApiException(BaseCmd.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage()); + } catch (ConcurrentOperationException ex) { + s_logger.warn("Exception: ", ex); + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, ex.getMessage()); + } catch (InsufficientCapacityException ex) { + s_logger.info(ex); + s_logger.trace(ex); + throw new ServerApiException(BaseCmd.INSUFFICIENT_CAPACITY_ERROR, ex.getMessage()); + } + } + + @Override + public String getEventType() { + return EventTypes.EVENT_VPC_RESTART; + } + + @Override + public String getEventDescription() { + return "restarting VPC id=" + getId(); + } +} diff --git a/api/src/com/cloud/api/commands/UpdateNetworkOfferingCmd.java b/api/src/com/cloud/api/commands/UpdateNetworkOfferingCmd.java index 27ba31b2565..319f58f946e 100755 --- a/api/src/com/cloud/api/commands/UpdateNetworkOfferingCmd.java +++ b/api/src/com/cloud/api/commands/UpdateNetworkOfferingCmd.java @@ -43,7 +43,8 @@ public class UpdateNetworkOfferingCmd extends BaseCmd { @Parameter(name=ApiConstants.DISPLAY_TEXT, type=CommandType.STRING, description="the display text of the network offering") private String displayText; - @Parameter(name=ApiConstants.AVAILABILITY, type=CommandType.STRING, description="the availability of network offering. Default value is Required for Guest Virtual network offering; Optional for Guest Direct network offering") + @Parameter(name=ApiConstants.AVAILABILITY, type=CommandType.STRING, description="the availability of network offering." + + " Default value is Required for Guest Virtual network offering; Optional for Guest Direct network offering") private String availability; @Parameter(name=ApiConstants.SORT_KEY, type=CommandType.INTEGER, description="sort key of the network offering, integer") diff --git a/api/src/com/cloud/api/commands/UpdateVPCCmd.java b/api/src/com/cloud/api/commands/UpdateVPCCmd.java new file mode 100644 index 00000000000..c4478625ee8 --- /dev/null +++ b/api/src/com/cloud/api/commands/UpdateVPCCmd.java @@ -0,0 +1,106 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.api.commands; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseAsyncCmd; +import com.cloud.api.BaseCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.VpcResponse; +import com.cloud.event.EventTypes; +import com.cloud.network.vpc.Vpc; +import com.cloud.user.Account; + +/** + * @author Alena Prokharchyk + */ +public class UpdateVPCCmd extends BaseAsyncCmd{ + public static final Logger s_logger = Logger.getLogger(UpdateVPCCmd.class.getName()); + private static final String _name = "updatevpcresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @IdentityMapper(entityTableName="vpc") + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, description="the id of the VPC") + private Long id; + + @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, description="the name of the VPC") + private String vpcName; + + @Parameter(name=ApiConstants.DISPLAY_TEXT, type=CommandType.STRING, description="the display text of the VPC") + private String displayText; + + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public String getVpcName() { + return vpcName; + } + + public String getDisplayText() { + return displayText; + } + + public Long getId() { + return id; + } + + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + @Override + public String getCommandName() { + return _name; + } + + @Override + public long getEntityOwnerId() { + Vpc vpc = _entityMgr.findById(Vpc.class, getId()); + if (vpc != null) { + return vpc.getAccountId(); + } + + return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked + } + + @Override + public void execute(){ + Vpc result = _vpcService.updateVpc(getId(), getVpcName(), getDisplayText()); + if (result != null) { + VpcResponse response = _responseGenerator.createVpcResponse(result); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to update VPC"); + } + } + + @Override + public String getEventType() { + return EventTypes.EVENT_VPC_UPDATE; + } + + @Override + public String getEventDescription() { + return "updating VPC id=" + getId(); + } +} diff --git a/api/src/com/cloud/api/commands/UpdateVPCOfferingCmd.java b/api/src/com/cloud/api/commands/UpdateVPCOfferingCmd.java new file mode 100644 index 00000000000..38a519b52f2 --- /dev/null +++ b/api/src/com/cloud/api/commands/UpdateVPCOfferingCmd.java @@ -0,0 +1,108 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.api.commands; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseAsyncCmd; +import com.cloud.api.BaseCmd; +import com.cloud.api.IdentityMapper; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.VpcOfferingResponse; +import com.cloud.event.EventTypes; +import com.cloud.network.vpc.VpcOffering; +import com.cloud.user.Account; + +/** + * @author Alena Prokharchyk + */ +public class UpdateVPCOfferingCmd extends BaseAsyncCmd{ + public static final Logger s_logger = Logger.getLogger(UpdateVPCOfferingCmd.class.getName()); + private static final String _name = "updatevpcofferingresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @IdentityMapper(entityTableName="vpc_offerings") + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, description="the id of the VPC offering") + private Long id; + + @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, description="the name of the VPC offering") + private String vpcOffName; + + @Parameter(name=ApiConstants.DISPLAY_TEXT, type=CommandType.STRING, description="the display text of the VPC offering") + private String displayText; + + @Parameter(name=ApiConstants.STATE, type=CommandType.STRING, description="update state for the VPC offering; " + + "supported states - Enabled/Disabled") + private String state; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public String getVpcOfferingName() { + return vpcOffName; + } + + public String getDisplayText() { + return displayText; + } + + public Long getId() { + return id; + } + + public String getState() { + return state; + } + + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + @Override + public String getCommandName() { + return _name; + } + + @Override + public long getEntityOwnerId() { + return Account.ACCOUNT_ID_SYSTEM; + } + + @Override + public void execute(){ + VpcOffering result = _vpcService.updateVpcOffering(getId(), getVpcOfferingName(), getDisplayText(), getState()); + if (result != null) { + VpcOfferingResponse response = _responseGenerator.createVpcOfferingResponse(result); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to update VPC offering"); + } + } + + @Override + public String getEventType() { + return EventTypes.EVENT_VPC_OFFERING_UPDATE; + } + + @Override + public String getEventDescription() { + return "Updating VPC offering id=" + getId(); + } +} diff --git a/api/src/com/cloud/api/response/DomainRouterResponse.java b/api/src/com/cloud/api/response/DomainRouterResponse.java index 10c50f5eeec..bd7e7d07d6f 100644 --- a/api/src/com/cloud/api/response/DomainRouterResponse.java +++ b/api/src/com/cloud/api/response/DomainRouterResponse.java @@ -15,8 +15,8 @@ package com.cloud.api.response; import java.util.Date; import com.cloud.api.ApiConstants; -import com.cloud.utils.IdentityProxy; import com.cloud.serializer.Param; +import com.cloud.utils.IdentityProxy; import com.cloud.vm.VirtualMachine.State; import com.google.gson.annotations.SerializedName; @@ -133,6 +133,9 @@ public class DomainRouterResponse extends BaseResponse implements ControlledEnti @SerializedName("scriptsversion") @Param(description="the version of scripts") private String scriptsVersion; + @SerializedName(ApiConstants.VPC_ID) @Param(description="VPC the network belongs to") + private IdentityProxy vpcId = new IdentityProxy("vpc"); + @Override public Long getObjectId() { return getId(); @@ -301,4 +304,8 @@ public class DomainRouterResponse extends BaseResponse implements ControlledEnti public void setProjectName(String projectName) { this.projectName = projectName; } + + public void setVpcId(Long vpcId) { + this.vpcId.setValue(vpcId); + } } diff --git a/api/src/com/cloud/api/response/IPAddressResponse.java b/api/src/com/cloud/api/response/IPAddressResponse.java index 9c803881c22..1113dd3a0b1 100644 --- a/api/src/com/cloud/api/response/IPAddressResponse.java +++ b/api/src/com/cloud/api/response/IPAddressResponse.java @@ -92,16 +92,10 @@ public class IPAddressResponse extends BaseResponse implements ControlledEntityR @SerializedName(ApiConstants.PURPOSE) @Param(description="purpose of the IP address. In Acton this value is not null for Ips with isSystem=true, and can have either StaticNat or LB value") private String purpose; + + @SerializedName(ApiConstants.VPC_ID) @Param(description="VPC the ip belongs to") + private IdentityProxy vpcId = new IdentityProxy("vpc"); -/* - @SerializedName(ApiConstants.JOB_ID) @Param(description="shows the current pending asynchronous job ID. This tag is not returned if no current pending jobs are acting on the volume") - private IdentityProxy jobId = new IdentityProxy("async_job"); -*/ - -/* - @SerializedName(ApiConstants.JOB_STATUS) @Param(description="shows the current pending asynchronous job status") - private Integer jobStatus; -*/ public void setIpAddress(String ipAddress) { this.ipAddress = ipAddress; @@ -212,4 +206,8 @@ public class IPAddressResponse extends BaseResponse implements ControlledEntityR public void setPurpose(String purpose) { this.purpose = purpose; } + + public void setVpcId(Long vpcId) { + this.vpcId.setValue(vpcId); + } } diff --git a/api/src/com/cloud/api/response/NetworkResponse.java b/api/src/com/cloud/api/response/NetworkResponse.java index 834248b8670..5cb2cb47a86 100644 --- a/api/src/com/cloud/api/response/NetworkResponse.java +++ b/api/src/com/cloud/api/response/NetworkResponse.java @@ -127,6 +127,9 @@ public class NetworkResponse extends BaseResponse implements ControlledEntityRes @SerializedName(ApiConstants.SPECIFY_IP_RANGES) @Param(description="true if network supports specifying ip ranges, false otherwise") private Boolean specifyIpRanges; + @SerializedName(ApiConstants.VPC_ID) @Param(description="VPC the network belongs to") + private IdentityProxy vpcId = new IdentityProxy("vpc"); + public void setId(Long id) { this.id.setValue(id); } @@ -268,4 +271,8 @@ public class NetworkResponse extends BaseResponse implements ControlledEntityRes public void setSpecifyIpRanges(Boolean specifyIpRanges) { this.specifyIpRanges = specifyIpRanges; } + + public void setVpcId(Long vpcId) { + this.vpcId.setValue(vpcId); + } } diff --git a/api/src/com/cloud/api/response/VpcOfferingResponse.java b/api/src/com/cloud/api/response/VpcOfferingResponse.java new file mode 100644 index 00000000000..8fe536181a1 --- /dev/null +++ b/api/src/com/cloud/api/response/VpcOfferingResponse.java @@ -0,0 +1,77 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.api.response; + +import java.util.Date; +import java.util.List; + +import com.cloud.api.ApiConstants; +import com.cloud.serializer.Param; +import com.cloud.utils.IdentityProxy; +import com.google.gson.annotations.SerializedName; + +/** + * @author Alena Prokharchyk + */ +@SuppressWarnings("unused") +public class VpcOfferingResponse extends BaseResponse{ + @SerializedName("id") @Param(description="the id of the vpc offering") + private final IdentityProxy id = new IdentityProxy("vpc_offerings"); + + @SerializedName(ApiConstants.NAME) @Param(description="the name of the vpc offering") + private String name; + + @SerializedName(ApiConstants.DISPLAY_TEXT) @Param(description="an alternate display text of the vpc offering.") + private String displayText; + + @SerializedName(ApiConstants.CREATED) @Param(description="the date this vpc offering was created") + private Date created; + + @SerializedName(ApiConstants.IS_DEFAULT) @Param(description="true if vpc offering is default, false otherwise") + private Boolean isDefault; + + @SerializedName(ApiConstants.STATE) @Param(description="state of the vpc offering. Can be Disabled/Enabled") + private String state; + + @SerializedName(ApiConstants.SERVICE) @Param(description="the list of supported services", responseObject = ServiceResponse.class) + private List services; + + + public void setId(Long id) { + this.id.setValue(id); + } + + public void setName(String name) { + this.name = name; + } + + public void setDisplayText(String displayText) { + this.displayText = displayText; + } + + public void setCreated(Date created) { + this.created = created; + } + + public void setIsDefault(Boolean isDefault) { + this.isDefault = isDefault; + } + + public void setServices(List services) { + this.services = services; + } + + public void setState(String state) { + this.state = state; + } +} diff --git a/api/src/com/cloud/api/response/VpcResponse.java b/api/src/com/cloud/api/response/VpcResponse.java new file mode 100644 index 00000000000..84e339d776a --- /dev/null +++ b/api/src/com/cloud/api/response/VpcResponse.java @@ -0,0 +1,156 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.api.response; + +import java.util.Date; +import java.util.List; + +import com.cloud.api.ApiConstants; +import com.cloud.serializer.Param; +import com.cloud.utils.IdentityProxy; +import com.google.gson.annotations.SerializedName; + +/** + * @author Alena Prokharchyk + */ + +@SuppressWarnings("unused") +public class VpcResponse extends BaseResponse implements ControlledEntityResponse{ + @SerializedName("id") @Param(description="the id of the VPC") + private final IdentityProxy id = new IdentityProxy("vpc"); + + @SerializedName(ApiConstants.NAME) @Param(description="the name of the VPC") + private String name; + + @SerializedName(ApiConstants.DISPLAY_TEXT) @Param(description="an alternate display text of the VPC.") + private String displayText; + + @SerializedName(ApiConstants.STATE) @Param(description="state of the VPC. Can be Disabled/Enabled") + private String state; + + @SerializedName(ApiConstants.ZONE_ID) @Param(description="zone id of the vpc") + private IdentityProxy zoneId = new IdentityProxy("data_center"); + + @SerializedName(ApiConstants.SERVICE) @Param(description="the list of supported services", responseObject = ServiceResponse.class) + private List services; + + @SerializedName(ApiConstants.CIDR) @Param(description="the cidr the VPC") + private String cidr; + + @SerializedName(ApiConstants.VPC_OFF_ID) @Param(description="vpc offering id the VPC is created from") + private IdentityProxy vpcOfferingId = new IdentityProxy("vpc_offerings"); + + @SerializedName(ApiConstants.CREATED) @Param(description="the date this VPC was created") + private Date created; + + @SerializedName(ApiConstants.ACCOUNT) @Param(description="the owner of the VPC") + private String accountName; + + @SerializedName(ApiConstants.PROJECT_ID) @Param(description="the project id of the VPC") + private IdentityProxy projectId = new IdentityProxy("projects"); + + @SerializedName(ApiConstants.PROJECT) @Param(description="the project name of the VPC") + private String projectName; + + @SerializedName(ApiConstants.DOMAIN_ID) @Param(description="the domain id of the VPC owner") + private IdentityProxy domainId = new IdentityProxy("domain"); + + @SerializedName(ApiConstants.DOMAIN) @Param(description="the domain name of the owner") + private String domain; + + @SerializedName(ApiConstants.NETWORK) @Param(description="the list of networks belongign to the VPC", responseObject = NetworkResponse.class) + private List networks; + + @SerializedName(ApiConstants.RESTART_REQUIRED) @Param(description="true network requires restart") + private Boolean restartRequired; + + @SerializedName(ApiConstants.NETWORK_DOMAIN) @Param(description="the network domain") + private String networkDomain; + + public void setId(Long id) { + this.id.setValue(id); + } + + public void setName(String name) { + this.name = name; + } + + public void setDisplayText(String displayText) { + this.displayText = displayText; + } + + public void setCreated(Date created) { + this.created = created; + } + + public void setServices(List services) { + this.services = services; + } + + public void setState(String state) { + this.state = state; + } + + @Override + public void setAccountName(String accountName) { + this.accountName = accountName; + } + + @Override + public void setProjectId(Long projectId) { + this.projectId.setValue(projectId); + } + + @Override + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + @Override + public void setDomainId(Long domainId) { + this.domainId.setValue(domainId); + } + + @Override + public void setDomainName(String domainName) { + this.domain = domainName; + } + + public void setZoneId(Long zoneId) { + this.zoneId.setValue(zoneId); + } + + public void setCidr(String cidr) { + this.cidr = cidr; + } + + public void setVpcOfferingId(Long vpcOfferingId) { + this.vpcOfferingId.setValue(vpcOfferingId); + } + + public List getNetworks() { + return networks; + } + + public void setNetworks(List networks) { + this.networks = networks; + } + + public void setRestartRequired(Boolean restartRequired) { + this.restartRequired = restartRequired; + } + + public void setNetworkDomain(String networkDomain) { + this.networkDomain = networkDomain; + } +} diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java index 4c3e05371fc..e91bda28d54 100755 --- a/api/src/com/cloud/event/EventTypes.java +++ b/api/src/com/cloud/event/EventTypes.java @@ -260,4 +260,14 @@ public class EventTypes { public static final String EVENT_TAGS_CREATE = "CREATE_TAGS"; public static final String EVENT_TAGS_DELETE = "DELETE_TAGS"; + // VPC + public static final String EVENT_VPC_CREATE = "VPC.CREATE"; + public static final String EVENT_VPC_UPDATE = "VPC.UPDATE"; + public static final String EVENT_VPC_DELETE = "VPC.DELETE"; + public static final String EVENT_VPC_RESTART = "VPC.RESTART"; + + + public static final String EVENT_VPC_OFFERING_CREATE = "VPC.OFFERING.CREATE"; + public static final String EVENT_VPC_OFFERING_UPDATE = "VPC.OFFERING.UPDATE"; + public static final String EVENT_VPC_OFFERING_DELETE = "VPC.OFFERING.DELETE"; } diff --git a/api/src/com/cloud/hypervisor/HypervisorGuru.java b/api/src/com/cloud/hypervisor/HypervisorGuru.java index 8d869d74fab..09cc3673e7a 100644 --- a/api/src/com/cloud/hypervisor/HypervisorGuru.java +++ b/api/src/com/cloud/hypervisor/HypervisorGuru.java @@ -13,9 +13,11 @@ package com.cloud.hypervisor; import com.cloud.agent.api.Command; +import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.utils.component.Adapter; +import com.cloud.vm.NicProfile; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; @@ -45,4 +47,10 @@ public interface HypervisorGuru extends Adapter { * */ boolean trackVmHostChange(); + + /** + * @param profile + * @return + */ + NicTO toNicTO(NicProfile profile); } diff --git a/api/src/com/cloud/network/IpAddress.java b/api/src/com/cloud/network/IpAddress.java index 0a4c2e4671d..416dcb7f919 100644 --- a/api/src/com/cloud/network/IpAddress.java +++ b/api/src/com/cloud/network/IpAddress.java @@ -76,4 +76,14 @@ public interface IpAddress extends ControlledEntity { boolean getSystem(); + /** + * @return + */ + Long getVpcId(); + + /** + * @param vpcId + */ + void setVpcId(Long vpcId); + } diff --git a/api/src/com/cloud/network/Network.java b/api/src/com/cloud/network/Network.java index e8394961b2b..236a5a84e37 100644 --- a/api/src/com/cloud/network/Network.java +++ b/api/src/com/cloud/network/Network.java @@ -37,12 +37,15 @@ public interface Network extends ControlledEntity { public static class Service { private static List supportedServices = new ArrayList(); - public static final Service Vpn = new Service("Vpn", Capability.SupportedVpnTypes); + public static final Service Vpn = new Service("Vpn", Capability.SupportedVpnProtocols, Capability.VpnTypes); public static final Service Dhcp = new Service("Dhcp"); public static final Service Dns = new Service("Dns", Capability.AllowDnsSuffixModification); public static final Service Gateway = new Service("Gateway"); - public static final Service Firewall = new Service("Firewall", Capability.SupportedProtocols, Capability.MultipleIps, Capability.TrafficStatistics); - public static final Service Lb = new Service("Lb", Capability.SupportedLBAlgorithms, Capability.SupportedLBIsolation, Capability.SupportedProtocols, Capability.TrafficStatistics, Capability.LoadBalancingSupportedIps, Capability.SupportedStickinessMethods, Capability.ElasticLb); + public static final Service Firewall = new Service("Firewall", Capability.SupportedProtocols, + Capability.MultipleIps, Capability.TrafficStatistics, Capability.FirewallType); + public static final Service Lb = new Service("Lb", Capability.SupportedLBAlgorithms, Capability.SupportedLBIsolation, + Capability.SupportedProtocols, Capability.TrafficStatistics, Capability.LoadBalancingSupportedIps, + Capability.SupportedStickinessMethods, Capability.ElasticLb); public static final Service UserData = new Service("UserData"); public static final Service SourceNat = new Service("SourceNat", Capability.SupportedSourceNatTypes, Capability.RedundantRouter); public static final Service StaticNat = new Service("StaticNat", Capability.ElasticIp); @@ -109,6 +112,7 @@ public interface Network extends ControlledEntity { public static final Provider ExternalGateWay = new Provider("ExternalGateWay", true); public static final Provider ElasticLoadBalancerVm = new Provider("ElasticLoadBalancerVm", false); public static final Provider SecurityGroupProvider = new Provider("SecurityGroupProvider", false); + public static final Provider VPCVirtualRouter = new Provider("VpcVirtualRouter", false); public static final Provider None = new Provider("None", false); private String name; @@ -148,13 +152,16 @@ public interface Network extends ControlledEntity { public static final Capability SupportedStickinessMethods = new Capability("SupportedStickinessMethods"); public static final Capability MultipleIps = new Capability("MultipleIps"); public static final Capability SupportedSourceNatTypes = new Capability("SupportedSourceNatTypes"); - public static final Capability SupportedVpnTypes = new Capability("SupportedVpnTypes"); + public static final Capability SupportedVpnProtocols = new Capability("SupportedVpnTypes"); + public static final Capability VpnTypes = new Capability("VpnTypes"); public static final Capability TrafficStatistics = new Capability("TrafficStatistics"); public static final Capability LoadBalancingSupportedIps = new Capability("LoadBalancingSupportedIps"); public static final Capability AllowDnsSuffixModification = new Capability("AllowDnsSuffixModification"); public static final Capability RedundantRouter = new Capability("RedundantRouter"); public static final Capability ElasticIp = new Capability("ElasticIp"); public static final Capability ElasticLb = new Capability("ElasticLb"); + public static final Capability FirewallType = new Capability("FirewallType"); + private String name; @@ -279,4 +286,9 @@ public interface Network extends ControlledEntity { boolean isRestartRequired(); boolean getSpecifyIpRanges(); + + /** + * @return + */ + Long getVpcId(); } diff --git a/api/src/com/cloud/network/NetworkProfile.java b/api/src/com/cloud/network/NetworkProfile.java index 8c965e12abe..065529c4dfa 100644 --- a/api/src/com/cloud/network/NetworkProfile.java +++ b/api/src/com/cloud/network/NetworkProfile.java @@ -43,6 +43,7 @@ public class NetworkProfile implements Network { private ACLType aclType; private boolean restartRequired; private boolean specifyIpRanges; + private Long vpcId; public NetworkProfile(Network network) { this.id = network.getId(); @@ -67,6 +68,7 @@ public class NetworkProfile implements Network { this.aclType = network.getAclType(); this.restartRequired = network.isRestartRequired(); this.specifyIpRanges = network.getSpecifyIpRanges(); + this.vpcId = network.getVpcId(); } public String getDns1() { @@ -206,4 +208,9 @@ public class NetworkProfile implements Network { return false; } + @Override + public Long getVpcId() { + return vpcId; + } + } diff --git a/api/src/com/cloud/network/NetworkService.java b/api/src/com/cloud/network/NetworkService.java index 048d7145b6f..129b6c38b3a 100755 --- a/api/src/com/cloud/network/NetworkService.java +++ b/api/src/com/cloud/network/NetworkService.java @@ -37,28 +37,21 @@ public interface NetworkService { List getIsolatedNetworksOwnedByAccountInZone(long zoneId, Account owner); - IpAddress allocateIP(long networkId, Account ipOwner) throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException; - /** - * Associates a public IP address for a router. - * - * @param ipId - * - the command specifying ipAddress - * @return ip address object - * @throws ResourceAllocationException - * , InsufficientCapacityException - */ - IpAddress associateIP(long ipId) throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException, ResourceUnavailableException; + IpAddress allocateIP(Account ipOwner, boolean isSystem, long zoneId) throws ResourceAllocationException, + InsufficientAddressCapacityException, ConcurrentOperationException; - boolean disassociateIpAddress(long ipAddressId) throws InsufficientAddressCapacityException; + boolean releaseIpAddress(long ipAddressId) throws InsufficientAddressCapacityException; - Network createNetwork(CreateNetworkCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException; + Network createGuestNetwork(CreateNetworkCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, + ResourceAllocationException; List searchForNetworks(ListNetworksCmd cmd); boolean deleteNetwork(long networkId); - boolean restartNetwork(RestartNetworkCmd cmd, boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; + boolean restartNetwork(RestartNetworkCmd cmd, boolean cleanup) throws ConcurrentOperationException, + ResourceUnavailableException, InsufficientCapacityException; int getActiveNicsInNetwork(long networkId); @@ -74,7 +67,8 @@ public interface NetworkService { Long getDedicatedNetworkDomain(long networkId); - Network updateGuestNetwork(long networkId, String name, String displayText, Account callerAccount, User callerUser, String domainSuffix, Long networkOfferingId, Boolean changeCidr); + Network updateGuestNetwork(long networkId, String name, String displayText, Account callerAccount, User callerUser, + String domainSuffix, Long networkOfferingId, Boolean changeCidr); Integer getNetworkRate(long networkId, Long vmId); @@ -82,11 +76,14 @@ public interface NetworkService { Map> getNetworkOfferingServiceProvidersMap(long networkOfferingId); - PhysicalNetwork createPhysicalNetwork(Long zoneId, String vnetRange, String networkSpeed, List isolationMethods, String broadcastDomainRange, Long domainId, List tags, String name); + PhysicalNetwork createPhysicalNetwork(Long zoneId, String vnetRange, String networkSpeed, + List isolationMethods, String broadcastDomainRange, Long domainId, List tags, String name); - List searchPhysicalNetworks(Long id, Long zoneId, String keyword, Long startIndex, Long pageSize, String name); + List searchPhysicalNetworks(Long id, Long zoneId, String keyword, + Long startIndex, Long pageSize, String name); - PhysicalNetwork updatePhysicalNetwork(Long id, String networkSpeed, List tags, String newVnetRangeString, String state); + PhysicalNetwork updatePhysicalNetwork(Long id, String networkSpeed, List tags, + String newVnetRangeString, String state); boolean deletePhysicalNetwork(Long id); @@ -94,9 +91,11 @@ public interface NetworkService { List listSupportedNetworkServiceProviders(String serviceName); - PhysicalNetworkServiceProvider addProviderToPhysicalNetwork(Long physicalNetworkId, String providerName, Long destinationPhysicalNetworkId, List enabledServices); + PhysicalNetworkServiceProvider addProviderToPhysicalNetwork(Long physicalNetworkId, String providerName, + Long destinationPhysicalNetworkId, List enabledServices); - List listNetworkServiceProviders(Long physicalNetworkId, String name, String state, Long startIndex, Long pageSize); + List listNetworkServiceProviders(Long physicalNetworkId, String name, + String state, Long startIndex, Long pageSize); PhysicalNetworkServiceProvider updateNetworkServiceProvider(Long id, String state, List enabledServices); @@ -112,7 +111,8 @@ public interface NetworkService { long findPhysicalNetworkId(long zoneId, String tag, TrafficType trafficType); - PhysicalNetworkTrafficType addTrafficTypeToPhysicalNetwork(Long physicalNetworkId, String trafficType, String xenLabel, String kvmLabel, String vmwareLabel, String simulatorLabel, String vlan); + PhysicalNetworkTrafficType addTrafficTypeToPhysicalNetwork(Long physicalNetworkId, String trafficType, + String xenLabel, String kvmLabel, String vmwareLabel, String simulatorLabel, String vlan); PhysicalNetworkTrafficType getPhysicalNetworkTrafficType(Long id); @@ -130,4 +130,40 @@ public interface NetworkService { List getIsolatedNetworksWithSourceNATOwnedByAccountInZone(long zoneId, Account owner); + List listNetworksByVpc(long vpcId); + + boolean isVmPartOfNetwork(long vmId, long ntwkId); + + /** + * @param entityId + * @param networkId + * @param vpcId + * @return + * @throws ConcurrentOperationException + * @throws ResourceUnavailableException + * @throws ResourceAllocationException + * @throws InsufficientAddressCapacityException + */ + IpAddress associateIP(long ipId, Long networkId, Long vpcId) throws InsufficientAddressCapacityException, + ResourceAllocationException, ResourceUnavailableException, ConcurrentOperationException; + + /** + * @param networkName + * @param displayText + * @param physicalNetworkId + * @param vlan + * @param startIp + * @param endIP TODO + * @param gateway + * @param netmask + * @param networkOwnerId + * @return + * @throws InsufficientCapacityException + * @throws ConcurrentOperationException + * @throws ResourceAllocationException + */ + Network createPrivateNetwork(String networkName, String displayText, long physicalNetworkId, String vlan, + String startIp, String endIP, String gateway, String netmask, long networkOwnerId) + throws ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException; + } diff --git a/api/src/com/cloud/network/VirtualNetworkApplianceService.java b/api/src/com/cloud/network/VirtualNetworkApplianceService.java index 0a964b4dcee..8ef4dd814e3 100644 --- a/api/src/com/cloud/network/VirtualNetworkApplianceService.java +++ b/api/src/com/cloud/network/VirtualNetworkApplianceService.java @@ -26,7 +26,8 @@ public interface VirtualNetworkApplianceService { * the command specifying router's id * @return DomainRouter object */ - VirtualRouter startRouter(long routerId, boolean reprogramNetwork) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; + VirtualRouter startRouter(long routerId, boolean reprogramNetwork) throws ConcurrentOperationException, + ResourceUnavailableException, InsufficientCapacityException; /** * Reboots domain router @@ -35,7 +36,8 @@ public interface VirtualNetworkApplianceService { * the command specifying router's id * @return router if successful */ - VirtualRouter rebootRouter(long routerId, boolean reprogramNetwork) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; + VirtualRouter rebootRouter(long routerId, boolean reprogramNetwork) throws ConcurrentOperationException, + ResourceUnavailableException, InsufficientCapacityException; VirtualRouter upgradeRouter(UpgradeRouterCmd cmd); @@ -55,4 +57,5 @@ public interface VirtualNetworkApplianceService { VirtualRouter startRouter(long id) throws ResourceUnavailableException, InsufficientCapacityException, ConcurrentOperationException; VirtualRouter destroyRouter(long routerId) throws ResourceUnavailableException, ConcurrentOperationException; + } diff --git a/api/src/com/cloud/network/VirtualRouterProvider.java b/api/src/com/cloud/network/VirtualRouterProvider.java index 81eaf1e3c68..f6d416faa6b 100644 --- a/api/src/com/cloud/network/VirtualRouterProvider.java +++ b/api/src/com/cloud/network/VirtualRouterProvider.java @@ -15,7 +15,8 @@ package com.cloud.network; public interface VirtualRouterProvider { public enum VirtualRouterProviderType { VirtualRouter, - ElasticLoadBalancerVm + ElasticLoadBalancerVm, + VPCVirtualRouter } public VirtualRouterProviderType getType(); diff --git a/api/src/com/cloud/network/VpcVirtualNetworkApplianceService.java b/api/src/com/cloud/network/VpcVirtualNetworkApplianceService.java new file mode 100644 index 00000000000..078d4053534 --- /dev/null +++ b/api/src/com/cloud/network/VpcVirtualNetworkApplianceService.java @@ -0,0 +1,48 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network; + +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.router.VirtualRouter; + +/** + * @author Alena Prokharchyk + */ +public interface VpcVirtualNetworkApplianceService { + + /** + * @param router + * @param network + * @param isRedundant + * @return + * @throws ConcurrentOperationException + * @throws ResourceUnavailableException + * @throws InsufficientCapacityException + */ + boolean addVpcRouterToGuestNetwork(VirtualRouter router, Network network, boolean isRedundant) + throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; + + /** + * @param router + * @param network + * @param isRedundant + * @return + * @throws ConcurrentOperationException + * @throws ResourceUnavailableException + */ + boolean removeRouterFromGuestNetwork(VirtualRouter router, Network network, boolean isRedundant) + throws ConcurrentOperationException, ResourceUnavailableException; + +} diff --git a/api/src/com/cloud/network/element/NetworkElement.java b/api/src/com/cloud/network/element/NetworkElement.java index e18a34f6308..c6845d3d346 100644 --- a/api/src/com/cloud/network/element/NetworkElement.java +++ b/api/src/com/cloud/network/element/NetworkElement.java @@ -52,7 +52,8 @@ public interface NetworkElement extends Adapter { * @return true if network configuration is now usable; false if not; null if not handled by this element. * @throws InsufficientNetworkCapacityException TODO */ - boolean implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; + boolean implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) + throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; /** * Prepare for a nic to be added into this network. @@ -66,7 +67,9 @@ public interface NetworkElement extends Adapter { * @throws ResourceUnavailableException * @throws InsufficientNetworkCapacityException */ - boolean prepare(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; + boolean prepare(Network network, NicProfile nic, VirtualMachineProfile vm, + DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, + ResourceUnavailableException, InsufficientCapacityException; /** * A nic is released from this network. @@ -78,7 +81,8 @@ public interface NetworkElement extends Adapter { * @throws ConcurrentOperationException * @throws ResourceUnavailableException */ - boolean release(Network network, NicProfile nic, VirtualMachineProfile vm, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException; + boolean release(Network network, NicProfile nic, VirtualMachineProfile vm, + ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException; /** * The network is being shutdown. @@ -89,7 +93,8 @@ public interface NetworkElement extends Adapter { * @throws ConcurrentOperationException * @throws ResourceUnavailableException */ - boolean shutdown(Network network, ReservationContext context, boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException; + boolean shutdown(Network network, ReservationContext context, boolean cleanup) + throws ConcurrentOperationException, ResourceUnavailableException; /** * The network is being destroyed. @@ -114,7 +119,8 @@ public interface NetworkElement extends Adapter { * @throws ConcurrentOperationException * @throws ResourceUnavailableException */ - boolean shutdownProviderInstances(PhysicalNetworkServiceProvider provider, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException; + boolean shutdownProviderInstances(PhysicalNetworkServiceProvider provider, ReservationContext context) + throws ConcurrentOperationException, ResourceUnavailableException; /** * This should return true if out of multiple services provided by this element, only some can be enabled. If all the services MUST be provided, this should return false. diff --git a/api/src/com/cloud/network/element/UserDataServiceProvider.java b/api/src/com/cloud/network/element/UserDataServiceProvider.java index 59c64bb965d..7ffbe9548a0 100644 --- a/api/src/com/cloud/network/element/UserDataServiceProvider.java +++ b/api/src/com/cloud/network/element/UserDataServiceProvider.java @@ -17,7 +17,6 @@ import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network; -import com.cloud.uservm.UserVm; import com.cloud.vm.NicProfile; import com.cloud.vm.ReservationContext; import com.cloud.vm.VirtualMachine; diff --git a/api/src/com/cloud/network/element/VirtualRouterElementService.java b/api/src/com/cloud/network/element/VirtualRouterElementService.java index dc4e510259a..32139be141e 100644 --- a/api/src/com/cloud/network/element/VirtualRouterElementService.java +++ b/api/src/com/cloud/network/element/VirtualRouterElementService.java @@ -17,11 +17,12 @@ import java.util.List; import com.cloud.api.commands.ConfigureVirtualRouterElementCmd; import com.cloud.api.commands.ListVirtualRouterElementsCmd; import com.cloud.network.VirtualRouterProvider; +import com.cloud.network.VirtualRouterProvider.VirtualRouterProviderType; import com.cloud.utils.component.PluggableService; public interface VirtualRouterElementService extends PluggableService{ VirtualRouterProvider configure(ConfigureVirtualRouterElementCmd cmd); - VirtualRouterProvider addElement(Long nspId); + VirtualRouterProvider addElement(Long nspId, VirtualRouterProviderType providerType); VirtualRouterProvider getCreatedElement(long id); List searchForVirtualRouterElement(ListVirtualRouterElementsCmd cmd); } diff --git a/api/src/com/cloud/network/element/VpcProvider.java b/api/src/com/cloud/network/element/VpcProvider.java new file mode 100644 index 00000000000..bd55ff47c77 --- /dev/null +++ b/api/src/com/cloud/network/element/VpcProvider.java @@ -0,0 +1,50 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.element; + +import com.cloud.deploy.DeployDestination; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InsufficientNetworkCapacityException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.vpc.Vpc; +import com.cloud.vm.ReservationContext; + +/** + * @author Alena Prokharchyk + */ +public interface VpcProvider extends NetworkElement{ + /** + * Start vpc element as specified + * @param vpc fully specified vpc configuration. + * @throws InsufficientNetworkCapacityException TODO + */ + boolean implementVpc(Vpc vpc, DeployDestination dest, ReservationContext context) + throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; + + /** + * @param vpc + * @return + * @throws ConcurrentOperationException + * @throws ResourceUnavailableException + */ + boolean shutdownVpc(Vpc vpc) throws ConcurrentOperationException, ResourceUnavailableException; + + boolean createPrivateGateway(); + + boolean createVpnGateway(); + + boolean deletePrivateGateway(); + + boolean deleteVpnGateway(); +} diff --git a/api/src/com/cloud/network/router/VirtualRouter.java b/api/src/com/cloud/network/router/VirtualRouter.java index 34ed9c12445..2ab2a5deafb 100755 --- a/api/src/com/cloud/network/router/VirtualRouter.java +++ b/api/src/com/cloud/network/router/VirtualRouter.java @@ -30,8 +30,11 @@ public interface VirtualRouter extends VirtualMachine { FAULT } RedundantState getRedundantState(); - String getGuestIpAddress(); String getPublicIpAddress(); boolean isStopPending(); void setStopPending(boolean stopPending); + /** + * @return + */ + Long getVpcId(); } diff --git a/api/src/com/cloud/network/rules/RulesService.java b/api/src/com/cloud/network/rules/RulesService.java index cde28dbfd52..28db9dc385d 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, boolean isSystemVm) throws NetworkRuleConflictException, ResourceUnavailableException; + boolean enableStaticNat(long ipAddressId, long vmId, long networkId, boolean isSystemVm) throws NetworkRuleConflictException, ResourceUnavailableException; PortForwardingRule getPortForwardigRule(long ruleId); diff --git a/api/src/com/cloud/network/vpc/Vpc.java b/api/src/com/cloud/network/vpc/Vpc.java new file mode 100644 index 00000000000..5e15bab1732 --- /dev/null +++ b/api/src/com/cloud/network/vpc/Vpc.java @@ -0,0 +1,52 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc; + +import com.cloud.acl.ControlledEntity; +import com.cloud.network.Network; + + +/** + * @author Alena Prokharchyk + */ +public interface Vpc extends ControlledEntity{ + public enum State { + Enabled, + Disabled + } + + public static final String _supportedProviders = Network.Provider.VPCVirtualRouter.getName(); + + boolean readyToUse(); + + long getId(); + + String getUuid(); + + String getName(); + + long getZoneId(); + + String getCidr(); + + State getState(); + + long getVpcOfferingId(); + + String getDisplayText(); + + String getNetworkDomain(); + + boolean isRestartRequired(); + +} diff --git a/api/src/com/cloud/network/vpc/VpcOffering.java b/api/src/com/cloud/network/vpc/VpcOffering.java new file mode 100644 index 00000000000..167cdced8bb --- /dev/null +++ b/api/src/com/cloud/network/vpc/VpcOffering.java @@ -0,0 +1,46 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc; + + +/** + * @author Alena Prokharchyk + */ +public interface VpcOffering { + public enum State { + Disabled, + Enabled + } + + public static final String defaultVPCOfferingName = "Default VPC offering"; + + long getId(); + + String getUuid(); + + String getName(); + + String getUniqueName(); + + String getDisplayText(); + + State getState(); + + boolean isDefault(); + + /** + * @return + */ + Long getServiceOfferingId(); + +} diff --git a/api/src/com/cloud/network/vpc/VpcService.java b/api/src/com/cloud/network/vpc/VpcService.java new file mode 100644 index 00000000000..9473d180867 --- /dev/null +++ b/api/src/com/cloud/network/vpc/VpcService.java @@ -0,0 +1,138 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.Network; +import com.cloud.network.Network.Provider; +import com.cloud.network.Network.Service; + +/** + * @author Alena Prokharchyk + */ +public interface VpcService { + + public VpcOffering getVpcOffering(long vpcOfferingId); + + public VpcOffering createVpcOffering(String name, String displayText, List supportedServices); + + public Vpc getVpc(long vpcId); + + public Vpc getActiveVpc(long vpcId); + + public List getVpcNetworks(long vpcId); + + Map> getVpcOffSvcProvidersMap(long vpcOffId); + + List listVpcOfferings(Long id, String name, String displayText, List supportedServicesStr, + Boolean isDefault, String keyword, String state, Long startIndex, Long pageSizeVal); + + /** + * @param offId + * @return + */ + public boolean deleteVpcOffering(long offId); + + /** + * @param vpcOffId + * @param vpcOfferingName + * @param displayText + * @param state + * @return + */ + public VpcOffering updateVpcOffering(long vpcOffId, String vpcOfferingName, String displayText, String state); + + /** + * @param zoneId + * @param vpcOffId + * @param vpcOwnerId + * @param vpcName + * @param displayText + * @param cidr + * @param networkDomain TODO + * @return + */ + public Vpc createVpc(long zoneId, long vpcOffId, long vpcOwnerId, String vpcName, String displayText, String cidr, String networkDomain); + + /** + * @param vpcId + * @return + * @throws InsufficientCapacityException + * @throws ResourceUnavailableException + * @throws ConcurrentOperationException + */ + public boolean deleteVpc(long vpcId) throws ConcurrentOperationException, ResourceUnavailableException; + + /** + * @param vpcId + * @param vpcName + * @param displayText + * @return + */ + public Vpc updateVpc(long vpcId, String vpcName, String displayText); + + /** + * @param id + * @param vpcName + * @param displayText + * @param supportedServicesStr + * @param cidr + * @param state TODO + * @param accountName + * @param domainId + * @param keyword + * @param startIndex + * @param pageSizeVal + * @param zoneId TODO + * @param isRecursive TODO + * @param listAll TODO + * @param restartRequired TODO + * @param vpc + * @return + */ + public List listVpcs(Long id, String vpcName, String displayText, + List supportedServicesStr, String cidr, Long vpcOffId, String state, String accountName, Long domainId, + String keyword, Long startIndex, Long pageSizeVal, Long zoneId, Boolean isRecursive, Boolean listAll, + Boolean restartRequired); + + /** + * @param vpcId + * @return + * @throws InsufficientCapacityException + * @throws ResourceUnavailableException + * @throws ConcurrentOperationException + */ + boolean startVpc(long vpcId) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; + + /** + * @param vpcId + * @return + * @throws ConcurrentOperationException + * @throws ResourceUnavailableException + */ + boolean shutdownVpc(long vpcId) throws ConcurrentOperationException, ResourceUnavailableException; + + /** + * @param id + * @return + * @throws InsufficientCapacityException + */ + boolean restartVpc(Long id) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; + +} diff --git a/api/src/com/cloud/network/vpn/RemoteAccessVpnService.java b/api/src/com/cloud/network/vpn/RemoteAccessVpnService.java index 3a50d7466d1..091626cdc26 100644 --- a/api/src/com/cloud/network/vpn/RemoteAccessVpnService.java +++ b/api/src/com/cloud/network/vpn/RemoteAccessVpnService.java @@ -23,7 +23,8 @@ import com.cloud.network.VpnUser; public interface RemoteAccessVpnService { - RemoteAccessVpn createRemoteAccessVpn(long vpnServerAddressId, String ipRange, boolean openFirewall) throws NetworkRuleConflictException; + RemoteAccessVpn createRemoteAccessVpn(long vpnServerAddressId, String ipRange, boolean openFirewall, long networkId) + throws NetworkRuleConflictException; void destroyRemoteAccessVpn(long vpnServerAddressId) throws ResourceUnavailableException; RemoteAccessVpn startRemoteAccessVpn(long vpnServerAddressId, boolean openFirewall) throws ResourceUnavailableException; diff --git a/api/src/com/cloud/offering/NetworkOffering.java b/api/src/com/cloud/offering/NetworkOffering.java index 195bc0d6926..7415e1a44bc 100644 --- a/api/src/com/cloud/offering/NetworkOffering.java +++ b/api/src/com/cloud/offering/NetworkOffering.java @@ -35,13 +35,16 @@ public interface NetworkOffering { public final static String SystemControlNetwork = "System-Control-Network"; public final static String SystemManagementNetwork = "System-Management-Network"; public final static String SystemStorageNetwork = "System-Storage-Network"; - + public final static String SystemPrivateGatewayNetworkOffering = "System-Private-Gateway-Network-Offering"; + public final static String DefaultSharedNetworkOfferingWithSGService = "DefaultSharedNetworkOfferingWithSGService"; public final static String DefaultIsolatedNetworkOfferingWithSourceNatService = "DefaultIsolatedNetworkOfferingWithSourceNatService"; public final static String OvsIsolatedNetworkOfferingWithSourceNatService = "OvsIsolatedNetworkOfferingWithSourceNatService"; public final static String DefaultSharedNetworkOffering = "DefaultSharedNetworkOffering"; public final static String DefaultIsolatedNetworkOffering = "DefaultIsolatedNetworkOffering"; public final static String DefaultSharedEIPandELBNetworkOffering = "DefaultSharedNetscalerEIPandELBNetworkOffering"; + public final static String DefaultIsolatedNetworkOfferingForVpcNetworks = "DefaultIsolatedNetworkOfferingForVpcNetworks"; + long getId(); diff --git a/api/src/com/cloud/storage/StorageService.java b/api/src/com/cloud/storage/StorageService.java index 7553f9e84b2..4fa097ee50f 100644 --- a/api/src/com/cloud/storage/StorageService.java +++ b/api/src/com/cloud/storage/StorageService.java @@ -43,7 +43,8 @@ public interface StorageService{ * @throws ResourceUnavailableException * TODO */ - StoragePool createPool(CreateStoragePoolCmd cmd) throws ResourceInUseException, IllegalArgumentException, UnknownHostException, ResourceUnavailableException; + StoragePool createPool(CreateStoragePoolCmd cmd) throws ResourceInUseException, IllegalArgumentException, + UnknownHostException, ResourceUnavailableException; /** * Creates the database object for a volume based on the given criteria @@ -88,7 +89,8 @@ public interface StorageService{ * @throws InsufficientCapacityException * TODO */ - public StoragePool preparePrimaryStorageForMaintenance(Long primaryStorageId) throws ResourceUnavailableException, InsufficientCapacityException; + public StoragePool preparePrimaryStorageForMaintenance(Long primaryStorageId) throws ResourceUnavailableException, + InsufficientCapacityException; /** * Complete maintenance for primary storage @@ -99,7 +101,8 @@ public interface StorageService{ * @throws ResourceUnavailableException * TODO */ - public StoragePool cancelPrimaryStorageForMaintenance(CancelPrimaryStorageMaintenanceCmd cmd) throws ResourceUnavailableException; + public StoragePool cancelPrimaryStorageForMaintenance(CancelPrimaryStorageMaintenanceCmd cmd) + throws ResourceUnavailableException; public StoragePool updateStoragePool(UpdateStoragePoolCmd cmd) throws IllegalArgumentException; diff --git a/api/src/com/cloud/vm/Nic.java b/api/src/com/cloud/vm/Nic.java index 3bc92920fd8..d121034867c 100644 --- a/api/src/com/cloud/vm/Nic.java +++ b/api/src/com/cloud/vm/Nic.java @@ -31,7 +31,8 @@ public interface Nic { } public enum State implements FiniteState { - Allocated("Resource is allocated but not reserved"), Reserving("Resource is being reserved right now"), Reserved("Resource has been reserved."), Releasing("Resource is being released"), Deallocating( + Allocated("Resource is allocated but not reserved"), Reserving("Resource is being reserved right now"), + Reserved("Resource has been reserved."), Releasing("Resource is being released"), Deallocating( "Resource is being deallocated"); String _description; diff --git a/api/src/com/cloud/vm/NicProfile.java b/api/src/com/cloud/vm/NicProfile.java index 128e36172e8..a21748f3db2 100644 --- a/api/src/com/cloud/vm/NicProfile.java +++ b/api/src/com/cloud/vm/NicProfile.java @@ -203,7 +203,8 @@ public class NicProfile { return strategy; } - public NicProfile(Nic nic, Network network, URI broadcastUri, URI isolationUri, Integer networkRate, boolean isSecurityGroupEnabled, String name) { + public NicProfile(Nic nic, Network network, URI broadcastUri, URI isolationUri, Integer networkRate, + boolean isSecurityGroupEnabled, String name) { this.id = nic.getId(); this.networkId = network.getId(); this.gateway = nic.getGateway(); @@ -230,13 +231,6 @@ public class NicProfile { } } - public NicProfile(long id, BroadcastDomainType type, Mode mode, long vmId) { - this.id = id; - this.broadcastType = type; - this.mode = mode; - this.vmId = vmId; - } - public NicProfile(ReservationStrategy strategy, String ip4Address, String macAddress, String gateway, String netmask) { this.format = AddressFormat.Ip4; this.ip4Address = ip4Address; diff --git a/api/src/com/cloud/vm/PluggableNics.java b/api/src/com/cloud/vm/PluggableNics.java new file mode 100644 index 00000000000..3b6c34970f2 --- /dev/null +++ b/api/src/com/cloud/vm/PluggableNics.java @@ -0,0 +1,20 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.vm; + +/** + * @author Alena Prokharchyk + */ +public interface PluggableNics { + boolean canPlugNics(); +} diff --git a/api/src/com/cloud/vm/UserVmService.java b/api/src/com/cloud/vm/UserVmService.java index 8b8eb205b36..5d4b668790c 100755 --- a/api/src/com/cloud/vm/UserVmService.java +++ b/api/src/com/cloud/vm/UserVmService.java @@ -50,7 +50,6 @@ import com.cloud.template.VirtualMachineTemplate; import com.cloud.user.Account; import com.cloud.uservm.UserVm; import com.cloud.utils.exception.ExecutionException; -import com.cloud.vm.VirtualMachineProfile.Param; public interface UserVmService { /** diff --git a/api/src/com/cloud/vm/VirtualMachine.java b/api/src/com/cloud/vm/VirtualMachine.java index d282aa6464f..9dc04c1ee0b 100755 --- a/api/src/com/cloud/vm/VirtualMachine.java +++ b/api/src/com/cloud/vm/VirtualMachine.java @@ -286,4 +286,6 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, Identity, S HypervisorType getHypervisorType(); public Map getDetails(); + + boolean canPlugNics(); } diff --git a/api/src/com/cloud/vm/VirtualMachineProfile.java b/api/src/com/cloud/vm/VirtualMachineProfile.java index 8f863d9032e..ea714c2d80c 100644 --- a/api/src/com/cloud/vm/VirtualMachineProfile.java +++ b/api/src/com/cloud/vm/VirtualMachineProfile.java @@ -36,7 +36,7 @@ public interface VirtualMachineProfile { public static final Param VmPassword = new Param("VmPassword"); public static final Param ControlNic = new Param("ControlNic"); - public static final Param ReProgramNetwork = new Param("RestartNetwork"); + public static final Param ReProgramGuestNetworks = new Param("RestartNetwork"); public static final Param PxeSeverType = new Param("PxeSeverType"); public static final Param HaTag = new Param("HaTag"); diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index fb1f236dfe6..a4e85ac54eb 100755 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -337,3 +337,24 @@ deleteNetworkDevice=com.cloud.api.commands.DeleteNetworkDeviceCmd;1 createTags=com.cloud.api.commands.CreateTagsCmd;15 deleteTags=com.cloud.api.commands.DeleteTagsCmd;15 listTags=com.cloud.api.commands.ListTagsCmd;15 + +### VPC commands +createVPC=com.cloud.api.commands.CreateVPCCmd;15 +listVPCs=com.cloud.api.commands.ListVPCsCmd;15 +deleteVPC=com.cloud.api.commands.DeleteVPCCmd;15 +updateVPC=com.cloud.api.commands.UpdateVPCCmd;15 +restartVPC=com.cloud.api.commands.RestartVPCCmd;15 + +#### VPC offering commands +createVPCOffering=com.cloud.api.commands.CreateVPCOfferingCmd;1 +updateVPCOffering=com.cloud.api.commands.UpdateVPCOfferingCmd;1 +deleteVPCOffering=com.cloud.api.commands.DeleteVPCOfferingCmd;1 +listVPCOfferings=com.cloud.api.commands.ListVPCOfferingsCmd;15 + +#### Private gateway commands +#createPrivateGateway=com.cloud.api.commands.CreatePrivateGatewayCmd;15 +#listPrivateGateways=com.cloud.api.commands.ListPrivateGatewaysCmd;15 +#deletePrivateGateway=com.cloud.api.commands.DeletePrivateGatewayCmd;15 + +#### Private network command +createPrivateNetwork=com.cloud.api.commands.CreatePrivateNetworkCmd;1 diff --git a/client/tomcatconf/components.xml.in b/client/tomcatconf/components.xml.in index 48869b5daee..8202d70e4bf 100755 --- a/client/tomcatconf/components.xml.in +++ b/client/tomcatconf/components.xml.in @@ -78,6 +78,7 @@ + @@ -142,6 +143,7 @@ + diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java index 876e3fe4a2c..a610e70380e 100755 --- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java +++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java @@ -82,7 +82,6 @@ import com.cloud.utils.script.Script; public class VirtualRoutingResource implements Manager { private static final Logger s_logger = Logger.getLogger(VirtualRoutingResource.class); private String _savepasswordPath; // This script saves a random password to the DomR file system - private String _ipassocPath; private String _publicIpAddress; private String _firewallPath; private String _loadbPath; @@ -90,11 +89,8 @@ public class VirtualRoutingResource implements Manager { private String _vmDataPath; private String _publicEthIf; private String _privateEthIf; - private String _getRouterStatusPath; private String _bumpUpPriorityPath; - private String _l2tpVpnPath; - private String _getDomRVersionPath; - + private String _routerProxyPath; private int _timeout; private int _startTimeout; @@ -147,36 +143,40 @@ public class VirtualRoutingResource implements Manager { private Answer execute(VpnUsersCfgCommand cmd) { for (VpnUsersCfgCommand.UsernamePassword userpwd: cmd.getUserpwds()) { - Script command = new Script(_l2tpVpnPath, _timeout, s_logger); - command.add(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP)); + String args = ""; if (!userpwd.isAdd()) { - command.add("-U ", userpwd.getUsername()); + args +="-U "; + args +=userpwd.getUsername(); } else { - command.add("-u ", userpwd.getUsernamePassword()); + args +="-u "; + args += userpwd.getUsernamePassword(); } - String result = command.execute(); + String result = routerProxy("vpn_l2tp.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); if (result != null) { return new Answer(cmd, false, "Configure VPN user failed for user " + userpwd.getUsername()); } } - return new Answer(cmd); } private Answer execute(RemoteAccessVpnCfgCommand cmd) { - Script command = new Script(_l2tpVpnPath, _timeout, s_logger); - command.add(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP)); + String args = ""; if (cmd.isCreate()) { - command.add("-r ", cmd.getIpRange()); - command.add("-p ", cmd.getPresharedKey()); - command.add("-s ", cmd.getVpnServerIp()); - command.add("-l ", cmd.getLocalIp()); - command.add("-c "); + args += "-r "; + args += cmd.getIpRange(); + args += " -p "; + args += cmd.getPresharedKey(); + args += " -s "; + args += cmd.getVpnServerIp(); + args += " -l "; + args += cmd.getLocalIp(); + args += " -c "; } else { - command.add("-d "); - command.add("-s ", cmd.getVpnServerIp()); + args +="-d "; + args += " -s "; + args += cmd.getVpnServerIp(); } - String result = command.execute(); + String result = routerProxy("vpn_l2tp.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); if (result != null) { return new Answer(cmd, false, "Configure VPN failed"); } @@ -474,9 +474,18 @@ public class VirtualRoutingResource implements Manager { } public String getRouterStatus(String routerIP) { - final Script command = new Script(_getRouterStatusPath, _timeout, s_logger); + return routerProxy("checkrouter.sh", routerIP, null); + } + + + public String routerProxy(String script, String routerIP, String args) { + final Script command = new Script(_routerProxyPath, _timeout, s_logger); final OutputInterpreter.OneLineParser parser = new OutputInterpreter.OneLineParser(); + command.add(script); command.add(routerIP); + if ( args != null ) { + command.add(args); + } String result = command.execute(parser); if (result == null) { return parser.getLine(); @@ -507,14 +516,7 @@ public class VirtualRoutingResource implements Manager { } protected String getDomRVersion(String routerIP) { - final Script command = new Script(_getDomRVersionPath, _timeout, s_logger); - final OutputInterpreter.OneLineParser parser = new OutputInterpreter.OneLineParser(); - command.add(routerIP); - String result = command.execute(parser); - if (result == null) { - return parser.getLine(); - } - return null; + return routerProxy("netusage.sh", routerIP, null); } protected Answer execute(GetDomRVersionCmd cmd) { @@ -592,48 +594,49 @@ public class VirtualRoutingResource implements Manager { public String assignPublicIpAddress(final String vmName, final long id, final String vnet, final String privateIpAddress, final String macAddress, final String publicIpAddress) { - - final Script command = new Script(_ipassocPath, _timeout, s_logger); - command.add("-A"); - command.add("-f"); //first ip is source nat ip - command.add("-r", vmName); - command.add("-i", privateIpAddress); - command.add("-a", macAddress); - command.add("-l", publicIpAddress); - - return command.execute(); + String args ="-A"; + args += " -f"; //first ip is source nat ip + args += " -r "; + args += vmName; + args += " -i "; + args += privateIpAddress; + args += " -a "; + args += macAddress; + args += " -l "; + args += publicIpAddress; + return routerProxy("ipassoc.sh", privateIpAddress, args); } + public String assignPublicIpAddress(final String vmName, final String privateIpAddress, final String publicIpAddress, final boolean add, final boolean firstIP, final boolean sourceNat, final String vlanId, final String vlanGateway, final String vlanNetmask, final String vifMacAddress, String guestIp, int nicNum){ - final Script command = new Script(_ipassocPath, _timeout, s_logger); - command.add( privateIpAddress); + String args = ""; if (add) { - command.add("-A"); + args += "-A"; } else { - command.add("-D"); - } - - if (sourceNat) { - command.add("-s"); - } - if (firstIP) { - command.add( "-f"); - + args += "-D"; } String cidrSize = Long.toString(NetUtils.getCidrSize(vlanNetmask)); - command.add( "-l", publicIpAddress + "/" + cidrSize); - String publicNic = "eth" + nicNum; - command.add("-c", publicNic); - - command.add("-g", vlanGateway); - + if (sourceNat) { + args +=" -s"; + } + if (firstIP) { + args += " -f"; + } + args += " -l "; + args += publicIpAddress + "/" + cidrSize; - return command.execute(); + String publicNic = "eth" + nicNum; + args += " -c "; + args += publicNic; + + args +=" -g "; + args += vlanGateway; + return routerProxy("ipassoc.sh", privateIpAddress, args); } private void deletExitingLinkLocalRoutTable(String linkLocalBr) { @@ -801,12 +804,6 @@ public class VirtualRoutingResource implements Manager { value = (String)params.get("ssh.port"); _port = NumbersUtil.parseInt(value, 3922); - _ipassocPath = findScript("ipassoc.sh"); - if (_ipassocPath == null) { - throw new ConfigurationException("Unable to find the ipassoc.sh"); - } - s_logger.info("ipassoc.sh found in " + _ipassocPath); - _publicIpAddress = (String)params.get("public.ip.address"); if (_publicIpAddress != null) { s_logger.warn("Incoming public ip address is overriden. Will always be using the same ip address: " + _publicIpAddress); @@ -837,11 +834,6 @@ public class VirtualRoutingResource implements Manager { throw new ConfigurationException("Unable to find user_data.sh"); } - _getRouterStatusPath = findScript("getRouterStatus.sh"); - if(_getRouterStatusPath == null) { - throw new ConfigurationException("Unable to find getRouterStatus.sh"); - } - _publicEthIf = (String)params.get("public.network.device"); if (_publicEthIf == null) { _publicEthIf = "xenbr1"; @@ -859,14 +851,9 @@ public class VirtualRoutingResource implements Manager { throw new ConfigurationException("Unable to find bumpUpPriority.sh"); } - _l2tpVpnPath = findScript("l2tp_vpn.sh"); - if (_l2tpVpnPath == null) { - throw new ConfigurationException("Unable to find l2tp_vpn.sh"); - } - - _getDomRVersionPath = findScript("getDomRVersion.sh"); - if(_getDomRVersionPath == null) { - throw new ConfigurationException("Unable to find getDomRVersion.sh"); + _routerProxyPath = findScript("routerProxy.sh"); + if (_routerProxyPath == null) { + throw new ConfigurationException("Unable to find routerProxy.sh"); } return true; diff --git a/core/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/core/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index f87fd7d725f..bbb47364c97 100755 --- a/core/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/core/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -1021,7 +1021,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa protected Answer execute(CheckRouterCommand cmd) { if (s_logger.isDebugEnabled()) { s_logger.debug("Executing resource CheckRouterCommand: " + _gson.toJson(cmd)); - s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /root/checkrouter.sh "); + s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /opt/cloud/bin/checkrouter.sh "); } Pair result; @@ -3871,12 +3871,12 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa try { if (s_logger.isTraceEnabled()) { - s_logger.trace("Executing /root/netusage.sh " + args + " on DomR " + privateIpAddress); + s_logger.trace("Executing /opt/cloud/bin/netusage.sh " + args + " on DomR " + privateIpAddress); } VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - Pair result = SshHelper.sshExecute(privateIpAddress, DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(), null, "/root/netusage.sh " + args); + Pair result = SshHelper.sshExecute(privateIpAddress, DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/netusage.sh " + args); if (!result.first()) { return null; diff --git a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 4b8146b3be2..4293e41ad59 100644 --- a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -103,6 +103,8 @@ import com.cloud.agent.api.PingCommand; import com.cloud.agent.api.PingRoutingWithNwGroupsCommand; import com.cloud.agent.api.PingRoutingWithOvsCommand; import com.cloud.agent.api.PingTestCommand; +import com.cloud.agent.api.PlugNicAnswer; +import com.cloud.agent.api.PlugNicCommand; import com.cloud.agent.api.PoolEjectCommand; import com.cloud.agent.api.PrepareForMigrationAnswer; import com.cloud.agent.api.PrepareForMigrationCommand; @@ -113,8 +115,11 @@ import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.RebootRouterCommand; import com.cloud.agent.api.SecurityGroupRuleAnswer; import com.cloud.agent.api.SecurityGroupRulesCmd; +import com.cloud.agent.api.SetSourceNatAnswer; import com.cloud.agent.api.SetupAnswer; import com.cloud.agent.api.SetupCommand; +import com.cloud.agent.api.SetupGuestNetworkAnswer; +import com.cloud.agent.api.SetupGuestNetworkCommand; import com.cloud.agent.api.StartAnswer; import com.cloud.agent.api.StartCommand; import com.cloud.agent.api.StartupCommand; @@ -123,6 +128,8 @@ import com.cloud.agent.api.StartupStorageCommand; import com.cloud.agent.api.StopAnswer; import com.cloud.agent.api.StopCommand; import com.cloud.agent.api.StoragePoolInfo; +import com.cloud.agent.api.UnPlugNicAnswer; +import com.cloud.agent.api.UnPlugNicCommand; import com.cloud.agent.api.UpdateHostPasswordCommand; import com.cloud.agent.api.UpgradeSnapshotCommand; import com.cloud.agent.api.VmStatsEntry; @@ -134,6 +141,7 @@ import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand; import com.cloud.agent.api.routing.DhcpEntryCommand; import com.cloud.agent.api.routing.IpAssocAnswer; import com.cloud.agent.api.routing.IpAssocCommand; +import com.cloud.agent.api.routing.IpAssocVpcCommand; import com.cloud.agent.api.routing.LoadBalancerConfigCommand; import com.cloud.agent.api.routing.NetworkElementCommand; import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand; @@ -142,6 +150,7 @@ import com.cloud.agent.api.routing.SetFirewallRulesAnswer; import com.cloud.agent.api.routing.SetFirewallRulesCommand; import com.cloud.agent.api.routing.SetPortForwardingRulesAnswer; import com.cloud.agent.api.routing.SetPortForwardingRulesCommand; +import com.cloud.agent.api.routing.SetSourceNatCommand; import com.cloud.agent.api.routing.SetStaticNatRulesAnswer; import com.cloud.agent.api.routing.SetStaticNatRulesCommand; import com.cloud.agent.api.routing.VmDataCommand; @@ -512,12 +521,21 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return execute((GetDomRVersionCmd)cmd); } else if (clazz == CheckNetworkCommand.class) { return execute((CheckNetworkCommand) cmd); + } else if (clazz == SetupGuestNetworkCommand.class) { + return execute((SetupGuestNetworkCommand) cmd); + } else if (clazz == PlugNicCommand.class) { + return execute((PlugNicCommand) cmd); + } else if (clazz == UnPlugNicCommand.class) { + return execute((UnPlugNicCommand) cmd); + } else if (clazz == IpAssocVpcCommand.class) { + return execute((IpAssocVpcCommand) cmd); + } else if (clazz == SetSourceNatCommand.class) { + return execute((SetSourceNatCommand) cmd); } else { return Answer.createUnsupportedCommandAnswer(cmd); } } - protected XsLocalNetwork getNativeNetworkForTraffic(Connection conn, TrafficType type, String name) throws XenAPIException, XmlRpcException { if (name != null) { if (s_logger.isDebugEnabled()) { @@ -1334,8 +1352,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe private CheckRouterAnswer execute(CheckRouterCommand cmd) { Connection conn = getConnection(); - String args = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String result = callHostPlugin(conn, "vmops", "checkRouter", "args", args); + String args = "checkrouter.sh " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args); if (result == null || result.isEmpty()) { return new CheckRouterAnswer(cmd, "CheckRouterCommand failed"); } @@ -1344,8 +1362,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe private GetDomRVersionAnswer execute(GetDomRVersionCmd cmd) { Connection conn = getConnection(); - String args = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String result = callHostPlugin(conn, "vmops", "getDomRVersion", "args", args); + String args = "get_template_version.sh " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args); if (result == null || result.isEmpty()) { return new GetDomRVersionAnswer(cmd, "getDomRVersionCmd failed"); } @@ -1573,7 +1591,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe protected synchronized Answer execute(final RemoteAccessVpnCfgCommand cmd) { Connection conn = getConnection(); - String args = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + String args = "vpn_l2tp.sh " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); if (cmd.isCreate()) { args += " -r " + cmd.getIpRange(); args += " -p " + cmd.getPresharedKey(); @@ -1585,7 +1603,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe args += " -d "; args += " -s " + cmd.getVpnServerIp(); } - String result = callHostPlugin(conn, "vmops", "lt2p_vpn", "args", args); + String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args); if (result == null || result.isEmpty()) { return new Answer(cmd, false, "Configure VPN failed"); } @@ -1717,7 +1735,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe throw new InternalErrorException("Failed to find DomR VIF to associate/disassociate IP with."); } - String args = privateIpAddress; + String args = "ipassoc.sh " + privateIpAddress; if (add) { args += " -A "; @@ -1743,7 +1761,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe args += vlanGateway; - String result = callHostPlugin(conn, "vmops", "ipassoc", "args", args); + String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args); if (result == null || result.isEmpty()) { throw new InternalErrorException("Xen plugin \"ipassoc\" failed."); } @@ -6954,7 +6972,138 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return changes; } + /** + * @param cmd + * @return + */ + private UnPlugNicAnswer execute(UnPlugNicCommand cmd) { + Connection conn = getConnection(); + VirtualMachineTO vmto = cmd.getVirtualMachine(); + String vmName = vmto.getName(); + try { + Set vms = VM.getByNameLabel(conn, vmName); + if ( vms == null || vms.isEmpty() ) { + return new UnPlugNicAnswer(cmd, false, "Can not find VM " + vmName); + } + VM vm = vms.iterator().next(); + NicTO nic = cmd.getNic(); + String mac = nic.getMac(); + for ( VIF vif : vm.getVIFs(conn)) { + String lmac = vif.getMAC(conn); + if ( lmac.equals(mac) ) { + vif.unplug(conn); + vif.destroy(conn); + break; + } + } + return new UnPlugNicAnswer(cmd, true, "success"); + } catch (Exception e) { + String msg = " UnPlug Nic failed due to " + e.toString(); + s_logger.warn(msg, e); + return new UnPlugNicAnswer(cmd, false, msg); + } + } + /** + * @param cmd + * @return + */ + private PlugNicAnswer execute(PlugNicCommand cmd) { + Connection conn = getConnection(); + VirtualMachineTO vmto = cmd.getVirtualMachine(); + String vmName = vmto.getName(); + try { + Set vms = VM.getByNameLabel(conn, vmName); + if ( vms == null || vms.isEmpty() ) { + return new PlugNicAnswer(cmd, false, "Can not find VM " + vmName); + } + VM vm = vms.iterator().next(); + NicTO nic = cmd.getNic(); + VIF vif = createVif(conn, vmName, vm, nic); + vif.plug(conn); + return new PlugNicAnswer(cmd, true, "success"); + } catch (Exception e) { + String msg = " Plug Nic failed due to " + e.toString(); + s_logger.warn(msg, e); + return new PlugNicAnswer(cmd, false, msg); + } + } + + /** + * @param cmd + * @return + */ + private SetupGuestNetworkAnswer execute(SetupGuestNetworkCommand cmd) { + Connection conn = getConnection(); + NicTO nic = cmd.getNic(); + String domrIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + String domrGIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP); + String domrName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); + String gw = cmd.getAccessDetail(NetworkElementCommand.GUEST_NETWORK_GATEWAY); + String cidr = Long.toString(NetUtils.getCidrSize(nic.getNetmask()));; + String domainName = cmd.getNetworkDomain(); + String dns = cmd.getDefaultDns1(); + if (dns == null || dns.isEmpty()) { + dns = cmd.getDefaultDns2(); + } else { + String dns2= cmd.getDefaultDns2(); + if ( dns2 != null && !dns2.isEmpty()) { + dns += "," + dns2; + } + } + try { + Set vms = VM.getByNameLabel(conn, domrName); + if ( vms == null || vms.isEmpty() ) { + return new SetupGuestNetworkAnswer(cmd, false, "Can not find VM " + domrName); + } + VM vm = vms.iterator().next(); + String mac = nic.getMac(); + VIF domrVif = null; + for ( VIF vif : vm.getVIFs(conn)) { + String lmac = vif.getMAC(conn); + if ( lmac.equals(mac) ) { + domrVif = vif; + break; + } + } + if ( domrVif == null ) { + return new SetupGuestNetworkAnswer(cmd, false, "Can not find vif with mac " + mac + " for VM " + domrName); + } + + String args = "guestnw.sh " + domrIP + " -C"; + String dev = "eth" + domrVif.getDevice(conn); + args += " -d " + dev; + args += " -i " + domrGIP; + args += " -g " + gw; + args += " -m " + cidr; + if ( dns != null && !dns.isEmpty() ) { + args += " -s " + dns; + } + if ( domainName != null && !domainName.isEmpty() ) { + args += " -e " + domainName; + } + String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args); + if (result == null || result.isEmpty()) { + return new SetupGuestNetworkAnswer(cmd, false, "creating guest network failed due to " + ((result == null)? "null":result)); + } + return new SetupGuestNetworkAnswer(cmd, true, "success"); + } catch (Exception e) { + String msg = " UnPlug Nic failed due to " + e.toString(); + s_logger.warn(msg, e); + return new SetupGuestNetworkAnswer(cmd, false, msg); + } + } + + protected IpAssocAnswer execute(IpAssocVpcCommand cmd) { + //FIXME - add implementation here + return null; + } + + + protected SetSourceNatAnswer execute(SetSourceNatCommand cmd) { + //FIXME - add implementation here + return null; + } } diff --git a/core/src/com/cloud/hypervisor/xen/resource/XenServer56Resource.java b/core/src/com/cloud/hypervisor/xen/resource/XenServer56Resource.java index ff0c5d7b87c..4ad276f99a3 100644 --- a/core/src/com/cloud/hypervisor/xen/resource/XenServer56Resource.java +++ b/core/src/com/cloud/hypervisor/xen/resource/XenServer56Resource.java @@ -142,24 +142,22 @@ public class XenServer56Resource extends CitrixResourceBase { @Override protected String networkUsage(Connection conn, final String privateIpAddress, final String option, final String vif) { - String args = null; + String args = "netusage.sh " + privateIpAddress + " "; if (option.equals("get")) { - args = "-g"; + args += "-g"; } else if (option.equals("create")) { - args = "-c"; + args += "-c"; } else if (option.equals("reset")) { - args = "-r"; + args += "-r"; } else if (option.equals("addVif")) { - args = "-a"; + args += "-a "; args += vif; } else if (option.equals("deleteVif")) { - args = "-d"; + args += "-d "; args += vif; } - args += " -i "; - args += privateIpAddress; - return callHostPlugin(conn, "vmops", "networkUsage", "args", args); + return callHostPlugin(conn, "vmops", "routerProxy", "args", args); } protected NetworkUsageAnswer execute(NetworkUsageCommand cmd) { diff --git a/core/src/com/cloud/vm/DomainRouterVO.java b/core/src/com/cloud/vm/DomainRouterVO.java index 42c14c64e1a..463d68ebb07 100755 --- a/core/src/com/cloud/vm/DomainRouterVO.java +++ b/core/src/com/cloud/vm/DomainRouterVO.java @@ -41,12 +41,6 @@ public class DomainRouterVO extends VMInstanceVO implements VirtualRouter { @Column(name="public_netmask") private String publicNetmask; - - @Column(name="guest_ip_address") - private String guestIpAddress; - - @Column(name="network_id") - long networkId; @Column(name="is_redundant_router") boolean isRedundantRouter; @@ -74,6 +68,9 @@ public class DomainRouterVO extends VMInstanceVO implements VirtualRouter { @Column(name="scripts_version") private String scriptsVersion; + @Column(name="vpc_id") + private Long vpcId; + public DomainRouterVO(long id, long serviceOfferingId, long elementId, @@ -83,20 +80,20 @@ public class DomainRouterVO extends VMInstanceVO implements VirtualRouter { long guestOSId, long domainId, long accountId, - long networkId, boolean isRedundantRouter, int priority, boolean isPriorityBumpUp, RedundantState redundantState, - boolean haEnabled, boolean stopPending) { + boolean haEnabled, + boolean stopPending, Long vpcId) { super(id, serviceOfferingId, name, name, Type.DomainRouter, templateId, hypervisorType, guestOSId, domainId, accountId, haEnabled); this.elementId = elementId; - this.networkId = networkId; this.isRedundantRouter = isRedundantRouter; this.priority = priority; this.redundantState = redundantState; this.isPriorityBumpUp = isPriorityBumpUp; this.stopPending = stopPending; + this.vpcId = vpcId; } public DomainRouterVO(long id, @@ -108,21 +105,21 @@ public class DomainRouterVO extends VMInstanceVO implements VirtualRouter { long guestOSId, long domainId, long accountId, - long networkId, boolean isRedundantRouter, int priority, boolean isPriorityBumpUp, RedundantState redundantState, boolean haEnabled, - boolean stopPending, VirtualMachine.Type vmType) { + boolean stopPending, + VirtualMachine.Type vmType, Long vpcId) { super(id, serviceOfferingId, name, name, vmType, templateId, hypervisorType, guestOSId, domainId, accountId, haEnabled); this.elementId = elementId; - this.networkId = networkId; this.isRedundantRouter = isRedundantRouter; this.priority = priority; this.redundantState = redundantState; this.isPriorityBumpUp = isPriorityBumpUp; this.stopPending = stopPending; + this.vpcId = vpcId; } public long getElementId() { @@ -141,14 +138,6 @@ public class DomainRouterVO extends VMInstanceVO implements VirtualRouter { this.publicNetmask = publicNetmask; } - public long getNetworkId() { - return networkId; - } - - public void setGuestIpAddress(String routerIpAddress) { - this.guestIpAddress = routerIpAddress; - } - @Override public long getDataCenterIdToDeployIn() { return dataCenterIdToDeployIn; @@ -162,11 +151,6 @@ public class DomainRouterVO extends VMInstanceVO implements VirtualRouter { return publicMacAddress; } - @Override - public String getGuestIpAddress() { - return guestIpAddress; - } - protected DomainRouterVO() { super(); } @@ -249,4 +233,14 @@ public class DomainRouterVO extends VMInstanceVO implements VirtualRouter { public void setScriptsVersion(String scriptsVersion) { this.scriptsVersion = scriptsVersion; } + + @Override + public Long getVpcId() { + return vpcId; + } + + @Override + public boolean canPlugNics() { + return true; + } } diff --git a/core/src/com/cloud/vm/VMInstanceVO.java b/core/src/com/cloud/vm/VMInstanceVO.java index f9c57f5931e..2d9eeb6a00d 100644 --- a/core/src/com/cloud/vm/VMInstanceVO.java +++ b/core/src/com/cloud/vm/VMInstanceVO.java @@ -458,5 +458,10 @@ public class VMInstanceVO implements VirtualMachine, FiniteStateObject /etc/network/interfaces << EOF +auto lo $1 +iface lo inet loopback +EOF + setup_interface "0" $ETH0_IP $ETH0_MASK $GW + + echo $NAME > /etc/hostname + echo 'AVAHI_DAEMON_DETECT_LOCAL=0' > /etc/default/avahi-daemon + hostname $NAME + + #Nameserver + sed -i -e "/^nameserver.*$/d" /etc/resolv.conf # remove previous entries + sed -i -e "/^nameserver.*$/d" /etc/dnsmasq-resolv.conf # remove previous entries + if [ -n "$internalNS1" ] + then + echo "nameserver $internalNS1" > /etc/dnsmasq-resolv.conf + echo "nameserver $internalNS1" > /etc/resolv.conf + fi + + if [ -n "$internalNS2" ] + then + echo "nameserver $internalNS2" >> /etc/dnsmasq-resolv.conf + echo "nameserver $internalNS2" >> /etc/resolv.conf + fi + if [ -n "$NS1" ] + then + echo "nameserver $NS1" >> /etc/dnsmasq-resolv.conf + echo "nameserver $NS1" >> /etc/resolv.conf + fi + + if [ -n "$NS2" ] + then + echo "nameserver $NS2" >> /etc/dnsmasq-resolv.conf + echo "nameserver $NS2" >> /etc/resolv.conf + fi + if [ -n "$MGMTNET" -a -n "$LOCAL_GW" ] + then + ip route add $MGMTNET via $LOCAL_GW dev eth1 + fi + + ip route delete default + + + sed -i /gateway/d /etc/hosts + + echo "$ETH0_IP $NAME" >> /etc/hosts + setup_sshd $ETH0_IP + + enable_svc dnsmasq 1 + enable_svc haproxy 1 + enable_svc cloud-passwd-srvr 1 + enable_svc cloud 0 + disable_rpfilter_domR + enable_fwding 1 + chkconfig nfs-common off + cp /etc/iptables/iptables-vpcrouter /etc/iptables/rules + cp /etc/vpcdnsmasq.conf /etc/dnsmasq.conf + cp /etc/cloud-nic.rules /etc/udev/rules.d/cloud-nic.rules + echo "" > /etc/dnsmasq.d/dhcphosts.txt + echo "dhcp-hostsfile=/etc/dhcphosts.txt" > /etc/dnsmasq.d/cloud.conf +} + + + setup_dhcpsrvr() { log_it "Setting up dhcp server system vm" setup_common eth0 eth1 @@ -721,6 +794,10 @@ start() { [ "$NAME" == "" ] && NAME=router setup_router ;; + vpcrouter) + [ "$NAME" == "" ] && NAME=vpcrouter + setup_vpcrouter + ;; dhcpsrvr) [ "$NAME" == "" ] && NAME=dhcpsrvr setup_dhcpsrvr diff --git a/patches/systemvm/debian/config/etc/iptables/iptables-vpcrouter b/patches/systemvm/debian/config/etc/iptables/iptables-vpcrouter new file mode 100644 index 00000000000..c1d0c158cc2 --- /dev/null +++ b/patches/systemvm/debian/config/etc/iptables/iptables-vpcrouter @@ -0,0 +1,25 @@ +*nat +:PREROUTING ACCEPT [0:0] +:POSTROUTING ACCEPT [0:0] +:OUTPUT ACCEPT [0:0] +COMMIT +*filter +:INPUT DROP [0:0] +:FORWARD DROP [0:0] +:OUTPUT ACCEPT [0:0] +-A INPUT -d 224.0.0.18/32 -j ACCEPT +-A INPUT -d 225.0.0.50/32 -j ACCEPT +-A INPUT -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT +-A INPUT -p icmp -j ACCEPT +-A INPUT -i lo -j ACCEPT +-A INPUT -i eth0 -p tcp -m state --state NEW --dport 3922 -j ACCEPT +COMMIT +*mangle +:PREROUTING ACCEPT [0:0] +:INPUT ACCEPT [0:0] +:FORWARD ACCEPT [0:0] +:OUTPUT ACCEPT [0:0] +:POSTROUTING ACCEPT [0:0] +-A PREROUTING -m state --state ESTABLISHED,RELATED -j CONNMARK --restore-mark +-A OUTPUT -p udp --dport bootpc -j CHECKSUM --checksum-fill +COMMIT diff --git a/patches/systemvm/debian/config/etc/vpcdnsmasq.conf b/patches/systemvm/debian/config/etc/vpcdnsmasq.conf new file mode 100644 index 00000000000..3717fc8a80c --- /dev/null +++ b/patches/systemvm/debian/config/etc/vpcdnsmasq.conf @@ -0,0 +1,465 @@ +# Configuration file for dnsmasq. +# +# Format is one option per line, legal options are the same +# as the long options legal on the command line. See +# "/usr/sbin/dnsmasq --help" or "man 8 dnsmasq" for details. + +# The following two options make you a better netizen, since they +# tell dnsmasq to filter out queries which the public DNS cannot +# answer, and which load the servers (especially the root servers) +# uneccessarily. If you have a dial-on-demand link they also stop +# these requests from bringing up the link uneccessarily. + +# Never forward plain names (without a dot or domain part) +domain-needed +# Never forward addresses in the non-routed address spaces. +bogus-priv + + +# Uncomment this to filter useless windows-originated DNS requests +# which can trigger dial-on-demand links needlessly. +# Note that (amongst other things) this blocks all SRV requests, +# so don't use it if you use eg Kerberos. +# This option only affects forwarding, SRV records originating for +# dnsmasq (via srv-host= lines) are not suppressed by it. +#filterwin2k + +# Change this line if you want dns to get its upstream servers from +# somewhere other that /etc/resolv.conf +resolv-file=/etc/dnsmasq-resolv.conf + +# By default, dnsmasq will send queries to any of the upstream +# servers it knows about and tries to favour servers to are known +# to be up. Uncommenting this forces dnsmasq to try each query +# with each server strictly in the order they appear in +# /etc/resolv.conf +#strict-order + +# If you don't want dnsmasq to read /etc/resolv.conf or any other +# file, getting its servers from this file instead (see below), then +# uncomment this. +#no-resolv + +# If you don't want dnsmasq to poll /etc/resolv.conf or other resolv +# files for changes and re-read them then uncomment this. +#no-poll + +# Add other name servers here, with domain specs if they are for +# non-public domains. +#server=/localnet/192.168.0.1 + +# Example of routing PTR queries to nameservers: this will send all +# address->name queries for 192.168.3/24 to nameserver 10.1.2.3 +#server=/3.168.192.in-addr.arpa/10.1.2.3 + +# Add local-only domains here, queries in these domains are answered +# from /etc/hosts or DHCP only. +local=/2.vmops-test.vmops.com/ + +# Add domains which you want to force to an IP address here. +# The example below send any host in doubleclick.net to a local +# webserver. +#address=/doubleclick.net/127.0.0.1 + +# If you want dnsmasq to change uid and gid to something other +# than the default, edit the following lines. +#user= +#group= + +# If you want dnsmasq to listen for DHCP and DNS requests only on +# specified interfaces (and the loopback) give the name of the +# interface (eg eth0) here. +# Repeat the line for more than one interface. +#interface=eth0 + +# Or you can specify which interface _not_ to listen on +except-interface=lo + +# Or which to listen on by address (remember to include 127.0.0.1 if +# you use this.) +#listen-address= +# If you want dnsmasq to provide only DNS service on an interface, +# configure it as shown above, and then use the following line to +# disable DHCP on it. +#no-dhcp-interface=eth1 + +# On systems which support it, dnsmasq binds the wildcard address, +# even when it is listening on only some interfaces. It then discards +# requests that it shouldn't reply to. This has the advantage of +# working even when interfaces come and go and change address. If you +# want dnsmasq to really bind only the interfaces it is listening on, +# uncomment this option. About the only time you may need this is when +# running another nameserver on the same machine. +bind-interfaces + +# If you don't want dnsmasq to read /etc/hosts, uncomment the +# following line. +#no-hosts +# or if you want it to read another file, as well as /etc/hosts, use +# this. +#addn-hosts=/etc/banner_add_hosts + +# Set this (and domain: see below) if you want to have a domain +# automatically added to simple names in a hosts-file. +expand-hosts + +# Set the domain for dnsmasq. this is optional, but if it is set, it +# does the following things. +# 1) Allows DHCP hosts to have fully qualified domain names, as long +# as the domain part matches this setting. +# 2) Sets the "domain" DHCP option thereby potentially setting the +# domain of all systems configured by DHCP +# 3) Provides the domain part for "expand-hosts" +#domain=2.vmops-test.vmops.com + +# Uncomment this to enable the integrated DHCP server, you need +# to supply the range of addresses available for lease and optionally +# a lease time. If you have more than one network, you will need to +# repeat this for each network on which you want to supply DHCP +# service. +#dhcp-range=10.1.1.1,static +#dhcp-range=10.0.0.1,10.255.255.255 +#dhcp-hostsfile=/etc/dhcphosts.txt + +# This is an example of a DHCP range where the netmask is given. This +# is needed for networks we reach the dnsmasq DHCP server via a relay +# agent. If you don't know what a DHCP relay agent is, you probably +# don't need to worry about this. +#dhcp-range=192.168.0.50,192.168.0.150,255.255.255.0,12h + +# This is an example of a DHCP range with a network-id, so that +# some DHCP options may be set only for this network. +#dhcp-range=red,192.168.0.50,192.168.0.150 + +# Supply parameters for specified hosts using DHCP. There are lots +# of valid alternatives, so we will give examples of each. Note that +# IP addresses DO NOT have to be in the range given above, they just +# need to be on the same network. The order of the parameters in these +# do not matter, it's permissble to give name,adddress and MAC in any order + +# Always allocate the host with ethernet address 11:22:33:44:55:66 +# The IP address 192.168.0.60 +#dhcp-host=11:22:33:44:55:66,192.168.0.60 + +# Always set the name of the host with hardware address +# 11:22:33:44:55:66 to be "fred" +#dhcp-host=11:22:33:44:55:66,fred + +# Always give the host with ethernet address 11:22:33:44:55:66 +# the name fred and IP address 192.168.0.60 and lease time 45 minutes +#dhcp-host=11:22:33:44:55:66,fred,192.168.0.60,45m + +# Give the machine which says it's name is "bert" IP address +# 192.168.0.70 and an infinite lease +#dhcp-host=bert,192.168.0.70,infinite + +# Always give the host with client identifier 01:02:02:04 +# the IP address 192.168.0.60 +#dhcp-host=id:01:02:02:04,192.168.0.60 + +# Always give the host with client identifier "marjorie" +# the IP address 192.168.0.60 +#dhcp-host=id:marjorie,192.168.0.60 + +# Enable the address given for "judge" in /etc/hosts +# to be given to a machine presenting the name "judge" when +# it asks for a DHCP lease. +#dhcp-host=judge + +# Never offer DHCP service to a machine whose ethernet +# address is 11:22:33:44:55:66 +#dhcp-host=11:22:33:44:55:66,ignore + +# Ignore any client-id presented by the machine with ethernet +# address 11:22:33:44:55:66. This is useful to prevent a machine +# being treated differently when running under different OS's or +# between PXE boot and OS boot. +#dhcp-host=11:22:33:44:55:66,id:* + +# Send extra options which are tagged as "red" to +# the machine with ethernet address 11:22:33:44:55:66 +#dhcp-host=11:22:33:44:55:66,net:red + +# Send extra options which are tagged as "red" to +# any machine with ethernet address starting 11:22:33: +#dhcp-host=11:22:33:*:*:*,net:red + +# Ignore any clients which are specified in dhcp-host lines +# or /etc/ethers. Equivalent to ISC "deny unkown-clients". +# This relies on the special "known" tag which is set when +# a host is matched. +#dhcp-ignore=#known + +# Send extra options which are tagged as "red" to any machine whose +# DHCP vendorclass string includes the substring "Linux" +#dhcp-vendorclass=red,Linux + +# Send extra options which are tagged as "red" to any machine one +# of whose DHCP userclass strings includes the substring "accounts" +#dhcp-userclass=red,accounts + +# Send extra options which are tagged as "red" to any machine whose +# MAC address matches the pattern. +#dhcp-mac=red,00:60:8C:*:*:* + +# If this line is uncommented, dnsmasq will read /etc/ethers and act +# on the ethernet-address/IP pairs found there just as if they had +# been given as --dhcp-host options. Useful if you keep +# MAC-address/host mappings there for other purposes. +#read-ethers + +# Send options to hosts which ask for a DHCP lease. +# See RFC 2132 for details of available options. +# Common options can be given to dnsmasq by name: +# run "dnsmasq --help dhcp" to get a list. +# Note that all the common settings, such as netmask and +# broadcast address, DNS server and default route, are given +# sane defaults by dnsmasq. You very likely will not need +# any dhcp-options. If you use Windows clients and Samba, there +# are some options which are recommended, they are detailed at the +# end of this section. + +# Override the default route supplied by dnsmasq, which assumes the +# router is the same machine as the one running dnsmasq. +#dhcp-option=3,1.2.3.4 + +# Do the same thing, but using the option name +#dhcp-option=option:router,1.2.3.4 + +# Override the default route supplied by dnsmasq and send no default +# route at all. Note that this only works for the options sent by +# default (1, 3, 6, 12, 28) the same line will send a zero-length option +# for all other option numbers. +#dhcp-option=3 + +# Set the NTP time server addresses to 192.168.0.4 and 10.10.0.5 +#dhcp-option=option:ntp-server,192.168.0.4,10.10.0.5 + +# Set the NTP time server address to be the same machine as +# is running dnsmasq +#dhcp-option=42,0.0.0.0 + +# Set the NIS domain name to "welly" +#dhcp-option=40,welly + +# Set the default time-to-live to 50 +#dhcp-option=23,50 + +# Set the "all subnets are local" flag +#dhcp-option=27,1 + +# Set the domain +dhcp-option=15,"2.vmops-test.vmops.com" + +# Send the etherboot magic flag and then etherboot options (a string). +#dhcp-option=128,e4:45:74:68:00:00 +#dhcp-option=129,NIC=eepro100 + +# Specify an option which will only be sent to the "red" network +# (see dhcp-range for the declaration of the "red" network) +# Note that the net: part must precede the option: part. +#dhcp-option = net:red, option:ntp-server, 192.168.1.1 + +# The following DHCP options set up dnsmasq in the same way as is specified +# for the ISC dhcpcd in +# http://www.samba.org/samba/ftp/docs/textdocs/DHCP-Server-Configuration.txt +# adapted for a typical dnsmasq installation where the host running +# dnsmasq is also the host running samba. +# you may want to uncomment them if you use Windows clients and Samba. +#dhcp-option=19,0 # option ip-forwarding off +#dhcp-option=44,0.0.0.0 # set netbios-over-TCP/IP nameserver(s) aka WINS server(s) +#dhcp-option=45,0.0.0.0 # netbios datagram distribution server +#dhcp-option=46,8 # netbios node type +#dhcp-option=47 # empty netbios scope. + +# Send RFC-3397 DNS domain search DHCP option. WARNING: Your DHCP client +# probably doesn't support this...... +#dhcp-option=option:domain-search,eng.apple.com,marketing.apple.com + +# Send RFC-3442 classless static routes (note the netmask encoding) +#dhcp-option=121,192.168.1.0/24,1.2.3.4,10.0.0.0/8,5.6.7.8 + +# Send vendor-class specific options encapsulated in DHCP option 43. +# The meaning of the options is defined by the vendor-class so +# options are sent only when the client supplied vendor class +# matches the class given here. (A substring match is OK, so "MSFT" +# matches "MSFT" and "MSFT 5.0"). This example sets the +# mtftp address to 0.0.0.0 for PXEClients. +#dhcp-option=vendor:PXEClient,1,0.0.0.0 + +# Send microsoft-specific option to tell windows to release the DHCP lease +# when it shuts down. Note the "i" flag, to tell dnsmasq to send the +# value as a four-byte integer - that's what microsoft wants. See +# http://technet2.microsoft.com/WindowsServer/en/library/a70f1bb7-d2d4-49f0-96d6-4b7414ecfaae1033.mspx?mfr=true +dhcp-option=vendor:MSFT,2,1i + +# Send the Encapsulated-vendor-class ID needed by some configurations of +# Etherboot to allow is to recognise the DHCP server. +#dhcp-option=vendor:Etherboot,60,"Etherboot" + +# Send options to PXELinux. Note that we need to send the options even +# though they don't appear in the parameter request list, so we need +# to use dhcp-option-force here. +# See http://syslinux.zytor.com/pxe.php#special for details. +# Magic number - needed before anything else is recognised +#dhcp-option-force=208,f1:00:74:7e +# Configuration file name +#dhcp-option-force=209,configs/common +# Path prefix +#dhcp-option-force=210,/tftpboot/pxelinux/files/ +# Reboot time. (Note 'i' to send 32-bit value) +#dhcp-option-force=211,30i + +# Set the boot filename for BOOTP. You will only need +# this is you want to boot machines over the network and you will need +# a TFTP server; either dnsmasq's built in TFTP server or an +# external one. (See below for how to enable the TFTP server.) +#dhcp-boot=pxelinux.0 + +# Enable dnsmasq's built-in TFTP server +#enable-tftp + +# Set the root directory for files availble via FTP. +#tftp-root=/var/ftpd + +# Make the TFTP server more secure: with this set, only files owned by +# the user dnsmasq is running as will be send over the net. +#tftp-secure + +# Set the boot file name only when the "red" tag is set. +#dhcp-boot=net:red,pxelinux.red-net + +# An example of dhcp-boot with an external server: the name and IP +# address of the server are given after the filename. +#dhcp-boot=/var/ftpd/pxelinux.0,boothost,192.168.0.3 + +# Set the limit on DHCP leases, the default is 150 +#dhcp-lease-max=150 + +# The DHCP server needs somewhere on disk to keep its lease database. +# This defaults to a sane location, but if you want to change it, use +# the line below. +#dhcp-leasefile=/var/lib/misc/dnsmasq.leases +leasefile-ro + +# Set the DHCP server to authoritative mode. In this mode it will barge in +# and take over the lease for any client which broadcasts on the network, +# whether it has a record of the lease or not. This avoids long timeouts +# when a machine wakes up on a new network. DO NOT enable this if there's +# the slighest chance that you might end up accidentally configuring a DHCP +# server for your campus/company accidentally. The ISC server uses +# the same option, and this URL provides more information: +# http://www.isc.org/index.pl?/sw/dhcp/authoritative.php +#dhcp-authoritative + +# Run an executable when a DHCP lease is created or destroyed. +# The arguments sent to the script are "add" or "del", +# then the MAC address, the IP address and finally the hostname +# if there is one. +#dhcp-script=/bin/echo + +# Set the cachesize here. +#cache-size=150 + +# If you want to disable negative caching, uncomment this. +#no-negcache + +# Normally responses which come form /etc/hosts and the DHCP lease +# file have Time-To-Live set as zero, which conventionally means +# do not cache further. If you are happy to trade lower load on the +# server for potentially stale date, you can set a time-to-live (in +# seconds) here. +#local-ttl= + +# If you want dnsmasq to detect attempts by Verisign to send queries +# to unregistered .com and .net hosts to its sitefinder service and +# have dnsmasq instead return the correct NXDOMAIN response, uncomment +# this line. You can add similar lines to do the same for other +# registries which have implemented wildcard A records. +#bogus-nxdomain=64.94.110.11 + +# If you want to fix up DNS results from upstream servers, use the +# alias option. This only works for IPv4. +# This alias makes a result of 1.2.3.4 appear as 5.6.7.8 +#alias=1.2.3.4,5.6.7.8 +# and this maps 1.2.3.x to 5.6.7.x +#alias=1.2.3.0,5.6.7.0,255.255.255.0 + + +# Change these lines if you want dnsmasq to serve MX records. + +# Return an MX record named "maildomain.com" with target +# servermachine.com and preference 50 +#mx-host=maildomain.com,servermachine.com,50 + +# Set the default target for MX records created using the localmx option. +#mx-target=servermachine.com + +# Return an MX record pointing to the mx-target for all local +# machines. +#localmx + +# Return an MX record pointing to itself for all local machines. +#selfmx + +# Change the following lines if you want dnsmasq to serve SRV +# records. These are useful if you want to serve ldap requests for +# Active Directory and other windows-originated DNS requests. +# See RFC 2782. +# You may add multiple srv-host lines. +# The fields are ,,,, +# If the domain part if missing from the name (so that is just has the +# service and protocol sections) then the domain given by the domain= +# config option is used. (Note that expand-hosts does not need to be +# set for this to work.) + +# A SRV record sending LDAP for the example.com domain to +# ldapserver.example.com port 289 +#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389 + +# A SRV record sending LDAP for the example.com domain to +# ldapserver.example.com port 289 (using domain=) +###domain=example.com +#srv-host=_ldap._tcp,ldapserver.example.com,389 + +# Two SRV records for LDAP, each with different priorities +#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389,1 +#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389,2 + +# A SRV record indicating that there is no LDAP server for the domain +# example.com +#srv-host=_ldap._tcp.example.com + +# The following line shows how to make dnsmasq serve an arbitrary PTR +# record. This is useful for DNS-SD. (Note that the +# domain-name expansion done for SRV records _does_not +# occur for PTR records.) +#ptr-record=_http._tcp.dns-sd-services,"New Employee Page._http._tcp.dns-sd-services" + +# Change the following lines to enable dnsmasq to serve TXT records. +# These are used for things like SPF and zeroconf. (Note that the +# domain-name expansion done for SRV records _does_not +# occur for TXT records.) + +#Example SPF. +#txt-record=example.com,"v=spf1 a -all" + +#Example zeroconf +#txt-record=_http._tcp.example.com,name=value,paper=A4 + + +# For debugging purposes, log each DNS query as it passes through +# dnsmasq. +#log-queries + +# Log lots of extra information about DHCP transactions. +#log-dhcp + +log-facility=/var/log/dnsmasq.log + +# Include a another lot of configuration options. +#conf-file=/etc/dnsmasq.more.conf +conf-dir=/etc/dnsmasq.d + +# Don't reply Windows's periodical DNS request +filterwin2k diff --git a/patches/systemvm/debian/config/opt/cloud/bin/acl.sh b/patches/systemvm/debian/config/opt/cloud/bin/acl.sh new file mode 100755 index 00000000000..525dfe47b0c --- /dev/null +++ b/patches/systemvm/debian/config/opt/cloud/bin/acl.sh @@ -0,0 +1,197 @@ +#!/usr/bin/env bash +# Copyright 2012 Citrix Systems, Inc. Licensed under the +# Apache License, Version 2.0 (the "License"); you may not use this +# file except in compliance with the License. Citrix Systems, Inc. +# reserves all rights not expressly granted by the License. +# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Automatically generated by addcopyright.py at 04/03/2012 +# firewall_rule.sh -- allow some ports / protocols to vm instances +# @VERSION@ + +source /root/func.sh + +lock="biglock" +locked=$(getLockFile $lock) +if [ "$locked" != "1" ] +then + exit 1 +fi + +usage() { + printf "Usage: %s: -a \n" $(basename $0) >&2 + printf "sourcecidrs format: cidr1-cidr2-cidr3-...\n" +} +#set -x +#FIXME: eating up the error code during execution of iptables +acl_remove_backup() { + sudo iptables -F _ACL_INBOUND_$ip 2>/dev/null + sudo iptables -D FORWARD -o $dev -d $gcidr -j _ACL_INBOUND_$ip 2>/dev/null + sudo iptables -X _ACL_INBOUND_$ip 2>/dev/null + sudo iptables -F _ACL_OUTBOUND_$ip 2>/dev/null + sudo iptables -D FORWARD -i $dev -s $gcidr -j _ACL_OUTBOUND_$ip 2>/dev/null + sudo iptables -X _ACL_OUTBOUND_$ip 2>/dev/null +} + +acl_remove() { + sudo iptables -F ACL_INBOUND_$ip 2>/dev/null + sudo iptables -D FORWARD -o $dev -d $gcidr -j ACL_INBOUND_$ip 2>/dev/null + sudo iptables -X ACL_INBOUND_$ip 2>/dev/null + sudo iptables -F ACL_OUTBOUND_$ip 2>/dev/null + sudo iptables -D FORWARD -i $dev -s $gcidr -j ACL_OUTBOUND_$ip 2>/dev/null + sudo iptables -X ACL_OUTBOUND_$ip 2>/dev/null +} + +acl_restore() { + acl_remove + sudo iptables -E _ACL_INBOUND_$ip ACL_INBOUND_$ip 2>/dev/null + sudo iptables -E _ACL_OUTBOUND_$ip ACL_OUTBOUND_$ip 2>/dev/null +} + +acl_save() { + acl_remove_backup + sudo iptables -E ACL_INBOUND_$ip _ACL_INBOUND_$ip 2>/dev/null + sudo iptables -E ACL_OUTBOUND_$ip _ACL_OUTBOUND_$gGW 2>/dev/null +} + +acl_chain_for_guest_network () { + acl_save + # inbound + sudo iptables -E ACL_INBOUND_$ip _ACL_INBOUND_$ip 2>/dev/null + sudo iptables -N ACL_INBOUND_$ip 2>/dev/null + # drop if no rules match (this will be the last rule in the chain) + sudo iptables -A ACL_INBOUND_$ip -j DROP 2>/dev/null + sudo iptables -A FORWARD -o $dev -d $gcidr -j ACL_INBOUND_$ip 2>/dev/null + # outbound + sudo iptables -E ACL_OUTBOUND_$ip _ACL_OUTBOUND_$ip 2>/dev/null + sudo iptables -N ACL_OUTBOUND_$ip 2>/dev/null + sudo iptables -A ACL_OUTBOUND_$ip -j DROP 2>/dev/null + sudo iptables -D FORWARD -i $dev -s $gcidr -j ACL_OUTBOUND_$ip 2>/dev/null +} + + + +acl_entry_for_guest_network() { + local rule=$1 + + local inbound=$(echo $rule | cut -d: -f1) + local prot=$(echo $rules | cut -d: -f2) + local sport=$(echo $rules | cut -d: -f3) + local eport=$(echo $rules | cut -d: -f4) + local cidrs=$(echo $rules | cut -d: -f5 | sed 's/-/ /g') + + logger -t cloud "$(basename $0): enter apply acl rules for guest network: $gcidr, inbound:$inbound:$prot:$sport:$eport:$cidrs" + + # note that rules are inserted after the RELATED,ESTABLISHED rule + # but before the DROP rule + for lcidr in $scidrs + do + [ "$prot" == "reverted" ] && continue; + if [ "$prot" == "icmp" ] + then + typecode="$sport/$eport" + [ "$eport" == "-1" ] && typecode="$sport" + [ "$sport" == "-1" ] && typecode="any" + if [ "$inbound" == "1" ] + then + sudo iptables -I ACL_INBOUND_$gGW -p $prot -s $lcidr \ + --icmp-type $typecode -j ACCEPT + else + sudo iptables -I ACL_OUTBOUND_$gGW -p $prot -d $lcidr \ + --icmp-type $typecode -j ACCEPT + fi + else + if [ "$inbound" == "1" ] + then + sudo iptables -I ACL_INBOUND_$gGW -p $prot -s $lcidr \ + --dport $sport:$eport -j ACCEPT + else + sudo iptables -I ACL_OUTBOUND_$gGW -p $prot -d $lcidr \ + --dport $sport:$eport -j ACCEP`T + fi + result=$? + [ $result -gt 0 ] && + logger -t cloud "Error adding iptables entry for guest network : $gcidr,inbound:$inbound:$prot:$sport:$eport:$cidrs" && + break + done + + logger -t cloud "$(basename $0): exit apply acl rules for guest network : $gcidr" + return $result +} + + +shift +dflag=0 +gflag=0 +aflag=0 +rules="" +rules_list="" +gcidr="" +ip="" +dev="" +while getopts ':d:g:a:' OPTION +do + case $OPTION in + d) dflag=1 + dev="$OPTAGR" + g) gflag=1 + gcidr="$OPTAGR" + a) aflag=1 + rules="$OPTARG" + ;; + ?) usage + unlock_exit 2 $lock $locked + ;; + esac +done + +if [ "$dflag$gflag$aflag" != "!11" ] +then + usage() +fi + + +if [ -n "$rules" == "" ] +then + rules_list=$(echo $rules | cut -d, -f1- --output-delimiter=" ") +fi + +# rule format +# protocal:sport:eport:cidr +#-a tcp:80:80:0.0.0.0/0::tcp:220:220:0.0.0.0/0:,172.16.92.44:tcp:222:222:192.168.10.0/24-75.57.23.0/22-88.100.33.1/32 +# if any entry is reverted , entry will be in the format :reverted:0:0:0 +# example : 172.16.92.44:tcp:80:80:0.0.0.0/0:,172.16.92.44:tcp:220:220:0.0.0.0/0:,200.1.1.2:reverted:0:0:0 + +success=0 +ip=$(echo $gcidr | awk -F'/' '{print $1}') + +acl_chain_for_guest_network + +for r in $rules_list +do + acl_entry_for_guest_network $r + success=$? + if [ $success -gt 0 ] + then + logger -t cloud "$(basename $0): failure to apply fw rules for guest network: $gcidr" + break + else + logger -t cloud "$(basename $0): successful in applying fw rules for guest network: $gcidr" + fi +done + +if [ $success -gt 0 ] +then + logger -t cloud "$(basename $0): restoring from backup for guest network: $gcidr" + acl_restore +else + logger -t cloud "$(basename $0): deleting backup for guest network: $gcidr" + acl_remove_backup +fi +unlock_exit $success $lock $locked + diff --git a/patches/systemvm/debian/config/opt/cloud/bin/cloud-nic.sh b/patches/systemvm/debian/config/opt/cloud/bin/cloud-nic.sh new file mode 100755 index 00000000000..3f80a4ca9b8 --- /dev/null +++ b/patches/systemvm/debian/config/opt/cloud/bin/cloud-nic.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + + +plug_nic() { + sudo iptables -t mangle -A PREROUTING -i $dev -m state --state NEW -j MARK --set-mark $tableNo 2>/dev/null + sudo iptables -t mangle -A PREROUTING -i $dev -m state --state NEW -j CONNMARK --save-mark 2>/dev/null + + sudo echo "$tableNo $tableName" >> /etc/iproute2/rt_tables 2>/dev/null + sudo ip rule add fwmark $tableNo table $tableName 2>/dev/null + sudo ip route flush table $tableName + sudo ip route flush cache +} + + +unplug_nic() { + sudo iptables -t mangle -D PREROUTING -i $dev -m state --state NEW -j MARK --set-mark $tableNo 2>/dev/null + sudo iptables -t mangle -D PREROUTING -i $dev -m state --state NEW -j CONNMARK --save-mark 2>/dev/null + + sudo ip rule del fwmark $tableNo 2>/dev/null + sudo ip route flush table $tableName + sudo sed -i /"$tableNo $tableName"/d /etc/iproute2/rt_tables 2>/dev/null + sudo ip route flush cache +} + +action=$1 +dev=$2 +tableNo=$(echo $dev | awk -F'eth' '{print $2}') +tableName="Table_$dev" + +if [ $action == 'add' ] +then + plug_nic +else + unplug_nic +fi diff --git a/patches/systemvm/debian/config/opt/cloud/bin/guestnw.sh b/patches/systemvm/debian/config/opt/cloud/bin/guestnw.sh new file mode 100755 index 00000000000..c2e3592e51a --- /dev/null +++ b/patches/systemvm/debian/config/opt/cloud/bin/guestnw.sh @@ -0,0 +1,186 @@ +#!/usr/bin/env bash +# Copyright 2012 Citrix Systems, Inc. Licensed under the +# Apache License, Version 2.0 (the "License"); you may not use this +# file except in compliance with the License. Citrix Systems, Inc. +# reserves all rights not expressly granted by the License. +# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Automatically generated by addcopyright.py at 04/03/2012 + +# guestnw.sh -- create/destroy guest network +# @VERSION@ + +source /root/func.sh + +lock="biglock" +locked=$(getLockFile $lock) +if [ "$locked" != "1" ] +then + exit 1 +fi + +usage() { + printf "Usage:\n %s -A -c -g -m -d -r [-f] \n" $(basename $0) >&2 + printf " %s -D -c \n" $(basename $0) >&2 +} + + +setup_dnsmasq() { + logger -t cloud "Setting up dnsmasq for network $ip/$mask " + # setup static + sed -i -e "/^[#]*dhcp-range=interface:$dev/d" /etc/dnsmasq.d/cloud.conf + echo "dhcp-range=interface:$dev,set:interface-$dev,$ip,static" >> /etc/dnsmasq.d/cloud.conf + # setup gateway + sed -i -e "/^[#]*dhcp-option=tag:interface-$dev,option:router.*$/d" /etc/dnsmasq.d/cloud.conf + if [ -n "$gw" ] + then + echo "dhcp-option=tag:interface-$dev,option:router,$gw" >> /etc/dnsmasq.d/cloud.conf + fi + # setup DNS + sed -i -e "/^[#]*dhcp-option=tag:interface-$dev,6.*$/d" /etc/dnsmasq.d/cloud.conf + if [ -n "$DNS" ] + then + echo "dhcp-option=tag:interface-$dev,6,$DNS" >> /etc/dnsmasq.d/cloud.conf + fi + # setup DOMAIN + sed -i -e "/^[#]*dhcp-option=tag:interface-$dev,15.*$/d" /etc/dnsmasq.d/cloud.conf + if [ -n "$DOMAIN" ] + then + echo "dhcp-option=tag:interface-$dev,15,$DOMAIN" >> /etc/dnsmasq.d/cloud.conf + fi + service dnsmasq restart + sleep 1 +} + +desetup_dnsmasq() { + logger -t cloud "Setting up dnsmasq for network $ip/$mask " + + sed -i -e "/^[#]*dhcp-option=tag:interface-$dev,option:router.*$/d" /etc/dnsmasq.d/cloud.conf + sed -i -e "/^[#]*dhcp-option=tag:interface-$dev,6.*$/d" /etc/dnsmasq.d/cloud.conf + sed -i -e "/^[#]*dhcp-range=interface:$dev/d" /etc/dnsmasq.d/cloud.conf + service dnsmasq restart + sleep 1 +} + + +create_guest_network() { + logger -t cloud " $(basename $0): Create network on interface $dev, gateway $gw, network $ip/$mask " + # setup ip configuration + sudo ip addr add dev $dev $ip/$mask + sudo ip link set $dev up + sudo arping -c 3 -I $dev -A -U -s $ip $ip; + # setup rules to allow dhcp/dns request + sudo iptables -A INPUT -i $dev -p udp -m udp --dport 67 -j ACCEPT + sudo iptables -A INPUT -i $dev -p udp -m udp --dport 53 -j ACCEPT + + # create inbound acl chain + if sudo iptables -N ACL_INBOUND_$ip 2>/dev/null + then + logger -t cloud "$(basename $0): create VPC inbound acl chain for network $ip/$mask" + # policy drop + sudo iptables -A ACL_INBOUND_$ip -j DROP >/dev/null + sudo iptables -A FORWARD -o $dev -d $ip/$mask -j ACL_INBOUND_$ip + fi + # create outbound acl chain + if sudo iptables -N ACL_OUTBOUND_$ip 2>/dev/null + then + logger -t cloud "$(basename $0): create VPC outbound acl chain for network $ip/$mask" + sudo iptables -A ACL_OUTBOUND_$ip -j DROP >/dev/null + sudo iptables -A FORWARD -i $dev -s $ip/$mask -j ACL_OUTBOUND_$ip + fi + + setup_dnsmasq +} + +destroy_guest_network() { + logger -t cloud " $(basename $0): Create network on interface $dev, gateway $gw, network $ip/$mask " + # destroy inbound acl chain + sudo iptables -F ACL_INBOUND_$ip 2>/dev/null + sudo iptables -D FORWARD -o $dev -d $ip/$mask -j ACL_INBOUND_$ip 2>/dev/null + sudo iptables -X ACL_INBOUND_$ip 2>/dev/null + # destroy outbound acl chain + sudo iptables -F ACL_OUTBOUND_$ip 2>/dev/null + sudo iptables -D FORWARD -i $dev -s $ip/$mask -j ACL_OUTBOUND_$ip 2>/dev/null + sudo iptables -X ACL_OUTBOUND_$ip 2>/dev/null + + desetup_dnsmasq +} + +#set -x +nflag=0 +dflag= +cflag= +gflag= +Cflag= +Dflag= + +op="" + + +while getopts 'CDn:m:d:i:g:s:e:' OPTION +do + case $OPTION in + C) Cflag=1 + op="-C" + ;; + D) Dflag=1 + op="-D" + ;; + n) nflag=1 + network="$OPTAGR" + ;; + m) mflag=1 + mask="$OPTARG" + ;; + d) dflag=1 + dev="$OPTARG" + ;; + i) iflag=1 + ip="$OPTARG" + ;; + g) gflag=1 + gw="$OPTARG" + ;; + s) sflag=1 + DNS="$OPTARG" + ;; + e) eflag=1 + DOMAIN="$OPTARG" + ;; + ?) usage + unlock_exit 2 $lock $locked + ;; + esac +done + + +if [ "$Cflag$Dflag$dflag" != "11" ] +then + usage + unlock_exit 2 $lock $locked +fi + +if [ "$Cflag" == "1" ] && ["$iflag$gflag$mflag" != "111" ] +then + usage + unlock_exit 2 $lock $locked +fi + + +if [ "$Cflag" == "1" ] +then + create_guest_network +fi + + +if [ "$Dflag" == "1" ] +then + destroy_guest_network +fi + +unlock_exit 0 $lock $locked diff --git a/patches/systemvm/debian/config/root/ipassoc.sh b/patches/systemvm/debian/config/opt/cloud/bin/ipassoc.sh old mode 100644 new mode 100755 similarity index 100% rename from patches/systemvm/debian/config/root/ipassoc.sh rename to patches/systemvm/debian/config/opt/cloud/bin/ipassoc.sh diff --git a/patches/systemvm/debian/config/root/netusage.sh b/patches/systemvm/debian/config/opt/cloud/bin/netusage.sh old mode 100644 new mode 100755 similarity index 100% rename from patches/systemvm/debian/config/root/netusage.sh rename to patches/systemvm/debian/config/opt/cloud/bin/netusage.sh diff --git a/patches/systemvm/debian/config/opt/cloud/bin/vpc_ipassoc.sh b/patches/systemvm/debian/config/opt/cloud/bin/vpc_ipassoc.sh new file mode 100755 index 00000000000..adf8eb4e510 --- /dev/null +++ b/patches/systemvm/debian/config/opt/cloud/bin/vpc_ipassoc.sh @@ -0,0 +1,225 @@ +#!/usr/bin/env bash +# Copyright 2012 Citrix Systems, Inc. Licensed under the +# Apache License, Version 2.0 (the "License"); you may not use this +# file except in compliance with the License. Citrix Systems, Inc. +# reserves all rights not expressly granted by the License. +# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Automatically generated by addcopyright.py at 04/03/2012 + + + + + +# $Id: ipassoc.sh 9804 2010-06-22 18:36:49Z alex $ $HeadURL: svn://svn.lab.vmops.com/repos/vmdev/java/scripts/network/domr/ipassoc.sh $ +# ipassoc.sh -- associate/disassociate a public ip with an instance +# @VERSION@ + +source /root/func.sh + +lock="biglock" +locked=$(getLockFile $lock) +if [ "$locked" != "1" ] +then + exit 1 +fi + +usage() { + printf "Usage:\n %s -A -l -c [-f] \n" $(basename $0) >&2 + printf " %s -D -l -c [-f] \n" $(basename $0) >&2 +} + +remove_routing() { + local pubIp=$1 + logger -t cloud "$(basename $0):Remove routing $pubIp on interface $ethDev" + local ipNoMask=$(echo $pubIp | awk -F'/' '{print $1}') + local mask=$(echo $pubIp | awk -F'/' '{print $2}') + local tableNo=$(echo $ethDev | awk -F'eth' '{print $2}') + + local tableName="Table_$ethDev" + local ethMask=$(ip route list scope link dev $ethDev | awk '{print $1}') + if [ "$ethMask" == "" ] + then +# rules and routes will be deleted for the last ip of the interface. + sudo ip rule delete fwmark $tableNo table $tableName + sudo ip rule delete table $tableName + sudo ip route flush table $tableName + sudo ip route flush cache + logger -t cloud "$(basename $0):Remove routing $pubIp - routes and rules deleted" + fi +} + +# copy eth0,eth1 and the current public interface +copy_routes_from_main() { + local tableName=$1 + +#get the network masks from the main table + local eth0Mask=$(ip route list scope link dev eth0 | awk '{print $1}') + local eth1Mask=$(ip route list scope link dev eth1 | awk '{print $1}') + local ethMask=$(ip route list scope link dev $ethDev | awk '{print $1}') + +# eth0,eth1 and other know routes will be skipped, so as main routing table will decide the route. This will be useful if the interface is down and up. + sudo ip route add throw $eth0Mask table $tableName proto static + sudo ip route add throw $eth1Mask table $tableName proto static + sudo ip route add throw $ethMask table $tableName proto static + return 0; +} + +ip_addr_add() { + local dev="$1" + local ip="$2" +} + +add_routing() { + local pubIp=$1 + logger -t cloud "$(basename $0):Add routing $pubIp on interface $ethDev" + local ipNoMask=$(echo $1 | awk -F'/' '{print $1}') + local mask=$(echo $1 | awk -F'/' '{print $2}') + + local tableName="Table_$ethDev" + local tablePresent=$(grep $tableName /etc/iproute2/rt_tables) + local tableNo=$(echo $ethDev | awk -F'eth' '{print $2}') + if [ "$tablePresent" == "" ] + then + if [ "$tableNo" == ""] + then + return 0; + fi + sudo echo "$tableNo $tableName" >> /etc/iproute2/rt_tables + fi + + copy_routes_from_main $tableName +# NOTE: this entry will be deleted if the interface is down without knowing to Management server, in that case all the outside traffic will be send through main routing table or it will be the first public NIC. + sudo ip route add default via $defaultGwIP table $tableName proto static + sudo ip route flush cache + + local ethMask=$(ip route list scope link dev $ethDev | awk '{print $1}') + local rulePresent=$(ip rule show | grep $ethMask) + if [ "$rulePresent" == "" ] + then +# rules will be added while adding the first ip of the interface + sudo ip rule add from $ethMask table $tableName + sudo ip rule add fwmark $tableNo table $tableName + logger -t cloud "$(basename $0):Add routing $pubIp rules added" + fi + return 0; +} + + +add_an_ip () { + local pubIp=$1 + logger -t cloud "$(basename $0):Adding ip $pubIp on interface $ethDev" + local ipNoMask=$(echo $1 | awk -F'/' '{print $1}') + sudo ip link show $ethDev | grep "state DOWN" > /dev/null + local old_state=$? + + sudo ip addr add dev $dev $ip + if [ $if_keep_state -ne 1 -o $old_state -ne 0 ] + then + sudo ip link set $ethDev up + sudo arping -c 3 -I $ethDev -A -U -s $ipNoMask $ipNoMask; + fi + add_routing $1 + return $? + +} + +remove_an_ip () { + local pubIp=$1 + logger -t cloud "$(basename $0):Removing ip $pubIp on interface $ethDev" + local ipNoMask=$(echo $1 | awk -F'/' '{print $1}') + local mask=$(echo $1 | awk -F'/' '{print $2}') + local existingIpMask=$(sudo ip addr show dev $ethDev | grep inet | awk '{print $2}' | grep -w $ipNoMask) + [ "$existingIpMask" == "" ] && return 0 + remove_snat $1 + local existingMask=$(echo $existingIpMask | awk -F'/' '{print $2}') + if [ "$existingMask" == "32" ] + then + sudo ip addr del dev $ethDev $existingIpMask + result=$? + fi + + if [ "$existingMask" != "32" ] + then + replaceIpMask=`sudo ip addr show dev $ethDev | grep inet | grep -v $existingIpMask | awk '{print $2}' | sort -t/ -k2 -n|tail -1` + sudo ip addr del dev $ethDev $existingIpMask; + if [ -n "$replaceIpMask" ]; then + sudo ip addr del dev $ethDev $replaceIpMask; + replaceIp=`echo $replaceIpMask | awk -F/ '{print $1}'`; + ip_addr_add $ethDev $replaceIp/$existingMask + fi + result=$? + fi + + if [ $result -gt 0 -a $result -ne 2 ] + then + remove_routing $1 + return 1 + fi + remove_routing $1 + return 0 +} + +#set -x +lflag= +cflag= +op="" + + +while getopts 'sfADa:l:c:g:' OPTION +do + case $OPTION in + A) Aflag=1 + op="-A" + ;; + D) Dflag=1 + op="-D" + ;; + l) lflag=1 + publicIp="$OPTARG" + ;; + c) cflag=1 + ethDev="$OPTARG" + ;; + g) gflag=1 + defaultGwIP="$OPTARG" + ;; + ?) usage + unlock_exit 2 $lock $locked + ;; + esac +done + + +if [ "$Aflag$Dflag" != "1" ] +then + usage + unlock_exit 2 $lock $locked +fi + +if [ "$lflag$cflag" != "11" ] +then + usage + unlock_exit 2 $lock $locked +fi + + +if [ "$Aflag" == "1" ] +then + add_an_ip $publicIp && + unlock_exit $? $lock $locked +fi + + +if [ "$Dflag" == "1" ] +then + remove_an_ip $publicIp && + unlock_exit $? $lock $locked +fi + + diff --git a/patches/systemvm/debian/vpn/opt/cloud/bin/vpc_vpn_l2tp.sh b/patches/systemvm/debian/vpn/opt/cloud/bin/vpc_vpn_l2tp.sh new file mode 100755 index 00000000000..574fd69e794 --- /dev/null +++ b/patches/systemvm/debian/vpn/opt/cloud/bin/vpc_vpn_l2tp.sh @@ -0,0 +1,174 @@ +#!/bin/bash +# Copyright 2012 Citrix Systems, Inc. Licensed under the +# Apache License, Version 2.0 (the "License"); you may not use this +# file except in compliance with the License. Citrix Systems, Inc. +# reserves all rights not expressly granted by the License. +# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Automatically generated by addcopyright.py at 04/03/2012 + + + + + + +#set -x +usage() { + printf "Usage:\n" + printf "Create VPN : %s -c -r -l -p -s -D -z < zone cidr> \n" $(basename $0) + printf "Delete VPN : %s -d -l -s -D -z < zone cidr> \n" $(basename $0) + printf "Add VPN User : %s -u \n" $(basename $0) + printf "Remote VPN User: %s -U /etc/ipsec.d/ipsec.any.secrets + sed -i -e "s/^ip range = .*$/ip range = $client_range/" /etc/xl2tpd/xl2tpd.conf + sed -i -e "s/^local ip = .*$/local ip = $local_ip/" /etc/xl2tpd/xl2tpd.conf + + sed -i -e "s/^ms-dns.*$/ms-dns $local_ip/" /etc/ppp/options.xl2tpd + + iptables_ "-D" $public_ip + iptables_ "-I" $public_ip + + ipsec_server "restart" + + ipsec auto --rereadsecrets + ipsec auto --replace L2TP-PSK +} + +destroy_l2tp_ipsec_vpn_server() { + local public_ip=$1 + + ipsec auto --down L2TP-PSK + + iptables_ "-D" $public_ip + + ipsec_server "stop" +} + +remove_l2tp_ipsec_user() { + local u=$1 + sed -i -e "/^$u .*$/d" /etc/ppp/chap-secrets + if [ -x /usr/bin/tdbdump ]; then + pid=$(tdbdump /var/run/pppd2.tdb | grep -w $u | awk -F';' '{print $4}' | awk -F= '{print $2}') + [ "$pid" != "" ] && kill -9 $pid + fi + return 0 +} + +add_l2tp_ipsec_user() { + local u=$1 + local passwd=$2 + + remove_l2tp_ipsec_user $u + echo "$u * $passwd *" >> /etc/ppp/chap-secrets +} + +rflag= +pflag= +lflag= +sflag= +create= +destroy= +useradd= +userdel= + +while getopts 'cdl:p:r:s:u:U:D:z' OPTION +do + case $OPTION in + c) create=1 + ;; + d) destroy=1 + ;; + u) useradd=1 + user_pwd="$OPTARG" + ;; + U) userdel=1 + user="$OPTARG" + ;; + r) rflag=1 + client_range="$OPTARG" + ;; + p) pflag=1 + ipsec_psk="$OPTARG" + ;; + l) lflag=1 + local_ip="$OPTARG" + ;; + s) sflag=1 + server_ip="$OPTARG" + ;; + D) dev="$OPTARG" + ;; + z) zcidr="$OPTARG" + ;; + ?) usage + exit 2 + ;; + esac +done + +[ "$create$destroy" == "11" ] || [ "$create$destroy$useradd$userdel" == "" ] && usage && exit 2 +[ "$create" == "1" ] && [ "$lflag$pflag$rflag$sflag" != "1111" ] && usage && exit 2 + +if [ "$create" == "1" ]; then + create_l2tp_ipsec_vpn_server $ipsec_psk $server_ip $client_range $local_ip + exit $? +fi + +if [ "$destroy" == "1" ]; then + destroy_l2tp_ipsec_vpn_server $server_ip + exit $? +fi + +if [ "$useradd" == "1" ]; then + u=$(echo $user_pwd | awk -F',' '{print $1}') + pwd=$(echo $user_pwd | awk -F',' '{print $2}') + add_l2tp_ipsec_user $u $pwd + exit $? +fi +if [ "$userdel" == "1" ]; then + remove_l2tp_ipsec_user $user + exit $? +fi diff --git a/scripts/network/domr/getDomRVersion.sh b/scripts/network/domr/getDomRVersion.sh deleted file mode 100755 index e11e052f7a1..00000000000 --- a/scripts/network/domr/getDomRVersion.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/bash -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by the License. -# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Automatically generated by addcopyright.py at 04/03/2012 - -usage() { - printf "Usage:\n %s \n" $(basename $0) >&2 - printf " %s \n" $(basename $0) >&2 -} - -cert="/root/.ssh/id_rsa.cloud" -domRIp=$1 -shift - -check_gw() { - ping -c 1 -n -q $1 > /dev/null - if [ $? -gt 0 ] - then - sleep 1 - ping -c 1 -n -q $1 > /dev/null - fi - return $?; -} - - -check_gw "$domRIp" -if [ $? -gt 0 ] -then - exit 1 -fi - -ssh -p 3922 -q -o StrictHostKeyChecking=no -i $cert root@$domRIp "/opt/cloud/bin/get_template_version.sh" -exit $? diff --git a/scripts/network/domr/ipassoc.sh b/scripts/network/domr/ipassoc.sh deleted file mode 100755 index 592b56c97f7..00000000000 --- a/scripts/network/domr/ipassoc.sh +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env bash -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by the License. -# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Automatically generated by addcopyright.py at 04/03/2012 - - - - - -# $Id: ipassoc.sh 9804 2010-06-22 18:36:49Z alex $ $HeadURL: svn://svn.lab.vmops.com/repos/vmdev/java/scripts/network/domr/ipassoc.sh $ -# ipassoc.sh -- associate/disassociate a public ip with an instance -# 2.1.4 -usage() { - printf "Usage:\n %s -A -i -l -r [-f] \n" $(basename $0) >&2 - printf " %s -D -i -l -r [-f] \n" $(basename $0) >&2 -} - -cert="/root/.ssh/id_rsa.cloud" -domRIp=$1 -shift - - -check_gw() { - ping -c 1 -n -q $1 > /dev/null - if [ $? -gt 0 ] - then - sleep 1 - ping -c 1 -n -q $1 > /dev/null - fi - return $?; -} - - -check_gw "$domRIp" -if [ $? -gt 0 ] -then - exit 1 -fi - - -ssh -p 3922 -q -o StrictHostKeyChecking=no -i $cert root@$domRIp "/root/ipassoc.sh $*" -exit $? - diff --git a/scripts/network/domr/l2tp_vpn.sh b/scripts/network/domr/l2tp_vpn.sh deleted file mode 100755 index 87d9a033c0e..00000000000 --- a/scripts/network/domr/l2tp_vpn.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by the License. -# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Automatically generated by addcopyright.py at 04/03/2012 - - - - - -# @VERSION@ - -cert="/root/.ssh/id_rsa.cloud" -domr=$1 -shift -ssh -p 3922 -o StrictHostKeyChecking=no -i $cert root@$domr "/opt/cloud/bin/vpn_l2tp.sh $*" >/dev/null - -exit $? diff --git a/scripts/network/domr/networkUsage.sh b/scripts/network/domr/networkUsage.sh deleted file mode 100755 index 3b1450ad902..00000000000 --- a/scripts/network/domr/networkUsage.sh +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env bash -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by the License. -# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Automatically generated by addcopyright.py at 04/03/2012 - - - - - -# $Id: networkUsage.sh 9879 2010-06-24 02:41:46Z anthony $ $HeadURL: svn://svn.lab.vmops.com/repos/vmdev/java/scripts/vm/hypervisor/xenserver/networkUsage.sh $ -# networkUsage.sh -- create iptable rules to gather network stats -usage() { - printf "Usage: %s -[c|g|r] -i [-[a|d] ]\n" $(basename $0) >&2 -} - -check_gw() { - ping -c 1 -n -q $1 > /dev/null - if [ $? -gt 0 ] - then - sleep 1 - ping -c 1 -n -q $1 > /dev/null - fi - return $?; -} - -cert="/root/.ssh/id_rsa.cloud" - -while getopts 'cgri:a:d:' OPTION -do - case $OPTION in - i) iflag=1 - domRIp="$OPTARG" - ;; - esac -done - -if ! check_gw "$domRIp" -then - printf "Unable to ping the routing domain, exiting\n" >&2 - exit 3 -fi - -ssh -p 3922 -q -o StrictHostKeyChecking=no -i $cert root@$domRIp "/root/netusage.sh $*" -exit $? diff --git a/scripts/network/domr/getRouterStatus.sh b/scripts/network/domr/router_proxy.sh similarity index 82% rename from scripts/network/domr/getRouterStatus.sh rename to scripts/network/domr/router_proxy.sh index 04511b6a6f3..ac0c9cb8df3 100755 --- a/scripts/network/domr/getRouterStatus.sh +++ b/scripts/network/domr/router_proxy.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Copyright 2012 Citrix Systems, Inc. Licensed under the # Apache License, Version 2.0 (the "License"); you may not use this # file except in compliance with the License. Citrix Systems, Inc. @@ -12,14 +12,11 @@ # # Automatically generated by addcopyright.py at 04/03/2012 -usage() { - printf "Usage:\n %s \n" $(basename $0) >&2 - printf " %s \n" $(basename $0) >&2 -} -cert="/root/.ssh/id_rsa.cloud" -domRIp=$1 -shift + +# used as a proxy to call script inside virtual router + +#set -x check_gw() { ping -c 1 -n -q $1 > /dev/null @@ -28,15 +25,30 @@ check_gw() { sleep 1 ping -c 1 -n -q $1 > /dev/null fi - return $?; + if [ $? -gt 0 ] + then + exit 1 + fi } +cert="/root/.ssh/id_rsa.cloud" + +script=$1 +shift + +domRIp=$1 +shift check_gw "$domRIp" -if [ $? -gt 0 ] -then - exit 1 -fi -ssh -p 3922 -q -o StrictHostKeyChecking=no -i $cert root@$domRIp "/root/checkrouter.sh" +ssh -p 3922 -q -o StrictHostKeyChecking=no -i $cert root@$domRIp "/opt/cloud/bin/$script $*" exit $? + + + + + + + + + diff --git a/scripts/vm/hypervisor/xenserver/vmops b/scripts/vm/hypervisor/xenserver/vmops index edef61906b5..52d9e4a4770 100755 --- a/scripts/vm/hypervisor/xenserver/vmops +++ b/scripts/vm/hypervisor/xenserver/vmops @@ -139,21 +139,6 @@ def pingxenserver(session, args): txt = 'success' return txt -@echo -def ipassoc(session, args): - sargs = args['args'] - cmd = sargs.split(' ') - cmd.insert(0, "/opt/xensource/bin/ipassoc.sh") - cmd.insert(0, "/bin/bash") - try: - txt = util.pread2(cmd) - txt = 'success' - except: - util.SMlog(" ip associate failed " ) - txt = '' - - return txt - @echo def vm_data(session, args): router_ip = args.pop('routerIP') @@ -247,21 +232,6 @@ def saveDhcpEntry(session, args): return txt -@echo -def lt2p_vpn(session, args): - sargs = args['args'] - cmd = sargs.split(' ') - cmd.insert(0, "/opt/xensource/bin/l2tp_vpn.sh") - cmd.insert(0, "/bin/bash") - try: - txt = util.pread2(cmd) - txt = 'success' - except: - util.SMlog("l2tp vpn failed " ) - txt = '' - - return txt - @echo def setLinkLocalIP(session, args): brName = args['brName'] @@ -307,6 +277,8 @@ def setLinkLocalIP(session, args): txt = 'success' return txt + + @echo def setFirewallRule(session, args): sargs = args['args'] @@ -322,6 +294,24 @@ def setFirewallRule(session, args): return txt +@echo +def routerProxy(session, args): + sargs = args['args'] + cmd = sargs.split(' ') + cmd.insert(0, "/opt/xensource/bin/router_proxy.sh") + cmd.insert(0, "/bin/bash") + try: + txt = util.pread2(cmd) + if txt is None or len(txt) == 0 : + txt = 'success' + except: + util.SMlog("routerProxy command " + sargs + " failed " ) + txt = '' + + return txt + + + @echo def setLoadBalancerRule(session, args): sargs = args['args'] @@ -368,19 +358,6 @@ def deleteFile(session, args): return txt -@echo -def networkUsage(session, args): - sargs = args['args'] - cmd = sargs.split(' ') - cmd.insert(0, "/opt/xensource/bin/networkUsage.sh") - cmd.insert(0, "/bin/bash") - try: - txt = util.pread2(cmd) - except: - util.SMlog(" network usage error " ) - txt = '' - - return txt def get_private_nic(session, args): vms = session.xenapi.VM.get_all() @@ -1418,20 +1395,6 @@ def network_rules(session, args): except: util.SMlog("Failed to network rule !") -@echo -def checkRouter(session, args): - sargs = args['args'] - cmd = sargs.split(' ') - cmd.insert(0, "/opt/xensource/bin/getRouterStatus.sh") - cmd.insert(0, "/bin/bash") - try: - txt = util.pread2(cmd) - except: - util.SMlog(" check router status fail! ") - txt = '' - - return txt - @echo def bumpUpPriority(session, args): sargs = args['args'] @@ -1447,33 +1410,20 @@ def bumpUpPriority(session, args): return txt -@echo -def getDomRVersion(session, args): - sargs = args['args'] - cmd = sargs.split(' ') - cmd.insert(0, "/opt/xensource/bin/getDomRVersion.sh") - cmd.insert(0, "/bin/bash") - try: - txt = util.pread2(cmd) - except: - util.SMlog(" get domR version fail! ") - txt = '' - - return txt if __name__ == "__main__": XenAPIPlugin.dispatch({"pingtest": pingtest, "setup_iscsi":setup_iscsi, "gethostvmstats": gethostvmstats, "getvncport": getvncport, "getgateway": getgateway, "preparemigration": preparemigration, "setIptables": setIptables, "pingdomr": pingdomr, "pingxenserver": pingxenserver, - "ipassoc": ipassoc, "vm_data": vm_data, "savePassword": savePassword, - "saveDhcpEntry": saveDhcpEntry, "setFirewallRule": setFirewallRule, + "vm_data": vm_data, "savePassword": savePassword, + "saveDhcpEntry": saveDhcpEntry, "setFirewallRule": setFirewallRule, "routerProxy": routerProxy, "setLoadBalancerRule": setLoadBalancerRule, "createFile": createFile, "deleteFile": deleteFile, - "networkUsage": networkUsage, "network_rules":network_rules, + "network_rules":network_rules, "can_bridge_firewall":can_bridge_firewall, "default_network_rules":default_network_rules, "destroy_network_rules_for_vm":destroy_network_rules_for_vm, "default_network_rules_systemvm":default_network_rules_systemvm, "get_rule_logs_for_vms":get_rule_logs_for_vms, - "setLinkLocalIP":setLinkLocalIP, "lt2p_vpn":lt2p_vpn, - "cleanup_rules":cleanup_rules, "checkRouter":checkRouter, - "bumpUpPriority":bumpUpPriority, "getDomRVersion":getDomRVersion, + "setLinkLocalIP":setLinkLocalIP, + "cleanup_rules":cleanup_rules, + "bumpUpPriority":bumpUpPriority, "kill_copy_process":kill_copy_process}) diff --git a/scripts/vm/hypervisor/xenserver/xcpserver/patch b/scripts/vm/hypervisor/xenserver/xcpserver/patch index 74338f76835..7171635be16 100644 --- a/scripts/vm/hypervisor/xenserver/xcpserver/patch +++ b/scripts/vm/hypervisor/xenserver/xcpserver/patch @@ -1,4 +1,5 @@ # This file specifies the files that need +# # to be transferred over to the XenServer. # The format of this file is as follows: # [Name of file]=[source path],[file permission],[destination path] @@ -11,7 +12,6 @@ # If [source path] does not start with '/' or '~', then it is relative path to the location of the patch file. NFSSR.py=/opt/xensource/sm vmops=..,0755,/etc/xapi.d/plugins -ovsgre=..,0755,/etc/xapi.d/plugins ovstunnel=..,0755,/etc/xapi.d/plugins vmopsSnapshot=..,0755,/etc/xapi.d/plugins hostvmstats.py=..,0755,/opt/xensource/sm @@ -23,13 +23,11 @@ make_migratable.sh=..,0755,/opt/xensource/bin setup_iscsi.sh=..,0755,/opt/xensource/bin pingtest.sh=../../..,0755,/opt/xensource/bin dhcp_entry.sh=../../../../network/domr/,0755,/opt/xensource/bin -ipassoc.sh=../../../../network/domr/,0755,/opt/xensource/bin +router_proxy.sh=../../../../network/domr/,0755,/opt/xensource/bin vm_data.sh=../../../../network/domr/,0755,/opt/xensource/bin save_password_to_domr.sh=../../../../network/domr/,0755,/opt/xensource/bin -networkUsage.sh=../../../../network/domr/,0755,/opt/xensource/bin call_firewall.sh=../../../../network/domr/,0755,/opt/xensource/bin call_loadbalancer.sh=../../../../network/domr/,0755,/opt/xensource/bin -l2tp_vpn.sh=../../../../network/domr/,0755,/opt/xensource/bin cloud-setup-bonding.sh=..,0755,/opt/xensource/bin copy_vhd_to_secondarystorage.sh=..,0755,/opt/xensource/bin copy_vhd_from_secondarystorage.sh=..,0755,/opt/xensource/bin diff --git a/scripts/vm/hypervisor/xenserver/xenserver56/patch b/scripts/vm/hypervisor/xenserver/xenserver56/patch index b06f0ea3d3b..37d4290f1c3 100644 --- a/scripts/vm/hypervisor/xenserver/xenserver56/patch +++ b/scripts/vm/hypervisor/xenserver/xenserver56/patch @@ -22,13 +22,11 @@ setup_iscsi.sh=..,0755,/opt/xensource/bin cloud-setup-bonding.sh=..,0755,/opt/xensource/bin pingtest.sh=../../..,0755,/opt/xensource/bin dhcp_entry.sh=../../../../network/domr/,0755,/opt/xensource/bin -ipassoc.sh=../../../../network/domr/,0755,/opt/xensource/bin vm_data.sh=../../../../network/domr/,0755,/opt/xensource/bin save_password_to_domr.sh=../../../../network/domr/,0755,/opt/xensource/bin -networkUsage.sh=../../../../network/domr/,0755,/opt/xensource/bin call_firewall.sh=../../../../network/domr/,0755,/opt/xensource/bin call_loadbalancer.sh=../../../../network/domr/,0755,/opt/xensource/bin -l2tp_vpn.sh=../../../../network/domr/,0755,/opt/xensource/bin +router_proxy.sh=../../../../network/domr/,0755,/opt/xensource/bin copy_vhd_to_secondarystorage.sh=..,0755,/opt/xensource/bin copy_vhd_from_secondarystorage.sh=..,0755,/opt/xensource/bin kill_copy_process.sh=..,0755,/opt/xensource/bin @@ -44,8 +42,6 @@ create_privatetemplate_from_snapshot.sh=..,0755,/opt/xensource/bin upgrade_snapshot.sh=..,0755,/opt/xensource/bin cloud-clean-vlan.sh=..,0755,/opt/xensource/bin cloud-prepare-upgrade.sh=..,0755,/opt/xensource/bin -getRouterStatus.sh=../../../../network/domr/,0755,/opt/xensource/bin bumpUpPriority.sh=../../../../network/domr/,0755,/opt/xensource/bin -getDomRVersion.sh=../../../../network/domr/,0755,/opt/xensource/bin swift=..,0755,/opt/xensource/bin swiftxen=..,0755,/etc/xapi.d/plugins diff --git a/scripts/vm/hypervisor/xenserver/xenserver56fp1/patch b/scripts/vm/hypervisor/xenserver/xenserver56fp1/patch index dbc65817e65..5e6aac1f697 100644 --- a/scripts/vm/hypervisor/xenserver/xenserver56fp1/patch +++ b/scripts/vm/hypervisor/xenserver/xenserver56fp1/patch @@ -21,13 +21,11 @@ make_migratable.sh=..,0755,/opt/xensource/bin setup_iscsi.sh=..,0755,/opt/xensource/bin pingtest.sh=../../..,0755,/opt/xensource/bin dhcp_entry.sh=../../../../network/domr/,0755,/opt/xensource/bin -ipassoc.sh=../../../../network/domr/,0755,/opt/xensource/bin vm_data.sh=../../../../network/domr/,0755,/opt/xensource/bin save_password_to_domr.sh=../../../../network/domr/,0755,/opt/xensource/bin -networkUsage.sh=../../../../network/domr/,0755,/opt/xensource/bin call_firewall.sh=../../../../network/domr/,0755,/opt/xensource/bin call_loadbalancer.sh=../../../../network/domr/,0755,/opt/xensource/bin -l2tp_vpn.sh=../../../../network/domr/,0755,/opt/xensource/bin +router_proxy.sh=../../../../network/domr/,0755,/opt/xensource/bin cloud-setup-bonding.sh=..,0755,/opt/xensource/bin copy_vhd_to_secondarystorage.sh=..,0755,/opt/xensource/bin copy_vhd_from_secondarystorage.sh=..,0755,/opt/xensource/bin @@ -43,8 +41,6 @@ create_privatetemplate_from_snapshot.sh=..,0755,/opt/xensource/bin upgrade_snapshot.sh=..,0755,/opt/xensource/bin cloud-clean-vlan.sh=..,0755,/opt/xensource/bin cloud-prepare-upgrade.sh=..,0755,/opt/xensource/bin -getRouterStatus.sh=../../../../network/domr/,0755,/opt/xensource/bin bumpUpPriority.sh=../../../../network/domr/,0755,/opt/xensource/bin -getDomRVersion.sh=../../../../network/domr/,0755,/opt/xensource/bin swift=..,0755,/opt/xensource/bin swiftxen=..,0755,/etc/xapi.d/plugins diff --git a/scripts/vm/hypervisor/xenserver/xenserver60/patch b/scripts/vm/hypervisor/xenserver/xenserver60/patch index 88d33c8b2df..fdbfbbef050 100644 --- a/scripts/vm/hypervisor/xenserver/xenserver60/patch +++ b/scripts/vm/hypervisor/xenserver/xenserver60/patch @@ -15,7 +15,6 @@ xen-ovs-vif-flows.rules=..,0644,/etc/udev/rules.d ovs-vif-flows.py=..,0755,/etc/xapi.d/plugins cloudstack_plugins.conf=..,0644,/etc/xensource cloudstack_pluginlib.py=..,0755,/etc/xapi.d/plugins -ovsgre=..,0755,/etc/xapi.d/plugins ovstunnel=..,0755,/etc/xapi.d/plugins vmopsSnapshot=..,0755,/etc/xapi.d/plugins hostvmstats.py=..,0755,/opt/xensource/sm @@ -27,13 +26,11 @@ make_migratable.sh=..,0755,/opt/xensource/bin setup_iscsi.sh=..,0755,/opt/xensource/bin pingtest.sh=../../..,0755,/opt/xensource/bin dhcp_entry.sh=../../../../network/domr/,0755,/opt/xensource/bin -ipassoc.sh=../../../../network/domr/,0755,/opt/xensource/bin vm_data.sh=../../../../network/domr/,0755,/opt/xensource/bin save_password_to_domr.sh=../../../../network/domr/,0755,/opt/xensource/bin -networkUsage.sh=../../../../network/domr/,0755,/opt/xensource/bin call_firewall.sh=../../../../network/domr/,0755,/opt/xensource/bin call_loadbalancer.sh=../../../../network/domr/,0755,/opt/xensource/bin -l2tp_vpn.sh=../../../../network/domr/,0755,/opt/xensource/bin +router_proxy.sh=../../../../network/domr/,0755,/opt/xensource/bin cloud-setup-bonding.sh=..,0755,/opt/xensource/bin copy_vhd_to_secondarystorage.sh=..,0755,/opt/xensource/bin copy_vhd_from_secondarystorage.sh=..,0755,/opt/xensource/bin @@ -49,8 +46,6 @@ create_privatetemplate_from_snapshot.sh=..,0755,/opt/xensource/bin upgrade_snapshot.sh=..,0755,/opt/xensource/bin cloud-clean-vlan.sh=..,0755,/opt/xensource/bin cloud-prepare-upgrade.sh=..,0755,/opt/xensource/bin -getRouterStatus.sh=../../../../network/domr/,0755,/opt/xensource/bin bumpUpPriority.sh=../../../../network/domr/,0755,/opt/xensource/bin -getDomRVersion.sh=../../../../network/domr/,0755,/opt/xensource/bin swift=..,0755,/opt/xensource/bin swiftxen=..,0755,/etc/xapi.d/plugins diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index 4db13ad44ba..d77fbe69fd8 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -49,6 +49,7 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.network.IPAddressVO; import com.cloud.network.IpAddress; import com.cloud.network.LoadBalancerVO; +import com.cloud.network.Network; import com.cloud.network.Network.Capability; import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; @@ -68,6 +69,7 @@ import com.cloud.network.security.SecurityGroup; import com.cloud.network.security.SecurityGroupManager; import com.cloud.network.security.SecurityGroupVO; import com.cloud.network.security.dao.SecurityGroupDao; +import com.cloud.network.vpc.VpcManager; import com.cloud.offering.ServiceOffering; import com.cloud.offerings.NetworkOfferingVO; import com.cloud.offerings.dao.NetworkOfferingDao; @@ -191,6 +193,7 @@ public class ApiDBUtils { private static NetworkDomainDao _networkDomainDao; private static HighAvailabilityManager _haMgr; private static TaggedResourceService _taggedResourceService; + private static VpcManager _vpcMgr; static { _ms = (ManagementServer) ComponentLocator.getComponent(ManagementServer.Name); @@ -245,6 +248,7 @@ public class ApiDBUtils { _networkDomainDao = locator.getDao(NetworkDomainDao.class); _haMgr = locator.getManager(HighAvailabilityManager.class); _taggedResourceService = locator.getManager(TaggedResourceService.class); + _vpcMgr = locator.getManager(VpcManager.class); // Note: stats collector should already have been initialized by this time, otherwise a null instance is returned _statsCollector = StatsCollector.getInstance(); @@ -757,4 +761,11 @@ public class ApiDBUtils { return _taggedResourceService.getUuid(resourceId, resourceType); } + public static Map> listVpcOffServices(long vpcOffId) { + return _vpcMgr.getVpcOffSvcProvidersMap(vpcOffId); + } + + public static List listVpcNetworks(long vpcId) { + return _networkMgr.listNetworksByVpc(vpcId); + } } diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 70db3b30ba7..bfedb2db7f8 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -92,6 +92,8 @@ import com.cloud.api.response.UserVmResponse; import com.cloud.api.response.VirtualRouterProviderResponse; import com.cloud.api.response.VlanIpRangeResponse; import com.cloud.api.response.VolumeResponse; +import com.cloud.api.response.VpcOfferingResponse; +import com.cloud.api.response.VpcResponse; import com.cloud.api.response.VpnUsersResponse; import com.cloud.api.response.ZoneResponse; import com.cloud.async.AsyncJob; @@ -144,6 +146,8 @@ import com.cloud.network.security.SecurityGroupRules; import com.cloud.network.security.SecurityGroupVO; import com.cloud.network.security.SecurityRule; import com.cloud.network.security.SecurityRule.SecurityRuleType; +import com.cloud.network.vpc.Vpc; +import com.cloud.network.vpc.VpcOffering; import com.cloud.offering.DiskOffering; import com.cloud.offering.NetworkOffering; import com.cloud.offering.ServiceOffering; @@ -729,30 +733,30 @@ public class ApiResponseHelper implements ResponseGenerator { } @Override - public IPAddressResponse createIPAddressResponse(IpAddress ipAddress) { - VlanVO vlan = ApiDBUtils.findVlanById(ipAddress.getVlanId()); + public IPAddressResponse createIPAddressResponse(IpAddress ipAddr) { + VlanVO vlan = ApiDBUtils.findVlanById(ipAddr.getVlanId()); boolean forVirtualNetworks = vlan.getVlanType().equals(VlanType.VirtualNetwork); - long zoneId = ipAddress.getDataCenterId(); + long zoneId = ipAddr.getDataCenterId(); IPAddressResponse ipResponse = new IPAddressResponse(); - ipResponse.setId(ipAddress.getId()); - ipResponse.setIpAddress(ipAddress.getAddress().toString()); - if (ipAddress.getAllocatedTime() != null) { - ipResponse.setAllocated(ipAddress.getAllocatedTime()); + ipResponse.setId(ipAddr.getId()); + ipResponse.setIpAddress(ipAddr.getAddress().toString()); + if (ipAddr.getAllocatedTime() != null) { + ipResponse.setAllocated(ipAddr.getAllocatedTime()); } ipResponse.setZoneId(zoneId); - ipResponse.setZoneName(ApiDBUtils.findZoneById(ipAddress.getDataCenterId()).getName()); - ipResponse.setSourceNat(ipAddress.isSourceNat()); - ipResponse.setIsSystem(ipAddress.getSystem()); + ipResponse.setZoneName(ApiDBUtils.findZoneById(ipAddr.getDataCenterId()).getName()); + ipResponse.setSourceNat(ipAddr.isSourceNat()); + ipResponse.setIsSystem(ipAddr.getSystem()); // get account information - populateOwner(ipResponse, ipAddress); + populateOwner(ipResponse, ipAddr); ipResponse.setForVirtualNetwork(forVirtualNetworks); - ipResponse.setStaticNat(ipAddress.isOneToOneNat()); + ipResponse.setStaticNat(ipAddr.isOneToOneNat()); - if (ipAddress.getAssociatedWithVmId() != null) { - UserVm vm = ApiDBUtils.findUserVmById(ipAddress.getAssociatedWithVmId()); + if (ipAddr.getAssociatedWithVmId() != null) { + UserVm vm = ApiDBUtils.findUserVmById(ipAddr.getAssociatedWithVmId()); ipResponse.setVirtualMachineId(vm.getId()); ipResponse.setVirtualMachineName(vm.getHostName()); if (vm.getDisplayName() != null) { @@ -762,11 +766,12 @@ public class ApiResponseHelper implements ResponseGenerator { } } - ipResponse.setAssociatedNetworkId(ipAddress.getAssociatedWithNetworkId()); + ipResponse.setAssociatedNetworkId(ipAddr.getAssociatedWithNetworkId()); + ipResponse.setVpcId(ipAddr.getVpcId()); // Network id the ip is associated withif associated networkId is null, try to get this information from vlan - Long associatedNetworkId = ipAddress.getAssociatedWithNetworkId(); - Long vlanNetworkId = ApiDBUtils.getVlanNetworkId(ipAddress.getVlanId()); + Long associatedNetworkId = ipAddr.getAssociatedWithNetworkId(); + Long vlanNetworkId = ApiDBUtils.getVlanNetworkId(ipAddr.getVlanId()); if (associatedNetworkId == null) { associatedNetworkId = vlanNetworkId; } @@ -782,18 +787,18 @@ public class ApiResponseHelper implements ResponseGenerator { } ipResponse.setNetworkId(networkId); - ipResponse.setState(ipAddress.getState().toString()); - ipResponse.setPhysicalNetworkId(ipAddress.getPhysicalNetworkId()); + ipResponse.setState(ipAddr.getState().toString()); + ipResponse.setPhysicalNetworkId(ipAddr.getPhysicalNetworkId()); // show this info to admin only Account account = UserContext.current().getCaller(); if ((account == null) || account.getType() == Account.ACCOUNT_TYPE_ADMIN) { - ipResponse.setVlanId(ipAddress.getVlanId()); - ipResponse.setVlanName(ApiDBUtils.findVlanById(ipAddress.getVlanId()).getVlanTag()); + ipResponse.setVlanId(ipAddr.getVlanId()); + ipResponse.setVlanName(ApiDBUtils.findVlanById(ipAddr.getVlanId()).getVlanTag()); } - if (ipAddress.getSystem()) { - if (ipAddress.isOneToOneNat()) { + if (ipAddr.getSystem()) { + if (ipAddr.isOneToOneNat()) { ipResponse.setPurpose(IpAddress.Purpose.StaticNat.toString()); } else { ipResponse.setPurpose(IpAddress.Purpose.Lb.toString()); @@ -1659,6 +1664,8 @@ public class ApiResponseHelper implements ResponseGenerator { routerResponse.setDns2(zone.getDns2()); } + routerResponse.setVpcId(router.getVpcId()); + routerResponse.setObjectName("domainrouter"); return routerResponse; } @@ -2888,6 +2895,7 @@ public class ApiResponseHelper implements ResponseGenerator { } response.setSpecifyIpRanges(network.getSpecifyIpRanges()); + response.setVpcId(network.getVpcId()); response.setObjectName("network"); return response; @@ -3438,4 +3446,88 @@ public class ApiResponseHelper implements ResponseGenerator { } + @Override + public VpcOfferingResponse createVpcOfferingResponse(VpcOffering offering) { + VpcOfferingResponse response = new VpcOfferingResponse(); + response.setId(offering.getId()); + response.setName(offering.getName()); + response.setDisplayText(offering.getDisplayText()); + response.setIsDefault(offering.isDefault()); + response.setState(offering.getState().name()); + + Map> serviceProviderMap = ApiDBUtils.listVpcOffServices(offering.getId()); + List serviceResponses = new ArrayList(); + for (Service service : serviceProviderMap.keySet()) { + ServiceResponse svcRsp = new ServiceResponse(); + // skip gateway service + if (service == Service.Gateway) { + continue; + } + svcRsp.setName(service.getName()); + List providers = new ArrayList(); + for (Provider provider : serviceProviderMap.get(service)) { + if (provider != null) { + ProviderResponse providerRsp = new ProviderResponse(); + providerRsp.setName(provider.getName()); + providers.add(providerRsp); + } + } + svcRsp.setProviders(providers); + + serviceResponses.add(svcRsp); + } + response.setServices(serviceResponses); + response.setObjectName("vpcoffering"); + return response; + } + + + @Override + public VpcResponse createVpcResponse(Vpc vpc) { + VpcResponse response = new VpcResponse(); + response.setId(vpc.getId()); + response.setName(vpc.getName()); + response.setDisplayText(vpc.getDisplayText()); + response.setState(vpc.getState().name()); + response.setVpcOfferingId(vpc.getVpcOfferingId()); + response.setCidr(vpc.getCidr()); + response.setZoneId(vpc.getZoneId()); + response.setRestartRequired(vpc.isRestartRequired()); + response.setNetworkDomain(vpc.getNetworkDomain()); + + Map> serviceProviderMap = ApiDBUtils.listVpcOffServices(vpc.getVpcOfferingId()); + List serviceResponses = new ArrayList(); + for (Service service : serviceProviderMap.keySet()) { + ServiceResponse svcRsp = new ServiceResponse(); + // skip gateway service + if (service == Service.Gateway) { + continue; + } + svcRsp.setName(service.getName()); + List providers = new ArrayList(); + for (Provider provider : serviceProviderMap.get(service)) { + if (provider != null) { + ProviderResponse providerRsp = new ProviderResponse(); + providerRsp.setName(provider.getName()); + providers.add(providerRsp); + } + } + svcRsp.setProviders(providers); + + serviceResponses.add(svcRsp); + } + + List networkResponses = new ArrayList(); + List networks = ApiDBUtils.listVpcNetworks(vpc.getId()); + for (Network network : networks) { + NetworkResponse ntwkRsp = createNetworkResponse(network); + networkResponses.add(ntwkRsp); + } + + response.setNetworks(networkResponses); + response.setServices(serviceResponses); + response.setObjectName("vpcoffering"); + return response; + } + } diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java index d13e67ae301..ebb914c075d 100755 --- a/server/src/com/cloud/api/ApiServer.java +++ b/server/src/com/cloud/api/ApiServer.java @@ -500,7 +500,8 @@ public class ApiServer implements HttpRequestHandler { asyncCmd.setStartEventId(startEventId); // save the scheduled event - Long eventId = EventUtils.saveScheduledEvent((callerUserId == null) ? User.UID_SYSTEM : callerUserId, asyncCmd.getEntityOwnerId(), asyncCmd.getEventType(), asyncCmd.getEventDescription(), + Long eventId = EventUtils.saveScheduledEvent((callerUserId == null) ? User.UID_SYSTEM : callerUserId, + asyncCmd.getEntityOwnerId(), asyncCmd.getEventType(), asyncCmd.getEventDescription(), startEventId); if (startEventId == 0) { // There was no create event before, set current event id as start eventId diff --git a/server/src/com/cloud/configuration/ConfigurationManager.java b/server/src/com/cloud/configuration/ConfigurationManager.java index 85cdf34cf24..29de7bf4ba2 100644 --- a/server/src/com/cloud/configuration/ConfigurationManager.java +++ b/server/src/com/cloud/configuration/ConfigurationManager.java @@ -164,11 +164,12 @@ public interface ConfigurationManager extends ConfigurationService, Manager { /** * Creates a new network offering - * * @param name * @param displayText * @param trafficType * @param tags + * @param specifyVlan + * ; * @param networkRate * TODO * @param serviceProviderMap @@ -180,19 +181,18 @@ public interface ConfigurationManager extends ConfigurationService, Manager { * @param systemOnly * TODO * @param serviceOfferingId + * @param conserveMode + * ; * @param specifyIpRanges * TODO * @param id - * @param specifyVlan - * ; - * @param conserveMode - * ; + * * @return network offering object */ - NetworkOfferingVO createNetworkOffering(long userId, String name, String displayText, TrafficType trafficType, String tags, boolean specifyVlan, Availability availability, Integer networkRate, - Map> serviceProviderMap, boolean isDefault, Network.GuestType type, boolean systemOnly, Long serviceOfferingId, boolean conserveMode, - Map> serviceCapabilityMap, boolean specifyIpRanges); + NetworkOfferingVO createNetworkOffering(String name, String displayText, TrafficType trafficType, String tags, boolean specifyVlan, Availability availability, Integer networkRate, Map> serviceProviderMap, + boolean isDefault, Network.GuestType type, boolean systemOnly, Long serviceOfferingId, boolean conserveMode, Map> serviceCapabilityMap, + boolean specifyIpRanges); Vlan createVlanAndPublicIpRange(long zoneId, long networkId, long physicalNetworkId, boolean forVirtualNetwork, Long podId, String startIP, String endIP, String vlanGateway, String vlanNetmask, String vlanId, Account vlanOwner) throws InsufficientCapacityException, ConcurrentOperationException, InvalidParameterValueException; @@ -226,4 +226,10 @@ public interface ConfigurationManager extends ConfigurationService, Manager { AllocationState findClusterAllocationState(ClusterVO cluster); + /** + * @param tags + * @return + */ + String cleanupTags(String tags); + } diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 09d53139d34..575a3f766c5 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -1608,11 +1608,14 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura } else { continue; } + } else if (offering.getTrafficType() == TrafficType.Guest) { + continue; } userNetwork.setBroadcastDomainType(broadcastDomainType); userNetwork.setNetworkDomain(networkDomain); - _networkMgr.setupNetwork(systemAccount, offering, userNetwork, plan, null, null, false, Domain.ROOT_DOMAIN, null, null); + _networkMgr.setupNetwork(systemAccount, offering, userNetwork, plan, null, null, false, + Domain.ROOT_DOMAIN, null, null, null); } } } @@ -2476,7 +2479,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura " as ip " + ip + " belonging to the range has firewall rules applied. Cleanup the rules first"); } //release public ip address here - success = success && _networkMgr.releasePublicIpAddress(ip.getId(), userId, caller); + success = success && _networkMgr.disassociatePublicIpAddress(ip.getId(), userId, caller); } if (!success) { s_logger.warn("Some ip addresses failed to be released as a part of vlan " + vlanDbId + " removal"); @@ -2531,7 +2534,8 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura return tags; } - private String cleanupTags(String tags) { + @Override + public String cleanupTags(String tags) { if (tags != null) { String[] tokens = tags.split(","); StringBuilder t = new StringBuilder(); @@ -2864,7 +2868,6 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura @Override @ActionEvent(eventType = EventTypes.EVENT_NETWORK_OFFERING_CREATE, eventDescription = "creating network offering") public NetworkOffering createNetworkOffering(CreateNetworkOfferingCmd cmd) { - Long userId = UserContext.current().getCallerUserId(); String name = cmd.getNetworkOfferingName(); String displayText = cmd.getDisplayText(); String tags = cmd.getTags(); @@ -2971,7 +2974,8 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura Set providers = new HashSet(); // in Acton, don't allow to specify more than 1 provider per service if (svcPrv.get(serviceStr) != null && svcPrv.get(serviceStr).size() > 1) { - throw new InvalidParameterValueException("In the current release only one provider can be specified for the service"); + throw new InvalidParameterValueException("In the current release only one provider can be " + + "specified for the service"); } for (String prvNameStr : svcPrv.get(serviceStr)) { // check if provider is supported @@ -3002,7 +3006,8 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura } serviceProviderMap.put(service, providers); } else { - throw new InvalidParameterValueException("Service " + serviceStr + " is not enabled for the network offering, can't add a provider to it"); + throw new InvalidParameterValueException("Service " + serviceStr + " is not enabled for the network " + + "offering, can't add a provider to it"); } } } @@ -3036,8 +3041,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura serviceCapabilityMap.put(Service.SourceNat, sourceNatServiceCapabilityMap); serviceCapabilityMap.put(Service.StaticNat, staticNatServiceCapabilityMap); - // if Firewall service is missing, and Juniper is a provider for any other service or VR is StaticNat/PF provider, add Firewall - // service/provider combination + // if Firewall service is missing, add Firewall service/provider combination if (firewallProvider != null) { s_logger.debug("Adding Firewall service with provider " + firewallProvider.getName()); Set firewallProviderSet = new HashSet(); @@ -3045,8 +3049,8 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura serviceProviderMap.put(Service.Firewall, firewallProviderSet); } - return createNetworkOffering(userId, name, displayText, trafficType, tags, specifyVlan, availability, networkRate, serviceProviderMap, false, guestType, - false, serviceOfferingId, conserveMode, serviceCapabilityMap, specifyIpRanges); + return createNetworkOffering(name, displayText, trafficType, tags, specifyVlan, availability, networkRate, serviceProviderMap, false, guestType, false, + serviceOfferingId, conserveMode, serviceCapabilityMap, specifyIpRanges); } void validateLoadBalancerServiceCapabilities(Map lbServiceCapabilityMap) { @@ -3126,9 +3130,9 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura @Override @DB - public NetworkOfferingVO createNetworkOffering(long userId, String name, String displayText, TrafficType trafficType, String tags, boolean specifyVlan, Availability availability, - Integer networkRate, Map> serviceProviderMap, boolean isDefault, Network.GuestType type, boolean systemOnly, - Long serviceOfferingId, boolean conserveMode, Map> serviceCapabilityMap, boolean specifyIpRanges) { + public NetworkOfferingVO createNetworkOffering(String name, String displayText, TrafficType trafficType, String tags, boolean specifyVlan, Availability availability, Integer networkRate, + Map> serviceProviderMap, boolean isDefault, Network.GuestType type, boolean systemOnly, Long serviceOfferingId, + boolean conserveMode, Map> serviceCapabilityMap, boolean specifyIpRanges) { String multicastRateStr = _configDao.getValue("multicast.throttling.rate"); int multicastRate = ((multicastRateStr == null) ? 10 : Integer.parseInt(multicastRateStr)); @@ -3190,13 +3194,15 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura if ((sourceNatServiceCapabilityMap != null) && (!sourceNatServiceCapabilityMap.isEmpty())) { String sourceNatType = sourceNatServiceCapabilityMap.get(Capability.SupportedSourceNatTypes); if (sourceNatType != null) { - _networkMgr.checkCapabilityForProvider(serviceProviderMap.get(Service.SourceNat), Service.SourceNat, Capability.SupportedSourceNatTypes, sourceNatType); + _networkMgr.checkCapabilityForProvider(serviceProviderMap.get(Service.SourceNat), Service.SourceNat, + Capability.SupportedSourceNatTypes, sourceNatType); sharedSourceNat = sourceNatType.contains("perzone"); } String param = sourceNatServiceCapabilityMap.get(Capability.RedundantRouter); if (param != null) { - _networkMgr.checkCapabilityForProvider(serviceProviderMap.get(Service.SourceNat), Service.SourceNat, Capability.RedundantRouter, param); + _networkMgr.checkCapabilityForProvider(serviceProviderMap.get(Service.SourceNat), Service.SourceNat, + Capability.RedundantRouter, param); redundantRouter = param.contains("true"); } } @@ -3210,7 +3216,8 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura } } - NetworkOfferingVO offering = new NetworkOfferingVO(name, displayText, trafficType, systemOnly, specifyVlan, networkRate, multicastRate, isDefault, availability, tags, type, conserveMode, dedicatedLb, + NetworkOfferingVO offering = new NetworkOfferingVO(name, displayText, trafficType, systemOnly, specifyVlan, + networkRate, multicastRate, isDefault, availability, tags, type, conserveMode, dedicatedLb, sharedSourceNat, redundantRouter, elasticIp, elasticLb, specifyIpRanges); if (serviceOfferingId != null) { @@ -3549,19 +3556,23 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura } } if (availability == null) { - throw new InvalidParameterValueException("Invalid value for Availability. Supported types: " + Availability.Required + ", " + Availability.Optional); + throw new InvalidParameterValueException("Invalid value for Availability. Supported types: " + + Availability.Required + ", " + Availability.Optional); } else { if (availability == NetworkOffering.Availability.Required) { - boolean canOffBeRequired = (offeringToUpdate.getGuestType() == GuestType.Isolated && _networkMgr.areServicesSupportedByNetworkOffering(offeringToUpdate.getId(), Service.SourceNat)); + boolean canOffBeRequired = (offeringToUpdate.getGuestType() == GuestType.Isolated + && _networkMgr.areServicesSupportedByNetworkOffering(offeringToUpdate.getId(), Service.SourceNat)); if (!canOffBeRequired) { - throw new InvalidParameterValueException("Availability can be " + NetworkOffering.Availability.Required + " only for networkOfferings of type " + GuestType.Isolated + " and with " + throw new InvalidParameterValueException("Availability can be " + + NetworkOffering.Availability.Required + " only for networkOfferings of type " + GuestType.Isolated + " and with " + Service.SourceNat.getName() + " enabled"); } // only one network offering in the system can be Required List offerings = _networkOfferingDao.listByAvailability(Availability.Required, false); if (!offerings.isEmpty() && offerings.get(0).getId() != offeringToUpdate.getId()) { - throw new InvalidParameterValueException("System already has network offering id=" + offerings.get(0).getId() + " with availability " + Availability.Required); + throw new InvalidParameterValueException("System already has network offering id=" + + offerings.get(0).getId() + " with availability " + Availability.Required); } } offering.setAvailability(availability); @@ -3576,7 +3587,8 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura } @Override - @ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_MARK_DEFAULT_ZONE, eventDescription = "Marking account with the default zone", async=true) + @ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_MARK_DEFAULT_ZONE, eventDescription = "Marking account with the " + + "default zone", async=true) public AccountVO markDefaultZone(String accountName, long domainId, long defaultZoneId) { // Check if the account exists diff --git a/server/src/com/cloud/configuration/DefaultComponentLibrary.java b/server/src/com/cloud/configuration/DefaultComponentLibrary.java index 16cc1324f9f..814aea33f96 100755 --- a/server/src/com/cloud/configuration/DefaultComponentLibrary.java +++ b/server/src/com/cloud/configuration/DefaultComponentLibrary.java @@ -112,6 +112,7 @@ import com.cloud.network.ovs.OvsTunnelManagerImpl; import com.cloud.network.ovs.dao.OvsTunnelInterfaceDaoImpl; import com.cloud.network.ovs.dao.OvsTunnelNetworkDaoImpl; import com.cloud.network.router.VirtualNetworkApplianceManagerImpl; +import com.cloud.network.router.VpcVirtualNetworkApplianceManagerImpl; import com.cloud.network.rules.RulesManagerImpl; import com.cloud.network.rules.dao.PortForwardingRulesDaoImpl; import com.cloud.network.security.SecurityGroupManagerImpl2; @@ -121,6 +122,11 @@ import com.cloud.network.security.dao.SecurityGroupRulesDaoImpl; import com.cloud.network.security.dao.SecurityGroupVMMapDaoImpl; import com.cloud.network.security.dao.SecurityGroupWorkDaoImpl; import com.cloud.network.security.dao.VmRulesetLogDaoImpl; +import com.cloud.network.vpc.VpcManagerImpl; +import com.cloud.network.vpc.Dao.PrivateIpDaoImpl; +import com.cloud.network.vpc.Dao.VpcDaoImpl; +import com.cloud.network.vpc.Dao.VpcOfferingDaoImpl; +import com.cloud.network.vpc.Dao.VpcOfferingServiceMapDaoImpl; import com.cloud.network.vpn.RemoteAccessVpnManagerImpl; import com.cloud.offerings.dao.NetworkOfferingDaoImpl; import com.cloud.offerings.dao.NetworkOfferingServiceMapDaoImpl; @@ -330,6 +336,10 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com addDao("StorageNetworkIpAddressDao", StorageNetworkIpAddressDaoImpl.class); addDao("StorageNetworkIpRangeDao", StorageNetworkIpRangeDaoImpl.class); addDao("TagsDao", ResourceTagsDaoImpl.class); + addDao("VpcDao", VpcDaoImpl.class); + addDao("VpcOfferingDao", VpcOfferingDaoImpl.class); + addDao("VpcOfferingServiceMapDao", VpcOfferingServiceMapDaoImpl.class); + addDao("PrivateIpDao", PrivateIpDaoImpl.class); } @Override @@ -387,6 +397,8 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com addManager("ExternalLoadBalancerUsageManager", ExternalLoadBalancerUsageManagerImpl.class); addManager("HA Manager", HighAvailabilityManagerImpl.class); addManager("TaggedResourcesManager", TaggedResourceManagerImpl.class); + addManager("VPC Manager", VpcManagerImpl.class); + addManager("VpcVirtualRouterManager", VpcVirtualNetworkApplianceManagerImpl.class); } @Override diff --git a/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java b/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java index 72fb87a008d..983e90932c3 100755 --- a/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java +++ b/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java @@ -29,13 +29,19 @@ import com.cloud.agent.api.GetVncPortCommand; import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupProxyCommand; import com.cloud.agent.api.StopAnswer; +import com.cloud.agent.api.to.NicTO; +import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.manager.Commands; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.deploy.DeployDestination; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ResourceUnavailableException; import com.cloud.host.HostVO; import com.cloud.host.Status; import com.cloud.host.dao.HostDao; import com.cloud.info.ConsoleProxyInfo; +import com.cloud.network.Network; import com.cloud.utils.NumbersUtil; import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.component.Inject; @@ -341,4 +347,20 @@ public class AgentBasedConsoleProxyManager implements ConsoleProxyManager, Virtu @Override public void finalizeExpunge(ConsoleProxyVO proxy) { } + + @Override + public boolean plugNic(Network network, NicTO nic, VirtualMachineTO vm, + ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException, + InsufficientCapacityException { + //not supported + throw new UnsupportedOperationException("Plug nic is not supported for vm of type " + vm.getType()); + } + + + @Override + public boolean unplugNic(Network network, NicTO nic, VirtualMachineTO vm, + ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException { + //not supported + throw new UnsupportedOperationException("Unplug nic is not supported for vm of type " + vm.getType()); + } } diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java index b6c1057a61a..492b05f2bbe 100755 --- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java +++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java @@ -43,6 +43,8 @@ import com.cloud.agent.api.check.CheckSshAnswer; import com.cloud.agent.api.check.CheckSshCommand; import com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer; import com.cloud.agent.api.proxy.StartConsoleProxyAgentHttpHandlerCommand; +import com.cloud.agent.api.to.NicTO; +import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.manager.Commands; import com.cloud.api.ServerApiException; import com.cloud.api.commands.DestroyConsoleProxyCmd; @@ -82,6 +84,7 @@ import com.cloud.keystore.KeystoreDao; import com.cloud.keystore.KeystoreManager; import com.cloud.keystore.KeystoreVO; import com.cloud.network.IPAddressVO; +import com.cloud.network.Network; import com.cloud.network.NetworkManager; import com.cloud.network.NetworkVO; import com.cloud.network.Networks.TrafficType; @@ -95,7 +98,6 @@ import com.cloud.resource.ResourceManager; import com.cloud.resource.ResourceStateAdapter; import com.cloud.resource.ServerResource; import com.cloud.resource.UnableDeleteHostException; -import com.cloud.server.ManagementServer; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.servlet.ConsoleProxyServlet; @@ -133,7 +135,6 @@ import com.cloud.uuididentity.dao.IdentityDao; import com.cloud.vm.ConsoleProxyVO; import com.cloud.vm.NicProfile; import com.cloud.vm.ReservationContext; -import com.cloud.vm.SecondaryStorageVmVO; import com.cloud.vm.SystemVmLoadScanHandler; import com.cloud.vm.SystemVmLoadScanner; import com.cloud.vm.SystemVmLoadScanner.AfterScanAction; @@ -1989,4 +1990,20 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, ConsoleProx } return _hashKey; } + + @Override + public boolean plugNic(Network network, NicTO nic, VirtualMachineTO vm, + ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException, + InsufficientCapacityException { + //not supported + throw new UnsupportedOperationException("Plug nic is not supported for vm of type " + vm.getType()); + } + + + @Override + public boolean unplugNic(Network network, NicTO nic, VirtualMachineTO vm, + ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException { + //not supported + throw new UnsupportedOperationException("Unplug nic is not supported for vm of type " + vm.getType()); + } } diff --git a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java index d62e3800542..2c3348427b7 100644 --- a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java +++ b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java @@ -35,7 +35,8 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis super(); } - protected NicTO toNicTO(NicProfile profile) { + @Override + public NicTO toNicTO(NicProfile profile) { NicTO to = new NicTO(); to.setDeviceId(profile.getDeviceId()); to.setBroadcastType(profile.getBroadcastType()); diff --git a/server/src/com/cloud/network/ExternalFirewallDeviceManagerImpl.java b/server/src/com/cloud/network/ExternalFirewallDeviceManagerImpl.java index 6a300a5170e..ad7372bbc35 100644 --- a/server/src/com/cloud/network/ExternalFirewallDeviceManagerImpl.java +++ b/server/src/com/cloud/network/ExternalFirewallDeviceManagerImpl.java @@ -379,11 +379,13 @@ public abstract class ExternalFirewallDeviceManagerImpl extends AdapterBase impl IPAddressVO sourceNatIp = null; if (!sharedSourceNat) { - // Get the source NAT IP address for this network - List sourceNatIps = _networkMgr.listPublicIpAddressesInVirtualNetwork(network.getAccountId(), zoneId, true, null); + // Get the source NAT IP address for this account + List sourceNatIps = _networkMgr.listPublicIpsAssignedToAccount(network.getAccountId(), + zoneId, true); if (sourceNatIps.size() != 1) { - String errorMsg = "External firewall was unable to find the source NAT IP address for account " + account.getAccountName(); + String errorMsg = "External firewall was unable to find the source NAT IP address for account " + + account.getAccountName(); s_logger.error(errorMsg); return true; } else { diff --git a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java b/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java index 3ad8c339350..1acba8ba7b6 100644 --- a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java +++ b/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java @@ -512,7 +512,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase // release the public & private IP back to dc pool, as the load balancer // appliance is now destroyed _dcDao.releasePrivateIpAddress(lbIP, guestConfig.getDataCenterId(), null); - _networkMgr.releasePublicIpAddress(publicIp.getId(), _accountMgr.getSystemUser().getId(), _accountMgr.getSystemAccount()); + _networkMgr.disassociatePublicIpAddress(publicIp.getId(), _accountMgr.getSystemUser().getId(), _accountMgr.getSystemAccount()); } } catch (Exception e) { s_logger.warn("Failed to destroy load balancer appliance created for the network" + guestConfig.getId() + " due to " + e.getMessage()); @@ -664,7 +664,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase // release the public IP allocated for this LB appliance DetailVO publicIpDetail = _hostDetailDao.findDetail(lbHost.getId(), "publicip"); IPAddressVO ipVo = _ipAddressDao.findByIpAndDcId(guestConfig.getDataCenterId(), publicIpDetail.toString()); - _networkMgr.releasePublicIpAddress(ipVo.getId(), _accountMgr.getSystemUser().getId(), _accountMgr.getSystemAccount()); + _networkMgr.disassociatePublicIpAddress(ipVo.getId(), _accountMgr.getSystemUser().getId(), _accountMgr.getSystemAccount()); } else { deviceMapLock.unlock(); } diff --git a/server/src/com/cloud/network/IPAddressVO.java b/server/src/com/cloud/network/IPAddressVO.java index 9ed071f774d..ea69b592ff8 100644 --- a/server/src/com/cloud/network/IPAddressVO.java +++ b/server/src/com/cloud/network/IPAddressVO.java @@ -100,6 +100,9 @@ public class IPAddressVO implements IpAddress, Identity { @Transient @Column(name="domain_id") private Long domainId = null; + + @Column(name="vpc_id") + private Long vpcId; protected IPAddressVO() { this.uuid = UUID.randomUUID().toString(); @@ -271,4 +274,14 @@ public class IPAddressVO implements IpAddress, Identity { public void setSystem(boolean isSystem) { this.system = isSystem; } + + @Override + public Long getVpcId() { + return vpcId; + } + + @Override + public void setVpcId(Long vpcId) { + this.vpcId = vpcId; + } } diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index 2577440d298..7908e8ec51d 100755 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -12,6 +12,7 @@ // Automatically generated by addcopyright.py at 04/03/2012 package com.cloud.network; +import java.net.URI; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -36,11 +37,13 @@ import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; import com.cloud.network.Networks.TrafficType; import com.cloud.network.addr.PublicIp; +import com.cloud.network.element.NetworkElement; import com.cloud.network.element.RemoteAccessVPNServiceProvider; import com.cloud.network.element.UserDataServiceProvider; import com.cloud.network.guru.NetworkGuru; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.StaticNat; +import com.cloud.network.vpc.Vpc; import com.cloud.offering.NetworkOffering; import com.cloud.offerings.NetworkOfferingVO; import com.cloud.user.Account; @@ -74,19 +77,9 @@ public interface NetworkManager extends NetworkService { * @throws InsufficientAddressCapacityException */ - PublicIp assignPublicIpAddress(long dcId, Long podId, Account owner, VlanType type, Long networkId, String requestedIp, boolean isSystem) throws InsufficientAddressCapacityException; + PublicIp assignPublicIpAddress(long dcId, Long podId, Account owner, VlanType type, Long networkId, String requestedIp, + boolean isSystem) throws InsufficientAddressCapacityException; - /** - * assigns a source nat ip address to an account within a network. - * - * @param owner - * @param network - * @param callerId - * @return - * @throws ConcurrentOperationException - * @throws InsufficientAddressCapacityException - */ - PublicIp assignSourceNatIpAddress(Account owner, Network network, long callerId) throws ConcurrentOperationException, InsufficientAddressCapacityException; /** * Do all of the work of releasing public ip addresses. Note that if this method fails, there can be side effects. @@ -97,28 +90,26 @@ public interface NetworkManager extends NetworkService { * @param ipAddress * @return true if it did; false if it didn't */ - public boolean releasePublicIpAddress(long id, long userId, Account caller); + public boolean disassociatePublicIpAddress(long id, long userId, Account caller); /** * Lists IP addresses that belong to VirtualNetwork VLANs * * @param accountId * - account that the IP address should belong to - * @param dcId - * - zone that the IP address should belong to - * @param sourceNat - * - (optional) true if the IP address should be a source NAT address * @param associatedNetworkId * TODO + * @param sourceNat + * - (optional) true if the IP address should be a source NAT address * @return - list of IP addresses */ - List listPublicIpAddressesInVirtualNetwork(long accountId, long dcId, Boolean sourceNat, Long associatedNetworkId); + List listPublicIpsAssignedToGuestNtwk(long accountId, long associatedNetworkId, Boolean sourceNat); List setupNetwork(Account owner, NetworkOfferingVO offering, DeploymentPlan plan, String name, String displayText, boolean isDefault) throws ConcurrentOperationException; List setupNetwork(Account owner, NetworkOfferingVO offering, Network predefined, DeploymentPlan plan, String name, String displayText, boolean errorIfAlreadySetup, Long domainId, - ACLType aclType, Boolean subdomainAccess) throws ConcurrentOperationException; + ACLType aclType, Boolean subdomainAccess, Long vpcId) throws ConcurrentOperationException; List getSystemAccountNetworkOfferings(String... offeringNames); @@ -161,8 +152,8 @@ public interface NetworkManager extends NetworkService { boolean destroyNetwork(long networkId, ReservationContext context); - Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, String networkDomain, Account owner, boolean isSecurityGroupEnabled, Long domainId, - PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType, Boolean subdomainAccess) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException; + Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, String networkDomain, Account owner, Long domainId, PhysicalNetwork physicalNetwork, + long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException; /** * @throws ResourceAllocationException TODO @@ -240,8 +231,6 @@ public interface NetworkManager extends NetworkService { boolean canElementEnableIndividualServices(Provider provider); - PhysicalNetworkServiceProvider addDefaultVirtualRouterToPhysicalNetwork(long physicalNetworkId); - boolean areServicesSupportedInNetwork(long networkId, Service... services); boolean isNetworkSystem(Network network); @@ -261,9 +250,6 @@ public interface NetworkManager extends NetworkService { void canProviderSupportServices(Map> providersMap); - PhysicalNetworkServiceProvider addDefaultSecurityGroupProviderToPhysicalNetwork( - long physicalNetworkId); - List getPhysicalNetworkInfo(long dcId, HypervisorType hypervisorType); @@ -307,4 +293,155 @@ public interface NetworkManager extends NetworkService { String getDefaultPublicTrafficLabel(long dcId, HypervisorType vmware); String getDefaultGuestTrafficLabel(long dcId, HypervisorType vmware); + + /** + * @param providerName + * @return + */ + NetworkElement getElementImplementingProvider(String providerName); + + /** + * @param owner + * @param guestNetwork + * @return + * @throws ConcurrentOperationException + * @throws InsufficientAddressCapacityException + */ + PublicIp assignSourceNatIpAddressToGuestNetwork(Account owner, Network guestNetwork) throws InsufficientAddressCapacityException, ConcurrentOperationException; + + + /** + * @param owner + * @param vpc + * @return + * @throws ConcurrentOperationException + * @throws InsufficientAddressCapacityException + */ + PublicIp assignSourceNatIpAddressToVpc(Account owner, Vpc vpc) throws InsufficientAddressCapacityException, ConcurrentOperationException; + + + /** + * @param accountId + * @param zoneId + * @return + */ + String getAccountNetworkDomain(long accountId, long zoneId); + + + /** + * @return + */ + String getDefaultNetworkDomain(); + + + /** + * @param networkId + * @return + */ + List getNtwkOffDistinctProviders(long networkId); + + + /** + * @param requested + * @param network + * @param isDefaultNic + * @param deviceId + * @param vm + * @return + * @throws InsufficientVirtualNetworkCapcityException + * @throws InsufficientAddressCapacityException + * @throws ConcurrentOperationException + */ + Pair allocateNic(NicProfile requested, Network network, Boolean isDefaultNic, int deviceId, + VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapcityException, + InsufficientAddressCapacityException, ConcurrentOperationException; + + + /** + * @param vmProfile + * @param dest + * @param context + * @param nicId + * @param network + * @return + * @throws InsufficientVirtualNetworkCapcityException + * @throws InsufficientAddressCapacityException + * @throws ConcurrentOperationException + * @throws InsufficientCapacityException + * @throws ResourceUnavailableException + */ + NicProfile prepareNic(VirtualMachineProfile vmProfile, DeployDestination dest, + ReservationContext context, long nicId, NetworkVO network) throws InsufficientVirtualNetworkCapcityException, + InsufficientAddressCapacityException, ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException; + + + /** + * @param vmProfile + * @param network + * @return TODO + * @throws ConcurrentOperationException + * @throws ResourceUnavailableException + */ + NicProfile releaseNic(VirtualMachineProfile vmProfile, NetworkVO network) + throws ConcurrentOperationException, ResourceUnavailableException; + + + /** + * @param vm + * @param network + */ + void removeNic(VirtualMachineProfile vm, Network network); + + + /** + * @param accountId + * @param dcId + * @param sourceNat + * @return + */ + List listPublicIpsAssignedToAccount(long accountId, long dcId, Boolean sourceNat); + + + /** + * @param ipAddrId + * @param networkId + */ + IpAddress associateIPToGuestNetwork(long ipAddrId, long networkId) throws ResourceAllocationException, ResourceUnavailableException, + InsufficientAddressCapacityException, ConcurrentOperationException; + + + /** + * @param ipId + */ + void unassignIPFromVpcNetwork(long ipId); + + + /** + * @param vm + * @param networkId + * @return + */ + NicProfile getNicProfile(VirtualMachine vm, long networkId); + + + /** + * @param network + * @param provider + * @return + */ + boolean setupDns(Network network, Provider provider); + + + /** + * @param vmProfile + * @param network + * @param broadcastUri + * @return + * @throws ConcurrentOperationException + * @throws ResourceUnavailableException + */ + NicProfile releaseNic(VirtualMachineProfile vmProfile, NetworkVO network, URI broadcastUri) + throws ConcurrentOperationException, ResourceUnavailableException; + + } diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 4a43a5ff09f..86239611cd6 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -55,12 +55,10 @@ import com.cloud.api.commands.CreateNetworkCmd; import com.cloud.api.commands.ListNetworksCmd; import com.cloud.api.commands.ListTrafficTypeImplementorsCmd; import com.cloud.api.commands.RestartNetworkCmd; -import com.cloud.capacity.dao.CapacityDao; import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; -import com.cloud.configuration.dao.ResourceLimitDao; import com.cloud.dc.AccountVlanMapVO; import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenter.NetworkType; @@ -110,6 +108,7 @@ import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.IsolationType; import com.cloud.network.Networks.TrafficType; import com.cloud.network.PhysicalNetwork.BroadcastDomainRange; +import com.cloud.network.VirtualRouterProvider.VirtualRouterProviderType; import com.cloud.network.addr.PublicIp; import com.cloud.network.dao.FirewallRulesDao; import com.cloud.network.dao.IPAddressDao; @@ -133,6 +132,7 @@ import com.cloud.network.element.SourceNatServiceProvider; import com.cloud.network.element.StaticNatServiceProvider; import com.cloud.network.element.UserDataServiceProvider; import com.cloud.network.element.VirtualRouterElement; +import com.cloud.network.element.VpcVirtualRouterElement; import com.cloud.network.guru.NetworkGuru; import com.cloud.network.lb.LoadBalancingRule; import com.cloud.network.lb.LoadBalancingRule.LbDestination; @@ -149,6 +149,10 @@ import com.cloud.network.rules.StaticNat; import com.cloud.network.rules.StaticNatRule; import com.cloud.network.rules.StaticNatRuleImpl; import com.cloud.network.rules.dao.PortForwardingRulesDao; +import com.cloud.network.vpc.PrivateIpVO; +import com.cloud.network.vpc.Vpc; +import com.cloud.network.vpc.VpcManager; +import com.cloud.network.vpc.Dao.PrivateIpDao; import com.cloud.network.vpn.RemoteAccessVpnService; import com.cloud.offering.NetworkOffering; import com.cloud.offering.NetworkOffering.Availability; @@ -230,10 +234,6 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Inject UserVmDao _userVmDao = null; @Inject - ResourceLimitDao _limitDao = null; - @Inject - CapacityDao _capacityDao = null; - @Inject AlertManager _alertMgr; @Inject AccountManager _accountMgr; @@ -301,6 +301,10 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag NetworkServiceMapDao _ntwkSrvcDao; @Inject StorageNetworkManager _stnwMgr; + @Inject + VpcManager _vpcMgr; + @Inject + PrivateIpDao _privateIpDao; private final HashMap _systemNetworks = new HashMap(5); @@ -326,6 +330,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag private static HashMap> s_serviceToImplementedProvidersMap = new HashMap>(); private static HashMap s_providerToNetworkElementMap = new HashMap(); + @Override public NetworkElement getElementImplementingProvider(String providerName) { String elementName = s_providerToNetworkElementMap.get(providerName); NetworkElement element = _networkElements.get(elementName); @@ -352,11 +357,12 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Override public PublicIp assignPublicIpAddress(long dcId, Long podId, Account owner, VlanType type, Long networkId, String requestedIp, boolean isSystem) throws InsufficientAddressCapacityException { - return fetchNewPublicIp(dcId, podId, null, owner, type, networkId, false, true, requestedIp, isSystem); + return fetchNewPublicIp(dcId, podId, null, owner, type, networkId, false, true, requestedIp, isSystem, null); } @DB - public PublicIp fetchNewPublicIp(long dcId, Long podId, Long vlanDbId, Account owner, VlanType vlanUse, Long networkId, boolean sourceNat, boolean assign, String requestedIp, boolean isSystem) + public PublicIp fetchNewPublicIp(long dcId, Long podId, Long vlanDbId, Account owner, VlanType vlanUse, + Long guestNetworkId, boolean sourceNat, boolean assign, String requestedIp, boolean isSystem, Long vpcId) throws InsufficientAddressCapacityException { StringBuilder errorMessage = new StringBuilder("Unable to get ip adress in "); Transaction txn = Transaction.currentTxn(); @@ -382,8 +388,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag // for direct network take ip addresses only from the vlans belonging to the network if (vlanUse == VlanType.DirectAttached) { - sc.setJoinParameters("vlan", "networkId", networkId); - errorMessage.append(", network id=" + networkId); + sc.setJoinParameters("vlan", "networkId", guestNetworkId); + errorMessage.append(", network id=" + guestNetworkId); } sc.setJoinParameters("vlan", "type", vlanUse); @@ -398,13 +404,15 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (addrs.size() == 0) { if (podId != null) { - InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", Pod.class, podId); + InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException + ("Insufficient address capacity", Pod.class, podId); // for now, we hardcode the table names, but we should ideally do a lookup for the tablename from the VO object. ex.addProxyObject("Pod", podId, "podId"); throw ex; } s_logger.warn(errorMessage.toString()); - InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", DataCenter.class, dcId); + InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException + ("Insufficient address capacity", DataCenter.class, dcId); ex.addProxyObject("data_center", dcId, "dcId"); throw ex; } @@ -426,7 +434,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag addr.setState(assign ? IpAddress.State.Allocated : IpAddress.State.Allocating); if (vlanUse != VlanType.DirectAttached || zone.getNetworkType() == NetworkType.Basic) { - addr.setAssociatedWithNetworkId(networkId); + addr.setAssociatedWithNetworkId(guestNetworkId); + addr.setVpcId(vpcId); } _ipAddressDao.update(addr.getId(), addr); @@ -445,7 +454,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @DB protected void markPublicIpAsAllocated(IPAddressVO addr) { - assert (addr.getState() == IpAddress.State.Allocating || addr.getState() == IpAddress.State.Free) : "Unable to transition from state " + addr.getState() + " to " + IpAddress.State.Allocated; + assert (addr.getState() == IpAddress.State.Allocating || addr.getState() == IpAddress.State.Free) : + "Unable to transition from state " + addr.getState() + " to " + IpAddress.State.Allocated; Transaction txn = Transaction.currentTxn(); @@ -461,7 +471,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag String guestType = vlan.getVlanType().toString(); - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NET_IP_ASSIGN, owner.getId(), addr.getDataCenterId(), addr.getId(), addr.getAddress().toString(), addr.isSourceNat(), guestType, addr.getSystem()); + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NET_IP_ASSIGN, owner.getId(), + addr.getDataCenterId(), addr.getId(), addr.getAddress().toString(), addr.isSourceNat(), guestType, + addr.getSystem()); _usageEventDao.persist(usageEvent); // don't increment resource count for direct ip addresses if (addr.getAssociatedWithNetworkId() != null) { @@ -472,16 +484,60 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag txn.commit(); } + @Override - @DB - public PublicIp assignSourceNatIpAddress(Account owner, Network network, long callerId) throws ConcurrentOperationException, InsufficientAddressCapacityException { - assert (network.getTrafficType() != null) : "You're asking for a source nat but your network can't participate in source nat. What do you have to say for yourself?"; + public PublicIp assignSourceNatIpAddressToVpc(Account owner, Vpc vpc) throws InsufficientAddressCapacityException, ConcurrentOperationException { + long dcId = vpc.getZoneId(); + + IPAddressVO sourceNatIp = getExistingSourceNat(owner.getId(), null, vpc.getId()); + + PublicIp ipToReturn = null; + + if (sourceNatIp != null) { + ipToReturn = new PublicIp(sourceNatIp, _vlanDao.findById(sourceNatIp.getVlanId()), + NetUtils.createSequenceBasedMacAddress(sourceNatIp.getMacAddress())); + } else { + ipToReturn = assignSourceNatIpAddress(owner, null, vpc.getId(), dcId); + } + + return ipToReturn; + } + + @Override + public PublicIp assignSourceNatIpAddressToGuestNetwork(Account owner, Network guestNetwork) + throws InsufficientAddressCapacityException, ConcurrentOperationException { + assert (guestNetwork.getTrafficType() != null) : "You're asking for a source nat but your network " + + "can't participate in source nat. What do you have to say for yourself?"; + long dcId = guestNetwork.getDataCenterId(); + + IPAddressVO sourceNatIp = getExistingSourceNat(owner.getId(), guestNetwork.getId(), guestNetwork.getVpcId()); + + PublicIp ipToReturn = null; + if (sourceNatIp != null) { + ipToReturn = new PublicIp(sourceNatIp, _vlanDao.findById(sourceNatIp.getVlanId()), + NetUtils.createSequenceBasedMacAddress(sourceNatIp.getMacAddress())); + } else { + ipToReturn = assignSourceNatIpAddress(owner, guestNetwork.getId(), null, dcId); + } + + return ipToReturn; + } + + @DB + public PublicIp assignSourceNatIpAddress(Account owner, Long guestNtwkId, Long vpcId, long dcId) + throws ConcurrentOperationException, InsufficientAddressCapacityException { - long dcId = network.getDataCenterId(); long ownerId = owner.getId(); - PublicIp ip = null; + // Check that the maximum number of public IPs for the given accountId will not be exceeded + try { + _resourceLimitMgr.checkResourceLimit(owner, ResourceType.public_ip); + } catch (ResourceAllocationException ex) { + s_logger.warn("Failed to allocate resource of type " + ex.getResourceType() + " for account " + owner); + throw new AccountLimitException("Maximum number of public IP addresses for account: " + owner.getAccountName() + " has been exceeded."); + } + PublicIp ip = null; Transaction txn = Transaction.currentTxn(); try { txn.start(); @@ -499,50 +555,23 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag s_logger.debug("lock account " + ownerId + " is acquired"); } - IPAddressVO sourceNat = null; - List addrs = listPublicIpAddressesInVirtualNetwork(ownerId, dcId, null, network.getId()); - if (addrs.size() == 0) { - - // Check that the maximum number of public IPs for the given accountId will not be exceeded - try { - _resourceLimitMgr.checkResourceLimit(owner, ResourceType.public_ip); - } catch (ResourceAllocationException ex) { - s_logger.warn("Failed to allocate resource of type " + ex.getResourceType() + " for account " + owner); - throw new AccountLimitException("Maximum number of public IP addresses for account: " + owner.getAccountName() + " has been exceeded."); - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("assigning a new ip address in " + dcId + " to " + owner); - } - // If account has Account specific ip ranges, try to allocate ip from there Long vlanId = null; List maps = _accountVlanMapDao.listAccountVlanMapsByAccount(ownerId); if (maps != null && !maps.isEmpty()) { //check if the ips from this vlan are associated with this network List ips = _ipAddressDao.listByVlanId(maps.get(0).getVlanDbId()); - if (ips != null && !ips.isEmpty() && ips.get(0).getAssociatedWithNetworkId() == network.getId()) { + if (ips != null && !ips.isEmpty() && ips.get(0).getAssociatedWithNetworkId() == guestNtwkId) { vlanId = maps.get(0).getVlanDbId(); } } - ip = fetchNewPublicIp(dcId, null, vlanId, owner, VlanType.VirtualNetwork, network.getId(), true, false, null, false); - sourceNat = ip.ip(); + ip = fetchNewPublicIp(dcId, null, vlanId, owner, VlanType.VirtualNetwork, guestNtwkId, + true, false, null, false, vpcId); + IPAddressVO sourceNatIp = ip.ip(); - markPublicIpAsAllocated(sourceNat); - _ipAddressDao.update(sourceNat.getId(), sourceNat); - } else { - // Account already has ip addresses - for (IPAddressVO addr : addrs) { - if (addr.isSourceNat()) { - sourceNat = addr; - break; - } - } - - assert (sourceNat != null) : "How do we get a bunch of ip addresses but none of them are source nat? account=" + ownerId + "; dc=" + dcId; - ip = new PublicIp(sourceNat, _vlanDao.findById(sourceNat.getVlanId()), NetUtils.createSequenceBasedMacAddress(sourceNat.getMacAddress())); - } + markPublicIpAsAllocated(sourceNatIp); + _ipAddressDao.update(sourceNatIp.getId(), sourceNatIp); txn.commit(); return ip; @@ -605,7 +634,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag List publicIps = new ArrayList(); if (userIps != null && !userIps.isEmpty()) { for (IPAddressVO userIp : userIps) { - PublicIp publicIp = new PublicIp(userIp, _vlanDao.findById(userIp.getVlanId()), NetUtils.createSequenceBasedMacAddress(userIp.getMacAddress())); + PublicIp publicIp = new PublicIp(userIp, _vlanDao.findById(userIp.getVlanId()), + NetUtils.createSequenceBasedMacAddress(userIp.getMacAddress())); publicIps.add(publicIp); } } @@ -614,16 +644,13 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (success) { for (IPAddressVO addr : userIps) { - if (addr.getState() == IpAddress.State.Allocating) { - - addr.setAssociatedWithNetworkId(network.getId()); markPublicIpAsAllocated(addr); - } else if (addr.getState() == IpAddress.State.Releasing) { // Cleanup all the resources for ip address if there are any, and only then un-assign ip in the // system if (cleanupIpResources(addr.getId(), Account.ACCOUNT_ID_SYSTEM, _accountMgr.getSystemAccount())) { + s_logger.debug("Unassiging ip address " + addr); _ipAddressDao.unassignIpAddress(addr.getId()); } else { success = false; @@ -690,7 +717,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag ipToServices.put(ip, services); // if IP in allocating state then it will not have any rules attached so skip IPAssoc to network service -// provider + // provider if (ip.getState() == State.Allocating) { continue; } @@ -884,7 +911,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return providerToIpList; } - protected boolean applyIpAssociations(Network network, boolean rulesRevoked, boolean continueOnError, List publicIps) throws ResourceUnavailableException { + protected boolean applyIpAssociations(Network network, boolean rulesRevoked, boolean continueOnError, + List publicIps) throws ResourceUnavailableException { boolean success = true; Map> ipToServices = getIpToServices(publicIps, rulesRevoked, false); @@ -981,53 +1009,31 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Override @ActionEvent(eventType = EventTypes.EVENT_NET_IP_ASSIGN, eventDescription = "allocating Ip", create = true) - public IpAddress allocateIP(long networkId, Account ipOwner) throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException { - return allocateIP(networkId, ipOwner, false); - } - - @DB - public IpAddress allocateIP(long networkId, Account ipOwner, boolean isSystem) throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException { + public IpAddress allocateIP(Account ipOwner, boolean isSystem, long zoneId) + throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException { Account caller = UserContext.current().getCaller(); - long userId = UserContext.current().getCallerUserId(); - - long ownerId = ipOwner.getId(); - Network network = _networksDao.findById(networkId); - if (network == null) { - InvalidParameterValueException ex = new InvalidParameterValueException("Network id is invalid"); - ex.addProxyObject("networks", networkId, "networkId"); - throw ex; - } + long callerUserId = UserContext.current().getCallerUserId(); // check permissions _accountMgr.checkAccess(caller, null, false, ipOwner); - _accountMgr.checkAccess(ipOwner, AccessType.UseNetwork, false, network); - DataCenter zone = _configMgr.getZone(network.getDataCenterId()); + DataCenter zone = _configMgr.getZone(zoneId); - // allow associating IP addresses to guest network only - if (network.getTrafficType() != TrafficType.Guest) { - throw new InvalidParameterValueException("Ip address can be associated to the network with trafficType " + TrafficType.Guest); - } + return allocateIp(ipOwner, isSystem, caller, callerUserId, zone); + } - // In Advance zone only allow to do IP assoc for Isolated networks with source nat service enabled - if (zone.getNetworkType() == NetworkType.Advanced && !(network.getGuestType() == GuestType.Isolated && areServicesSupportedInNetwork(network.getId(), Service.SourceNat))) { - throw new InvalidParameterValueException("In zone of type " + NetworkType.Advanced + " ip address can be associated only to the network of guest type " + GuestType.Isolated + " with the " - + Service.SourceNat.getName() + " enabled"); - } - - // Check that network belongs to IP owner - skip this check for Basic zone as there is just one guest network, -// and it - // belongs to the system - if (zone.getNetworkType() != NetworkType.Basic && network.getAccountId() != ipOwner.getId()) { - throw new InvalidParameterValueException("The owner of the network is not the same as owner of the IP"); - } + @DB + public IpAddress allocateIp(Account ipOwner, boolean isSystem, Account caller, long callerUserId, DataCenter zone) + throws ConcurrentOperationException, ResourceAllocationException, + InsufficientAddressCapacityException { VlanType vlanType = VlanType.VirtualNetwork; boolean assign = false; if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getType())) { // zone is of type DataCenter. See DataCenterVO.java. - PermissionDeniedException ex = new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled"); + PermissionDeniedException ex = new PermissionDeniedException("Cannot perform this operation, " + + "Zone is currently disabled"); ex.addProxyObject("data_center", zone.getId(), "zoneId"); throw ex; } @@ -1038,11 +1044,11 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag Account accountToLock = null; try { if (s_logger.isDebugEnabled()) { - s_logger.debug("Associate IP address called for user " + userId + " account " + ownerId); + s_logger.debug("Associate IP address called by the user " + callerUserId + " account " + ipOwner.getId()); } - accountToLock = _accountDao.acquireInLockTable(ownerId); + accountToLock = _accountDao.acquireInLockTable(ipOwner.getId()); if (accountToLock == null) { - s_logger.warn("Unable to lock account: " + ownerId); + s_logger.warn("Unable to lock account: " + ipOwner.getId()); throw new ConcurrentOperationException("Unable to acquire account lock"); } @@ -1054,53 +1060,68 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag // accountId will not be exceeded _resourceLimitMgr.checkResourceLimit(accountToLock, ResourceType.public_ip); - boolean isSourceNat = false; - txn.start(); - NetworkOffering offering = _networkOfferingDao.findById(network.getNetworkOfferingId()); - boolean sharedSourceNat = offering.getSharedSourceNat(); - - if (!sharedSourceNat) { - // First IP address should be source nat when it's being associated with Guest Virtual network - List addrs = listPublicIpAddressesInVirtualNetwork(ownerId, zone.getId(), true, networkId); - - if (addrs.isEmpty() && network.getGuestType() == Network.GuestType.Isolated) { - isSourceNat = true; - } - } - - ip = fetchNewPublicIp(zone.getId(), null, null, ipOwner, vlanType, network.getId(), isSourceNat, assign, null, isSystem); + ip = fetchNewPublicIp(zone.getId(), null, null, ipOwner, vlanType, null, + false, assign, null, isSystem, null); if (ip == null) { - InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Unable to find available public IP addresses", DataCenter.class, zone.getId()); + InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException + ("Unable to find available public IP addresses", DataCenter.class, zone.getId()); ex.addProxyObject("data_center", zone.getId(), "zoneId"); throw ex; } UserContext.current().setEventDetails("Ip Id: " + ip.getId()); Ip ipAddress = ip.getAddress(); - s_logger.debug("Got " + ipAddress + " to assign for account " + ipOwner.getId() + " in zone " + network.getDataCenterId()); + s_logger.debug("Got " + ipAddress + " to assign for account " + ipOwner.getId() + " in zone " + zone.getId()); txn.commit(); } finally { if (accountToLock != null) { - _accountDao.releaseFromLockTable(ownerId); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Releasing lock account " + ipOwner); + } + _accountDao.releaseFromLockTable(ipOwner.getId()); s_logger.debug("Associate IP address lock released"); } } - return ip; } - @Override - @ActionEvent(eventType = EventTypes.EVENT_NET_IP_ASSIGN, eventDescription = "associating Ip", async = true) - public IpAddress associateIP(long ipId) throws ResourceAllocationException, ResourceUnavailableException, InsufficientAddressCapacityException, ConcurrentOperationException { - return associateIP(ipId, false); + + protected IPAddressVO getExistingSourceNat(long ownerId, Long networkId, Long vpcId) { + + List addrs = null; + if (vpcId != null) { + addrs = listPublicIpsAssignedToVpc(ownerId, true, vpcId); + } else if (networkId != null) { + addrs = listPublicIpsAssignedToGuestNtwk(ownerId, networkId, true); + } + + IPAddressVO sourceNatIp = null; + if (addrs.isEmpty()) { + return null; + } else { + // Account already has ip addresses + for (IPAddressVO addr : addrs) { + if (addr.isSourceNat()) { + sourceNatIp = addr; + return sourceNatIp; + } + } + + assert (sourceNatIp != null) : "How do we get a bunch of ip addresses but none of them are source nat? " + + "account=" + ownerId + "; networkId=" + networkId + "; vpcId=" + vpcId; + } + + return sourceNatIp; } @DB - private IpAddress associateIP(long ipId, boolean isSystem) throws ResourceAllocationException, ResourceUnavailableException, InsufficientAddressCapacityException, ConcurrentOperationException { + @Override + public IpAddress associateIPToGuestNetwork(long ipId, long networkId) throws ResourceAllocationException, ResourceUnavailableException, + InsufficientAddressCapacityException, ConcurrentOperationException { Account caller = UserContext.current().getCaller(); Account owner = null; @@ -1113,16 +1134,68 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return null; } - Network network = _networksDao.findById(ipToAssoc.getAssociatedWithNetworkId()); + if (ipToAssoc.getAssociatedWithNetworkId() != null) { + s_logger.debug("IP " + ipToAssoc + " is already assocaited with network id" + networkId); + return ipToAssoc; + } + + Network network = _networksDao.findById(networkId); + if (network != null) { + _accountMgr.checkAccess(caller, AccessType.UseNetwork, false, network); + } else { + s_logger.debug("Unable to find ip address by id: " + ipId); + return null; + } + + DataCenter zone = _configMgr.getZone(network.getDataCenterId()); + + // allow associating IP addresses to guest network only + if (network.getTrafficType() != TrafficType.Guest) { + throw new InvalidParameterValueException("Ip address can be associated to the network with trafficType " + + TrafficType.Guest); + } + + // Check that network belongs to IP owner - skip this check for Basic zone as there is just one guest network, + // and it belongs to the system + if (zone.getNetworkType() != NetworkType.Basic && network.getAccountId() != owner.getId()) { + throw new InvalidParameterValueException("The owner of the network is not the same as owner of the IP"); + } + + // In Advance zone only allow to do IP assoc for Isolated networks with source nat service enabled + if (zone.getNetworkType() == NetworkType.Advanced && + !(network.getGuestType() == GuestType.Isolated && areServicesSupportedInNetwork(network.getId(), + Service.SourceNat))) { + throw new InvalidParameterValueException("In zone of type " + NetworkType.Advanced + + " ip address can be associated only to the network of guest type " + GuestType.Isolated + " with the " + + Service.SourceNat.getName() + " enabled"); + } + + NetworkOffering offering = _networkOfferingDao.findById(network.getNetworkOfferingId()); + boolean sharedSourceNat = offering.getSharedSourceNat(); + boolean isSourceNat = false; + if (!sharedSourceNat) { + if (getExistingSourceNat(owner.getId(), networkId, null) == null) { + if (network.getGuestType() == GuestType.Isolated) { + isSourceNat = true; + } + } + } + + s_logger.debug("Associating ip " + ipToAssoc + " to network " + network); IPAddressVO ip = _ipAddressDao.findById(ipId); + //update ip address with networkId + ip.setAssociatedWithNetworkId(networkId); + ip.setSourceNat(isSourceNat); + _ipAddressDao.update(ipId, ip); + boolean success = false; try { success = applyIpAssociations(network, false); if (success) { - s_logger.debug("Successfully associated ip address " + ip.getAddress().addr() + " for account " + owner.getId() + " in zone " + network.getDataCenterId()); + s_logger.debug("Successfully associated ip address " + ip.getAddress().addr() + " to network " + network); } else { - s_logger.warn("Failed to associate ip address " + ip.getAddress().addr() + " for account " + owner.getId() + " in zone " + network.getDataCenterId()); + s_logger.warn("Failed to associate ip address " + ip.getAddress().addr() + " to network " + network); } return ip; } catch (ResourceUnavailableException e) { @@ -1136,8 +1209,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag _ipAddressDao.markAsUnavailable(ip.getId()); if (!applyIpAssociations(network, true)) { // if fail to apply ip assciations again, unassign ip address without updating resource -// count and - // generating usage event as there is no need to keep it in the db + // count and generating usage event as there is no need to keep it in the db _ipAddressDao.unassignIpAddress(ip.getId()); } } catch (Exception e) { @@ -1148,12 +1220,57 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } } + + @DB + protected IpAddress associateIPToVpc(long ipId, long vpcId) throws ResourceAllocationException, ResourceUnavailableException, + InsufficientAddressCapacityException, ConcurrentOperationException { + Account caller = UserContext.current().getCaller(); + Account owner = null; + + IpAddress ipToAssoc = getIp(ipId); + if (ipToAssoc != null) { + _accountMgr.checkAccess(caller, null, true, ipToAssoc); + owner = _accountMgr.getAccount(ipToAssoc.getAllocatedToAccountId()); + } else { + s_logger.debug("Unable to find ip address by id: " + ipId); + return null; + } + + Vpc vpc = _vpcMgr.getVpc(vpcId); + if (vpc == null) { + throw new InvalidParameterValueException("Invalid VPC id " + vpcId); + } + + // check permissions + _accountMgr.checkAccess(caller, null, true, owner, vpc); + + boolean isSourceNat = false; + if (getExistingSourceNat(owner.getId(), null, vpcId) == null) { + isSourceNat = true; + } + + s_logger.debug("Associating ip " + ipToAssoc + " to vpc " + vpc); + + Transaction txn = Transaction.currentTxn(); + txn.start(); + IPAddressVO ip = _ipAddressDao.findById(ipId); + //update ip address with networkId + ip.setVpcId(vpcId); + ip.setSourceNat(isSourceNat); + _ipAddressDao.update(ipId, ip); + txn.commit(); + + s_logger.debug("Successfully assigned ip " + ipToAssoc + " to vpc " + vpc); + + return _ipAddressDao.findById(ipId); + } + + @Override @DB - public boolean releasePublicIpAddress(long addrId, long userId, Account caller) { + public boolean disassociatePublicIpAddress(long addrId, long userId, Account caller) { boolean success = true; - // Cleanup all ip address resources - PF/LB/Static nat rules if (!cleanupIpResources(addrId, userId, caller)) { success = false; @@ -1181,10 +1298,14 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } catch (ResourceUnavailableException e) { throw new CloudRuntimeException("We should never get to here because we used true when applyIpAssociations", e); } + } else { + if (ip.getState() == IpAddress.State.Releasing) { + _ipAddressDao.unassignIpAddress(ip.getId()); + } } if (success) { - s_logger.debug("released a public ip id=" + addrId); + s_logger.debug("Released a public ip id=" + addrId); } return success; @@ -1217,6 +1338,11 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag NetworkOfferingVO storageNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemStorageNetwork, TrafficType.Storage, true); storageNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(storageNetworkOffering); _systemNetworks.put(NetworkOfferingVO.SystemStorageNetwork, storageNetworkOffering); + NetworkOfferingVO privateGatewayNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemPrivateGatewayNetworkOffering, + GuestType.Isolated); + privateGatewayNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(privateGatewayNetworkOffering); + _systemNetworks.put(NetworkOfferingVO.SystemPrivateGatewayNetworkOffering, privateGatewayNetworkOffering); + // populate providers Map> defaultSharedNetworkOfferingProviders = new HashMap>(); @@ -1237,7 +1363,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag sgProviders.add(Provider.SecurityGroupProvider); defaultSharedSGEnabledNetworkOfferingProviders.put(Service.SecurityGroup, sgProviders); - Map> defaultIsolatedSourceNatEnabledNetworkOfferingProviders = new HashMap>(); + Map> defaultIsolatedSourceNatEnabledNetworkOfferingProviders = + new HashMap>(); defaultProviders.clear(); defaultProviders.add(Network.Provider.VirtualRouter); defaultIsolatedSourceNatEnabledNetworkOfferingProviders.put(Service.Dhcp, defaultProviders); @@ -1257,29 +1384,56 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag NetworkOfferingVO offering = null; if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedNetworkOfferingWithSGService) == null) { - offering = _configMgr.createNetworkOffering(Account.ACCOUNT_ID_SYSTEM, NetworkOffering.DefaultSharedNetworkOfferingWithSGService, "Offering for Shared Security group enabled networks", TrafficType.Guest, - null, true, Availability.Optional, null, defaultSharedNetworkOfferingProviders, true, Network.GuestType.Shared, false, null, true, null, true); + offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedNetworkOfferingWithSGService, "Offering for Shared Security group enabled networks", TrafficType.Guest, null, + true, Availability.Optional, null, defaultSharedNetworkOfferingProviders, true, Network.GuestType.Shared, false, null, true, null, true); offering.setState(NetworkOffering.State.Enabled); _networkOfferingDao.update(offering.getId(), offering); } if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedNetworkOffering) == null) { - offering = _configMgr.createNetworkOffering(Account.ACCOUNT_ID_SYSTEM, NetworkOffering.DefaultSharedNetworkOffering, "Offering for Shared networks", TrafficType.Guest, null, true, Availability.Optional, - null, defaultSharedNetworkOfferingProviders, true, Network.GuestType.Shared, false, null, true, null, true); + offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedNetworkOffering, "Offering for Shared networks", TrafficType.Guest, null, true, Availability.Optional, null, + defaultSharedNetworkOfferingProviders, true, Network.GuestType.Shared, false, null, true, null, true); offering.setState(NetworkOffering.State.Enabled); _networkOfferingDao.update(offering.getId(), offering); } + Map> defaultINetworkOfferingProvidersForVpcNetwork = new HashMap>(); + defaultProviders.clear(); + defaultProviders.add(Network.Provider.VPCVirtualRouter); + defaultINetworkOfferingProvidersForVpcNetwork.put(Service.Dhcp, defaultProviders); + defaultINetworkOfferingProvidersForVpcNetwork.put(Service.Dns, defaultProviders); + defaultINetworkOfferingProvidersForVpcNetwork.put(Service.UserData, defaultProviders); + defaultINetworkOfferingProvidersForVpcNetwork.put(Service.Firewall, defaultProviders); + defaultINetworkOfferingProvidersForVpcNetwork.put(Service.Gateway, defaultProviders); + defaultINetworkOfferingProvidersForVpcNetwork.put(Service.Lb, defaultProviders); + defaultINetworkOfferingProvidersForVpcNetwork.put(Service.SourceNat, defaultProviders); + defaultINetworkOfferingProvidersForVpcNetwork.put(Service.StaticNat, defaultProviders); + defaultINetworkOfferingProvidersForVpcNetwork.put(Service.PortForwarding, defaultProviders); + defaultINetworkOfferingProvidersForVpcNetwork.put(Service.Vpn, defaultProviders); + if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingWithSourceNatService) == null) { - offering = _configMgr.createNetworkOffering(Account.ACCOUNT_ID_SYSTEM, NetworkOffering.DefaultIsolatedNetworkOfferingWithSourceNatService, "Offering for Isolated networks with Source Nat service enabled", - TrafficType.Guest, null, false, Availability.Required, null, defaultIsolatedSourceNatEnabledNetworkOfferingProviders, true, Network.GuestType.Isolated, false, null, true, null, false); + offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingWithSourceNatService, + "Offering for Isolated networks with Source Nat service enabled", TrafficType.Guest, + null, false, Availability.Required, null, defaultINetworkOfferingProvidersForVpcNetwork, + true, Network.GuestType.Isolated, false, null, true, null, false); + offering.setState(NetworkOffering.State.Enabled); + _networkOfferingDao.update(offering.getId(), offering); + } + + if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworks) == null) { + offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworks, + "Offering for Isolated VPC networks with Source Nat service enabled", TrafficType.Guest, + null, false, Availability.Required, null, defaultIsolatedSourceNatEnabledNetworkOfferingProviders, + true, Network.GuestType.Isolated, false, null, false, null, false); offering.setState(NetworkOffering.State.Enabled); _networkOfferingDao.update(offering.getId(), offering); } if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOffering) == null) { - offering = _configMgr.createNetworkOffering(Account.ACCOUNT_ID_SYSTEM, NetworkOffering.DefaultIsolatedNetworkOffering, "Offering for Isolated networks with no Source Nat service", TrafficType.Guest, null, - true, Availability.Optional, null, defaultIsolatedNetworkOfferingProviders, true, Network.GuestType.Isolated, false, null, true, null, true); + offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOffering, + "Offering for Isolated networks with no Source Nat service", TrafficType.Guest, null, true, + Availability.Optional, null, defaultIsolatedNetworkOfferingProviders, true, Network.GuestType.Isolated, + false, null, true, null, true); offering.setState(NetworkOffering.State.Enabled); _networkOfferingDao.update(offering.getId(), offering); } @@ -1307,8 +1461,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag serviceCapabilityMap.put(Service.StaticNat, eip); if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedEIPandELBNetworkOffering) == null) { - offering = _configMgr.createNetworkOffering(Account.ACCOUNT_ID_SYSTEM, NetworkOffering.DefaultSharedEIPandELBNetworkOffering, "Offering for Shared networks with Elastic IP and Elastic LB capabilities", TrafficType.Guest, null, - true, Availability.Optional, null, netscalerServiceProviders, true, Network.GuestType.Shared, false, null, true, serviceCapabilityMap, true); + offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedEIPandELBNetworkOffering, "Offering for Shared networks with Elastic IP and Elastic LB capabilities", TrafficType.Guest, null, true, + Availability.Optional, null, netscalerServiceProviders, true, Network.GuestType.Shared, false, null, true, serviceCapabilityMap, true); offering.setState(NetworkOffering.State.Enabled); offering.setDedicatedLB(false); _networkOfferingDao.update(offering.getId(), offering); @@ -1348,6 +1502,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag IpAddressSearch = _ipAddressDao.createSearchBuilder(); IpAddressSearch.and("accountId", IpAddressSearch.entity().getAllocatedToAccountId(), Op.EQ); IpAddressSearch.and("dataCenterId", IpAddressSearch.entity().getDataCenterId(), Op.EQ); + IpAddressSearch.and("vpcId", IpAddressSearch.entity().getVpcId(), Op.EQ); IpAddressSearch.and("associatedWithNetworkId", IpAddressSearch.entity().getAssociatedWithNetworkId(), Op.EQ); SearchBuilder virtualNetworkVlanSB = _vlanDao.createSearchBuilder(); virtualNetworkVlanSB.and("vlanType", virtualNetworkVlanSB.entity().getVlanType(), Op.EQ); @@ -1387,7 +1542,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag Provider implementedProvider = element.getProvider(); if (implementedProvider != null) { if (s_providerToNetworkElementMap.containsKey(implementedProvider.getName())) { - s_logger.error("Cannot start NetworkManager: Provider <-> NetworkElement must be a one-to-one map, multiple NetworkElements found for Provider: " + implementedProvider.getName()); + s_logger.error("Cannot start NetworkManager: Provider <-> NetworkElement must be a one-to-one map, " + + "multiple NetworkElements found for Provider: " + implementedProvider.getName()); return false; } s_providerToNetworkElementMap.put(implementedProvider.getName(), element.getName()); @@ -1419,13 +1575,37 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } @Override - public List listPublicIpAddressesInVirtualNetwork(long accountId, long dcId, Boolean sourceNat, Long associatedNetworkId) { + public List listPublicIpsAssignedToGuestNtwk(long accountId, long associatedNetworkId, Boolean sourceNat) { + SearchCriteria sc = IpAddressSearch.create(); + sc.setParameters("accountId", accountId); + sc.setParameters("associatedWithNetworkId", associatedNetworkId); + + if (sourceNat != null) { + sc.addAnd("sourceNat", SearchCriteria.Op.EQ, sourceNat); + } + sc.setJoinParameters("virtualNetworkVlanSB", "vlanType", VlanType.VirtualNetwork); + + return _ipAddressDao.search(sc, null); + } + + @Override + public List listPublicIpsAssignedToAccount(long accountId, long dcId, Boolean sourceNat) { SearchCriteria sc = IpAddressSearch.create(); sc.setParameters("accountId", accountId); sc.setParameters("dataCenterId", dcId); - if (associatedNetworkId != null) { - sc.setParameters("associatedWithNetworkId", associatedNetworkId); + + if (sourceNat != null) { + sc.addAnd("sourceNat", SearchCriteria.Op.EQ, sourceNat); } + sc.setJoinParameters("virtualNetworkVlanSB", "vlanType", VlanType.VirtualNetwork); + + return _ipAddressDao.search(sc, null); + } + + protected List listPublicIpsAssignedToVpc(long accountId, Boolean sourceNat, long vpcId) { + SearchCriteria sc = IpAddressSearch.create(); + sc.setParameters("accountId", accountId); + sc.setParameters("vpcId", vpcId); if (sourceNat != null) { sc.addAnd("sourceNat", SearchCriteria.Op.EQ, sourceNat); @@ -1436,15 +1616,18 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } @Override - public List setupNetwork(Account owner, NetworkOfferingVO offering, DeploymentPlan plan, String name, String displayText, boolean isDefault) + public List setupNetwork(Account owner, NetworkOfferingVO offering, DeploymentPlan plan, String name, + String displayText, boolean isDefault) throws ConcurrentOperationException { - return setupNetwork(owner, offering, null, plan, name, displayText, false, null, null, null); + return setupNetwork(owner, offering, null, plan, name, displayText, false, null, null, null, null); } @Override @DB - public List setupNetwork(Account owner, NetworkOfferingVO offering, Network predefined, DeploymentPlan plan, String name, String displayText, boolean errorIfAlreadySetup, Long domainId, - ACLType aclType, Boolean subdomainAccess) throws ConcurrentOperationException { + public List setupNetwork(Account owner, NetworkOfferingVO offering, Network predefined, DeploymentPlan + plan, String name, String displayText, boolean errorIfAlreadySetup, Long domainId, + ACLType aclType, Boolean subdomainAccess, Long vpcId) throws ConcurrentOperationException { + Account locked = _accountDao.acquireInLockTable(owner.getId()); if (locked == null) { throw new ConcurrentOperationException("Unable to acquire lock on " + owner); @@ -1452,7 +1635,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag try { if (predefined == null - || (offering.getTrafficType() != TrafficType.Guest && predefined.getCidr() == null && predefined.getBroadcastUri() == null && predefined.getBroadcastDomainType() != BroadcastDomainType.Vlan)) { + || (offering.getTrafficType() != TrafficType.Guest && predefined.getCidr() == null + && predefined.getBroadcastUri() == null && predefined.getBroadcastDomainType() != BroadcastDomainType.Vlan)) { List configs = _networksDao.listBy(owner.getId(), offering.getId(), plan.getDataCenterId()); if (configs.size() > 0) { if (s_logger.isDebugEnabled()) { @@ -1460,7 +1644,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } if (errorIfAlreadySetup) { - throw new InvalidParameterValueException("Found existing network configuration for offering " + offering + ": " + configs.get(0)); + throw new InvalidParameterValueException("Found existing network configuration for offering " + + offering + ": " + configs.get(0)); } else { return configs; } @@ -1474,7 +1659,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } if (errorIfAlreadySetup) { - throw new InvalidParameterValueException("Found existing network configuration for offering " + offering + ": " + configs.get(0)); + throw new InvalidParameterValueException("Found existing network configuration for offering " + + offering + ": " + configs.get(0)); } else { return configs; } @@ -1508,9 +1694,11 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag Transaction txn = Transaction.currentTxn(); txn.start(); - NetworkVO vo = new NetworkVO(id, network, offering.getId(), guru.getName(), owner.getDomainId(), owner.getId(), related, name, displayText, predefined.getNetworkDomain(), - offering.getGuestType(), plan.getDataCenterId(), plan.getPhysicalNetworkId(), aclType, offering.getSpecifyIpRanges()); - networks.add(_networksDao.persist(vo, vo.getGuestType() == Network.GuestType.Isolated, finalizeServicesAndProvidersForNetwork(offering, plan.getPhysicalNetworkId()))); + NetworkVO vo = new NetworkVO(id, network, offering.getId(), guru.getName(), owner.getDomainId(), owner.getId(), + related, name, displayText, predefined.getNetworkDomain(), offering.getGuestType(), + plan.getDataCenterId(), plan.getPhysicalNetworkId(), aclType, offering.getSpecifyIpRanges(), vpcId); + networks.add(_networksDao.persist(vo, vo.getGuestType() == Network.GuestType.Isolated, + finalizeServicesAndProvidersForNetwork(offering, plan.getPhysicalNetworkId()))); if (domainId != null && aclType == ACLType.Domain) { _networksDao.addDomainToNetwork(id, domainId, subdomainAccess); @@ -1548,7 +1736,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Override @DB - public void allocate(VirtualMachineProfile vm, List> networks) throws InsufficientCapacityException, ConcurrentOperationException { + public void allocate(VirtualMachineProfile vm, List> networks) + throws InsufficientCapacityException, ConcurrentOperationException { Transaction txn = Transaction.currentTxn(); txn.start(); @@ -1557,63 +1746,53 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag boolean[] deviceIds = new boolean[networks.size()]; Arrays.fill(deviceIds, false); - List nics = new ArrayList(networks.size()); - NicVO defaultNic = null; + List nics = new ArrayList(networks.size()); + NicProfile defaultNic = null; for (Pair network : networks) { NetworkVO config = network.first(); - NetworkGuru guru = _networkGurus.get(config.getGuruName()); NicProfile requested = network.second(); - if (requested != null && requested.getMode() == null) { - requested.setMode(config.getMode()); - } - NicProfile profile = guru.allocate(config, requested, vm); - if (vm != null && vm.getVirtualMachine().getType() == Type.User && (requested != null && requested.isDefaultNic())) { - profile.setDefaultNic(true); + Boolean isDefaultNic = false; + if (vm != null && (requested != null && requested.isDefaultNic())) { + isDefaultNic = true; } - if (profile == null) { - continue; - } - - if (requested != null && requested.getMode() == null) { - profile.setMode(requested.getMode()); - } else { - profile.setMode(config.getMode()); - } - - NicVO vo = new NicVO(guru.getName(), vm.getId(), config.getId(), vm.getType()); - while (deviceIds[deviceId] && deviceId < deviceIds.length) { deviceId++; } - deviceId = applyProfileToNic(vo, profile, deviceId); + Pair vmNicPair = allocateNic(requested, config, isDefaultNic, + deviceId, vm); - vo = _nicDao.persist(vo); - - if (vo.isDefaultNic()) { - if (defaultNic != null) { - throw new IllegalArgumentException("You cannot specify two nics as default nics: nic 1 = " + defaultNic + "; nic 2 = " + vo); - } - defaultNic = vo; + NicProfile vmNic = vmNicPair.first(); + if (vmNic == null) { + continue; } - int devId = vo.getDeviceId(); + deviceId = vmNicPair.second(); + + int devId = vmNic.getDeviceId(); if (devId > deviceIds.length) { - throw new IllegalArgumentException("Device id for nic is too large: " + vo); + throw new IllegalArgumentException("Device id for nic is too large: " + vmNic); } if (deviceIds[devId]) { - throw new IllegalArgumentException("Conflicting device id for two different nics: " + devId); + throw new IllegalArgumentException("Conflicting device id for two different nics: " + vmNic); } deviceIds[devId] = true; - nics.add(vo); - Integer networkRate = getNetworkRate(config.getId(), vm.getId()); - vm.addNic(new NicProfile(vo, network.first(), vo.getBroadcastUri(), vo.getIsolationUri(), networkRate, isSecurityGroupSupportedInNetwork(network.first()), getNetworkTag(vm.getHypervisorType(), - network.first()))); + if (vmNic.isDefaultNic()) { + if (defaultNic != null) { + throw new IllegalArgumentException("You cannot specify two nics as default nics: nic 1 = " + + defaultNic + "; nic 2 = " + vmNic); + } + defaultNic = vmNic; + } + + nics.add(vmNic); + vm.addNic(vmNic); + } if (nics.size() != networks.size()) { @@ -1628,6 +1807,49 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag txn.commit(); } + + @DB + @Override + public Pair allocateNic(NicProfile requested, Network network, Boolean isDefaultNic, + int deviceId, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapcityException, + InsufficientAddressCapacityException, ConcurrentOperationException{ + + NetworkVO ntwkVO = _networksDao.findById(network.getId()); + s_logger.debug("Allocating nic for vm " + vm.getVirtualMachine() + " in network " + network); + NetworkGuru guru = _networkGurus.get(ntwkVO.getGuruName()); + + if (requested != null && requested.getMode() == null) { + requested.setMode(network.getMode()); + } + NicProfile profile = guru.allocate(network, requested, vm); + if (isDefaultNic != null) { + profile.setDefaultNic(isDefaultNic); + } + + if (profile == null) { + return null; + } + + if (requested != null && requested.getMode() == null) { + profile.setMode(requested.getMode()); + } else { + profile.setMode(network.getMode()); + } + + NicVO vo = new NicVO(guru.getName(), vm.getId(), network.getId(), vm.getType()); + + deviceId = applyProfileToNic(vo, profile, deviceId); + + vo = _nicDao.persist(vo); + + Integer networkRate = getNetworkRate(network.getId(), vm.getId()); + NicProfile vmNic = new NicProfile(vo, network, vo.getBroadcastUri(), vo.getIsolationUri(), networkRate, + isSecurityGroupSupportedInNetwork(network), getNetworkTag(vm.getHypervisorType(), + network)); + + return new Pair(vmNic, Integer.valueOf(deviceId)); + } + protected Integer applyProfileToNic(NicVO vo, NicProfile profile, Integer deviceId) { if (profile.getDeviceId() != null) { vo.setDeviceId(profile.getDeviceId()); @@ -1718,7 +1940,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Override @DB - public Pair implementNetwork(long networkId, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, + public Pair implementNetwork(long networkId, DeployDestination dest, ReservationContext context) + throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { Transaction.currentTxn(); Pair implemented = new Pair(null, null); @@ -1775,25 +1998,45 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag shutdownNetwork(networkId, context, false); } + if (s_logger.isDebugEnabled()) { + s_logger.debug("Releasing lock for network id " + networkId); + } _networksDao.releaseFromLockTable(networkId); } } - private void implementNetworkElementsAndResources(DeployDestination dest, ReservationContext context, NetworkVO network, NetworkOfferingVO offering) + private void implementNetworkElementsAndResources(DeployDestination dest, ReservationContext context, + NetworkVO network, NetworkOfferingVO offering) throws ConcurrentOperationException, InsufficientAddressCapacityException, ResourceUnavailableException, InsufficientCapacityException { // If this is a 1) guest virtual network 2) network has sourceNat service 3) network offering does not support a -// Shared source NAT rule, + // Shared source NAT rule, // associate a source NAT IP (if one isn't already associated with the network) boolean sharedSourceNat = offering.getSharedSourceNat(); - if (network.getGuestType() == Network.GuestType.Isolated && areServicesSupportedInNetwork(network.getId(), Service.SourceNat) && !sharedSourceNat) { - List ips = _ipAddressDao.listByAssociatedNetwork(network.getId(), true); + if (network.getGuestType() == Network.GuestType.Isolated + && areServicesSupportedInNetwork(network.getId(), Service.SourceNat) + && !sharedSourceNat) { + + List ips = null; + Vpc vpc = null; + if (network.getVpcId() != null) { + vpc = _vpcMgr.getVpc(network.getVpcId()); + ips = _ipAddressDao.listByAssociatedVpc(vpc.getId(), true); + } else { + ips = _ipAddressDao.listByAssociatedNetwork(network.getId(), true); + } + if (ips.isEmpty()) { - s_logger.debug("Creating a source nat ip for " + network); + String target = vpc != null ? vpc.toString() : network.toString(); + s_logger.debug("Creating a source nat ip for " + target); Account owner = _accountMgr.getAccount(network.getAccountId()); - assignSourceNatIpAddress(owner, network, context.getCaller().getId()); + if (vpc != null) { + assignSourceNatIpAddressToVpc(owner, vpc); + } else { + assignSourceNatIpAddressToGuestNetwork(owner, network); + } } } @@ -1827,7 +2070,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } } - protected void prepareElement(NetworkElement element, NetworkVO network, NicProfile profile, VirtualMachineProfile vmProfile, + protected void prepareElement(NetworkElement element, NetworkVO network, + NicProfile profile, VirtualMachineProfile vmProfile, DeployDestination dest, ReservationContext context) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { element.prepare(network, profile, vmProfile, dest, context); @@ -1871,9 +2115,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag List nics = _nicDao.listByVmId(vmProfile.getId()); // we have to implement default nics first - to ensure that default network elements start up first in multiple -// nics - // case) - // (need for setting DNS on Dhcp to domR's Ip4 address) + // nics case)(need for setting DNS on Dhcp to domR's Ip4 address) Collections.sort(nics, new Comparator() { @Override @@ -1887,9 +2129,23 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag for (NicVO nic : nics) { Pair implemented = implementNetwork(nic.getNetworkId(), dest, context); - NetworkGuru guru = implemented.first(); + NetworkVO network = implemented.second(); + NicProfile profile = prepareNic(vmProfile, dest, context, nic.getId(), network); + vmProfile.addNic(profile); + } + } + + @Override + public NicProfile prepareNic(VirtualMachineProfile vmProfile, DeployDestination + dest, ReservationContext context, long nicId, NetworkVO network) + throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException, + ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { + Integer networkRate = getNetworkRate(network.getId(), vmProfile.getId()); + NetworkGuru guru = _networkGurus.get(network.getGuruName()); + NicVO nic = _nicDao.findById(nicId); + NicProfile profile = null; if (nic.getReservationStrategy() == Nic.ReservationStrategy.Start) { nic.setState(Nic.State.Reserving); @@ -1902,7 +2158,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag URI isolationUri = nic.getIsolationUri(); - profile = new NicProfile(nic, network, broadcastUri, isolationUri, networkRate, isSecurityGroupSupportedInNetwork(network), getNetworkTag(vmProfile.getHypervisorType(), network)); + profile = new NicProfile(nic, network, broadcastUri, isolationUri, + networkRate, isSecurityGroupSupportedInNetwork(network), getNetworkTag(vmProfile.getHypervisorType(), network)); guru.reserve(profile, network, vmProfile, dest, context); nic.setIp4Address(profile.getIp4Address()); nic.setAddressFormat(profile.getFormat()); @@ -1921,7 +2178,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag updateNic(nic, network.getId(), 1); } else { - profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), networkRate, isSecurityGroupSupportedInNetwork(network), getNetworkTag(vmProfile.getHypervisorType(), network)); + profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), + networkRate, isSecurityGroupSupportedInNetwork(network), getNetworkTag(vmProfile.getHypervisorType(), network)); guru.updateNicProfile(profile, network); nic.setState(Nic.State.Reserved); updateNic(nic, network.getId(), 1); @@ -1936,8 +2194,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag profile.setSecurityGroupEnabled(isSecurityGroupSupportedInNetwork(network)); guru.updateNicProfile(profile, network); - vmProfile.addNic(profile); - } + return profile; } @Override @@ -1948,7 +2205,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag Integer networkRate = getNetworkRate(network.getId(), vm.getId()); NetworkGuru guru = _networkGurus.get(network.getGuruName()); - NicProfile profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), networkRate, isSecurityGroupSupportedInNetwork(network), getNetworkTag(vm.getHypervisorType(), network)); + NicProfile profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), networkRate, + isSecurityGroupSupportedInNetwork(network), getNetworkTag(vm.getHypervisorType(), network)); guru.updateNicProfile(profile, network); vm.addNic(profile); } @@ -1960,13 +2218,44 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag List nics = _nicDao.listByVmId(vmProfile.getId()); for (NicVO nic : nics) { NetworkVO network = _networksDao.findById(nic.getNetworkId()); + releaseNic(vmProfile, nic, network); + } + } + + @Override + public NicProfile releaseNic(VirtualMachineProfile vmProfile, NetworkVO network) + throws ConcurrentOperationException, ResourceUnavailableException { + NicVO nic = _nicDao.findByInstanceIdAndNetworkId(network.getId(), vmProfile.getId()); + releaseNic(vmProfile, nic, network); + + NicProfile profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), null, + isSecurityGroupSupportedInNetwork(network), getNetworkTag(vmProfile.getVirtualMachine().getHypervisorType(), network)); + return profile; + } + + + @Override + public NicProfile releaseNic(VirtualMachineProfile vmProfile, NetworkVO network, URI broadcastUri) + throws ConcurrentOperationException, ResourceUnavailableException { + NicVO nic = _nicDao.findByInstanceIdNetworkIdAndBroadcastUri(network.getId(), vmProfile.getId(), broadcastUri.toString()); + releaseNic(vmProfile, nic, network); + + NicProfile profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), null, + isSecurityGroupSupportedInNetwork(network), getNetworkTag(vmProfile.getVirtualMachine().getHypervisorType(), network)); + return profile; + } + + + protected void releaseNic(VirtualMachineProfile vmProfile, NicVO nic, NetworkVO network) + throws ConcurrentOperationException, ResourceUnavailableException { if (nic.getState() == Nic.State.Reserved || nic.getState() == Nic.State.Reserving) { Nic.State originalState = nic.getState(); if (nic.getReservationStrategy() == Nic.ReservationStrategy.Start) { NetworkGuru guru = _networkGurus.get(network.getGuruName()); nic.setState(Nic.State.Releasing); _nicDao.update(nic.getId(), nic); - NicProfile profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), null, isSecurityGroupSupportedInNetwork(network), getNetworkTag(vmProfile.getHypervisorType(), network)); + NicProfile profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), null, + isSecurityGroupSupportedInNetwork(network), getNetworkTag(vmProfile.getHypervisorType(), network)); if (guru.release(profile, vmProfile, nic.getReservationId())) { applyProfileToNicForRelease(nic, profile); nic.setState(Nic.State.Allocated); @@ -1992,7 +2281,6 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } } } - } @Override public List getNics(long vmId) { @@ -2010,7 +2298,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag Integer networkRate = getNetworkRate(network.getId(), vm.getId()); NetworkGuru guru = _networkGurus.get(network.getGuruName()); - NicProfile profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), networkRate, isSecurityGroupSupportedInNetwork(network), getNetworkTag(vm.getHypervisorType(), network)); + NicProfile profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), + networkRate, isSecurityGroupSupportedInNetwork(network), getNetworkTag(vm.getHypervisorType(), network)); guru.updateNicProfile(profile, network); profiles.add(profile); } @@ -2018,10 +2307,24 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return profiles; } + @Override + public NicProfile getNicProfile(VirtualMachine vm, long networkId) { + NicVO nic = _nicDao.findByInstanceIdAndNetworkId(networkId, vm.getId()); + NetworkVO network = _networksDao.findById(networkId); + Integer networkRate = getNetworkRate(network.getId(), vm.getId()); + + NetworkGuru guru = _networkGurus.get(network.getGuruName()); + NicProfile profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), + networkRate, isSecurityGroupSupportedInNetwork(network), getNetworkTag(vm.getHypervisorType(), network)); + guru.updateNicProfile(profile, network); + + return profile; + } + @Override @DB @ActionEvent(eventType = EventTypes.EVENT_NET_IP_RELEASE, eventDescription = "disassociating Ip", async = true) - public boolean disassociateIpAddress(long ipAddressId) throws InsufficientAddressCapacityException { + public boolean releaseIpAddress(long ipAddressId) throws InsufficientAddressCapacityException { Long userId = UserContext.current().getCallerUserId(); Account caller = UserContext.current().getCaller(); @@ -2043,9 +2346,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag _accountMgr.checkAccess(caller, null, true, ipVO); } - Network associatedNetwork = getNetwork(ipVO.getAssociatedWithNetworkId()); - - if (ipVO.isSourceNat() && areServicesSupportedInNetwork(associatedNetwork.getId(), Service.SourceNat)) { + if (ipVO.isSourceNat()) { throw new IllegalArgumentException("ip address is used for source nat purposes and can not be disassociated."); } @@ -2057,7 +2358,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag // Check for account wide pool. It will have an entry for account_vlan_map. if (_accountVlanMapDao.findAccountVlanMap(ipVO.getAllocatedToAccountId(), ipVO.getVlanId()) != null) { //see IPaddressVO.java - InvalidParameterValueException ex = new InvalidParameterValueException("Sepcified IP address uuid belongs to Account wide IP pool and cannot be disassociated"); + InvalidParameterValueException ex = new InvalidParameterValueException("Sepcified IP address uuid belongs to" + + " Account wide IP pool and cannot be disassociated"); ex.addProxyObject("user_ip_address", ipAddressId, "ipAddressId"); throw ex; } @@ -2067,9 +2369,11 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag throw new InvalidParameterValueException("Can't release system IP address " + ipVO); } - boolean success = releasePublicIpAddress(ipAddressId, userId, caller); - if (success) { - Network guestNetwork = getNetwork(ipVO.getAssociatedWithNetworkId()); + boolean success = disassociatePublicIpAddress(ipAddressId, userId, caller); + + Long networkId = ipVO.getAssociatedWithNetworkId(); + if (success && networkId != null) { + Network guestNetwork = getNetwork(networkId); NetworkOffering offering = _configMgr.getNetworkOffering(guestNetwork.getNetworkOfferingId()); Long vmId = ipVO.getAssociatedWithVmId(); if (offering.getElasticIp() && vmId != null) { @@ -2137,14 +2441,26 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag List nics = _nicDao.listByVmId(vm.getId()); for (NicVO nic : nics) { + removeNic(vm, nic); + } + } + + @Override + public void removeNic(VirtualMachineProfile vm, Network network) { + NicVO nic = _nicDao.findByInstanceIdAndNetworkId(network.getId(), vm.getVirtualMachine().getId()); + removeNic(vm, nic); + } + + protected void removeNic(VirtualMachineProfile vm, NicVO nic) { nic.setState(Nic.State.Deallocating); _nicDao.update(nic.getId(), nic); NetworkVO network = _networksDao.findById(nic.getNetworkId()); - NicProfile profile = new NicProfile(nic, network, null, null, null, isSecurityGroupSupportedInNetwork(network), getNetworkTag(vm.getHypervisorType(), network)); + NicProfile profile = new NicProfile(nic, network, null, null, null, + isSecurityGroupSupportedInNetwork(network), getNetworkTag(vm.getHypervisorType(), network)); NetworkGuru guru = _networkGurus.get(network.getGuruName()); guru.deallocate(network, profile, vm); _nicDao.remove(nic.getId()); - } + s_logger.debug("Removed nic id=" + nic.getId()); } @Override @@ -2211,7 +2527,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Override @DB @ActionEvent(eventType = EventTypes.EVENT_NETWORK_CREATE, eventDescription = "creating network") - public Network createNetwork(CreateNetworkCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException { + public Network createGuestNetwork(CreateNetworkCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException { Long networkOfferingId = cmd.getNetworkOfferingId(); String gateway = cmd.getGateway(); String startIP = cmd.getStartIp(); @@ -2221,7 +2537,6 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag String vlanId = cmd.getVlan(); String name = cmd.getNetworkName(); String displayText = cmd.getDisplayText(); - Long userId = UserContext.current().getCallerUserId(); Account caller = UserContext.current().getCaller(); Long physicalNetworkId = cmd.getPhysicalNetworkId(); Long zoneId = cmd.getZoneId(); @@ -2229,6 +2544,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag Long domainId = cmd.getDomainId(); boolean isDomainSpecific = false; Boolean subdomainAccess = cmd.getSubdomainAccess(); + Long vpcId = cmd.getVpcId(); // Validate network offering NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId); @@ -2261,6 +2577,15 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag throw ex; } + //validate vpc + if (vpcId != null) { + Vpc vpc = _vpcMgr.getActiveVpc(vpcId); + if (vpc == null) { + throw new InvalidParameterValueException("Unable to find enabled vpc by id " + vpcId); + } + _accountMgr.checkAccess(caller, null, false, vpc); + } + // Only domain and account ACL types are supported in Acton. ACLType aclType = null; if (aclTypeStr != null) { @@ -2278,7 +2603,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } } else if (ntwkOff.getGuestType() == GuestType.Shared) { if (!(aclType == ACLType.Domain || aclType == ACLType.Account)) { - throw new InvalidParameterValueException("AclType should be " + ACLType.Domain + " or " + ACLType.Account + " for network of type " + Network.GuestType.Shared); + throw new InvalidParameterValueException("AclType should be " + ACLType.Domain + " or " + + ACLType.Account + " for network of type " + Network.GuestType.Shared); } } } else { @@ -2308,7 +2634,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (domainId != null) { if (ntwkOff.getTrafficType() != TrafficType.Guest || ntwkOff.getGuestType() != Network.GuestType.Shared) { - throw new InvalidParameterValueException("Domain level networks are supported just for traffic type " + TrafficType.Guest + " and guest type " + Network.GuestType.Shared); + throw new InvalidParameterValueException("Domain level networks are supported just for traffic type " + + TrafficType.Guest + " and guest type " + Network.GuestType.Shared); } DomainVO domain = _domainDao.findById(domainId); @@ -2369,7 +2696,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL && (ntwkOff.getTrafficType() != TrafficType.Guest || ntwkOff.getGuestType() != Network.GuestType.Isolated && areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat))) { - throw new InvalidParameterValueException("Regular user can create a network only from the network offering having traffic type " + TrafficType.Guest + " and network type " + throw new InvalidParameterValueException("Regular user can create a network only from the network" + + " offering having traffic type " + TrafficType.Guest + " and network type " + Network.GuestType.Isolated + " with a service " + Service.SourceNat.getName() + " enabled"); } @@ -2401,7 +2729,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag // 2) GuestType is Isolated, but SourceNat service is disabled boolean createVlan = (startIP != null && endIP != null && zone.getNetworkType() == NetworkType.Advanced && ((ntwkOff.getGuestType() == Network.GuestType.Shared) - || (ntwkOff.getGuestType() == GuestType.Isolated && !areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat)))); + || (ntwkOff.getGuestType() == GuestType.Isolated && + !areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat)))); // Can add vlan range only to the network which allows it if (createVlan && !ntwkOff.getSpecifyIpRanges()) { @@ -2426,11 +2755,20 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag owner = _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM); } - Network network = createGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, networkDomain, owner, false, sharedDomainId, pNtwk, zoneId, aclType, subdomainAccess); + //Create guest network + Network network = null; + if (vpcId != null) { + network = createVpcGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, + networkDomain, owner, sharedDomainId, pNtwk, zoneId, aclType, subdomainAccess, vpcId); + } else { + network = createGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, + networkDomain, owner, sharedDomainId, pNtwk, zoneId, aclType, subdomainAccess, vpcId); + } if (caller.getType() == Account.ACCOUNT_TYPE_ADMIN && createVlan) { // Create vlan ip range - _configMgr.createVlanAndPublicIpRange(pNtwk.getDataCenterId(), network.getId(), physicalNetworkId, false, null, startIP, endIP, gateway, netmask, vlanId, null); + _configMgr.createVlanAndPublicIpRange(pNtwk.getDataCenterId(), network.getId(), physicalNetworkId, + false, null, startIP, endIP, gateway, netmask, vlanId, null); } txn.commit(); @@ -2438,10 +2776,33 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return network; } + @DB + protected Network createVpcGuestNetwork(long ntwkOffId, String name, String displayText, String gateway, + String cidr, String vlanId, String networkDomain, Account owner, Long domainId, + PhysicalNetwork pNtwk, long zoneId, ACLType aclType, Boolean subdomainAccess, long vpcId) + throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException { + + Vpc vpc = _vpcMgr.getActiveVpc(vpcId); + //1) Validate if network can be created for VPC + _vpcMgr.validateGuestNtkwForVpc(_configMgr.getNetworkOffering(ntwkOffId), cidr, networkDomain, owner, vpc); + + if (networkDomain == null) { + networkDomain = vpc.getNetworkDomain(); + } + + //2) Create network + Network guestNetwork = createGuestNetwork(ntwkOffId, name, displayText, gateway, cidr, vlanId, + networkDomain, owner, domainId, pNtwk, zoneId, aclType, subdomainAccess, vpcId); + + return guestNetwork; + } + @Override @DB - public Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, String networkDomain, Account owner, boolean isSecurityGroupEnabled, - Long domainId, PhysicalNetwork pNtwk, long zoneId, ACLType aclType, Boolean subdomainAccess) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException { + public Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, + String cidr, String vlanId, String networkDomain, Account owner, Long domainId, + PhysicalNetwork pNtwk, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId) + throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException { NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId); // this method supports only guest network creation @@ -2459,7 +2820,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag // Validate network offering if (ntwkOff.getState() != NetworkOffering.State.Enabled) { // see NetworkOfferingVO - InvalidParameterValueException ex = new InvalidParameterValueException("Can't use specified network offering id as its stat is not " + NetworkOffering.State.Enabled); + InvalidParameterValueException ex = new InvalidParameterValueException("Can't use specified network " + + "offering id as its stat is not " + NetworkOffering.State.Enabled); ex.addProxyObject("network_offerings", networkOfferingId, "networkOfferingId"); throw ex; } @@ -2467,7 +2829,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag // Validate physical network if (pNtwk.getState() != PhysicalNetwork.State.Enabled) { // see PhysicalNetworkVO.java - InvalidParameterValueException ex = new InvalidParameterValueException("Specified physical network id is in incorrect state:" + pNtwk.getState()); + InvalidParameterValueException ex = new InvalidParameterValueException("Specified physical network id is" + + " in incorrect state:" + pNtwk.getState()); ex.addProxyObject("physical_network", pNtwk.getId(), "physicalNetworkId"); throw ex; } @@ -2483,12 +2846,15 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag // Only one guest network is supported in Basic zone List guestNetworks = _networksDao.listByZoneAndTrafficType(zone.getId(), TrafficType.Guest); if (!guestNetworks.isEmpty()) { - throw new InvalidParameterValueException("Can't have more than one Guest network in zone with network type " + NetworkType.Basic); + throw new InvalidParameterValueException("Can't have more than one Guest network in zone with network type " + + NetworkType.Basic); } // if zone is basic, only Shared network offerings w/o source nat service are allowed - if (!(ntwkOff.getGuestType() == GuestType.Shared && !areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat))) { - throw new InvalidParameterValueException("For zone of type " + NetworkType.Basic + " only offerings of guestType " + GuestType.Shared + " with disabled " + Service.SourceNat.getName() + if (!(ntwkOff.getGuestType() == GuestType.Shared && + !areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat))) { + throw new InvalidParameterValueException("For zone of type " + NetworkType.Basic + " only offerings of " + + "guestType " + GuestType.Shared + " with disabled " + Service.SourceNat.getName() + " service are allowed"); } @@ -2499,14 +2865,16 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (subdomainAccess == null) { subdomainAccess = true; } else if (!subdomainAccess) { - throw new InvalidParameterValueException("Subdomain access should be set to true for the guest network in the Basic zone"); + throw new InvalidParameterValueException("Subdomain access should be set to true for the" + + " guest network in the Basic zone"); } if (vlanId == null) { vlanId = Vlan.UNTAGGED; } else { if (!vlanId.equalsIgnoreCase(Vlan.UNTAGGED)) { - throw new InvalidParameterValueException("Only vlan " + Vlan.UNTAGGED + " can be created in the zone of type " + NetworkType.Basic); + throw new InvalidParameterValueException("Only vlan " + Vlan.UNTAGGED + " can be created in " + + "the zone of type " + NetworkType.Basic); } } @@ -2514,9 +2882,11 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (zone.isSecurityGroupEnabled()) { // Only Account specific Isolated network with sourceNat service disabled are allowed in security group // enabled zone - boolean allowCreation = (ntwkOff.getGuestType() == GuestType.Isolated && !areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat)); + boolean allowCreation = (ntwkOff.getGuestType() == GuestType.Isolated + && !areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat)); if (!allowCreation) { - throw new InvalidParameterValueException("Only Account specific Isolated network with sourceNat service disabled are allowed in security group enabled zone"); + throw new InvalidParameterValueException("Only Account specific Isolated network with sourceNat " + + "service disabled are allowed in security group enabled zone"); } } } @@ -2541,11 +2911,13 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } // If networkDomain is not specified, take it from the global configuration if (areServicesSupportedByNetworkOffering(networkOfferingId, Service.Dns)) { - Map dnsCapabilities = getNetworkOfferingServiceCapabilities(_configMgr.getNetworkOffering(networkOfferingId), Service.Dns); + Map dnsCapabilities = getNetworkOfferingServiceCapabilities + (_configMgr.getNetworkOffering(networkOfferingId), Service.Dns); String isUpdateDnsSupported = dnsCapabilities.get(Capability.AllowDnsSuffixModification); if (isUpdateDnsSupported == null || !Boolean.valueOf(isUpdateDnsSupported)) { if (networkDomain != null) { - throw new InvalidParameterValueException("Domain name change is not supported by network offering id=" + networkOfferingId + " in zone id=" + zoneId); + throw new InvalidParameterValueException("Domain name change is not supported by network offering id=" + + networkOfferingId + " in zone id=" + zoneId); } } else { if (networkDomain == null) { @@ -2565,7 +2937,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag // validate network domain if (!NetUtils.verifyDomainName(networkDomain)) { throw new InvalidParameterValueException( - "Invalid network domain. Total length shouldn't exceed 190 chars. Each domain label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', " + "Invalid network domain. Total length shouldn't exceed 190 chars. Each domain " + + "label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', " + "and the hyphen ('-'); can't start or end with \"-\""); } } @@ -2576,9 +2949,11 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag // limitation, remove after we introduce support for multiple ip ranges // with different Cidrs for the same Shared network boolean cidrRequired = zone.getNetworkType() == NetworkType.Advanced && ntwkOff.getTrafficType() == TrafficType.Guest - && (ntwkOff.getGuestType() == GuestType.Shared || (ntwkOff.getGuestType() == GuestType.Isolated && !areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat))); + && (ntwkOff.getGuestType() == GuestType.Shared || (ntwkOff.getGuestType() == GuestType.Isolated + && !areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat))); if (cidr == null && cidrRequired) { - throw new InvalidParameterValueException("StartIp/endIp/gateway/netmask are required when create network of type " + Network.GuestType.Shared + " and network of type " + GuestType.Isolated + " with service " + throw new InvalidParameterValueException("StartIp/endIp/gateway/netmask are required when create network of" + + " type " + Network.GuestType.Shared + " and network of type " + GuestType.Isolated + " with service " + Service.SourceNat.getName() + " disabled"); } @@ -2619,13 +2994,15 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } } - List networks = setupNetwork(owner, ntwkOff, userNetwork, plan, name, displayText, true, domainId, aclType, subdomainAccess); + List networks = setupNetwork(owner, ntwkOff, userNetwork, plan, name, displayText, true, domainId, + aclType, subdomainAccess, vpcId); Network network = null; if (networks == null || networks.isEmpty()) { throw new CloudRuntimeException("Fail to create a network"); } else { - if (networks.size() > 0 && networks.get(0).getGuestType() == Network.GuestType.Isolated && networks.get(0).getTrafficType() == TrafficType.Guest) { + if (networks.size() > 0 && networks.get(0).getGuestType() == Network.GuestType.Isolated && + networks.get(0).getTrafficType() == TrafficType.Guest) { Network defaultGuestNetwork = networks.get(0); for (Network nw : networks) { if (nw.getCidr() != null && nw.getCidr().equals(zone.getGuestNetworkCidr())) { @@ -2669,6 +3046,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag boolean listAll = cmd.listAll(); boolean isRecursive = cmd.isRecursive(); Boolean specifyIpRanges = cmd.getSpecifyIpRanges(); + Long vpcId = cmd.getVpcId(); // 1) default is system to false if not specified // 2) reset parameter to false if it's specified by the regular user @@ -2779,21 +3157,25 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (domainId != null) { networksToReturn .addAll(listDomainLevelNetworks( - buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges), searchFilter, + buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, + physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId), searchFilter, domainId)); } if (!permittedAccounts.isEmpty()) { networksToReturn.addAll(listAccountSpecificNetworks( - buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges), searchFilter, + buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, + physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId), searchFilter, permittedAccounts)); } else if (domainId == null || listAll) { networksToReturn.addAll(listAccountSpecificNetworksByDomainPath( - buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges), searchFilter, path, + buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, + physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId), searchFilter, path, isRecursive)); } } else { - networksToReturn = _networksDao.search(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, null, skipProjectNetworks, restartRequired, specifyIpRanges), + networksToReturn = _networksDao.search(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, + guestIpType, trafficType, physicalNetworkId, null, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId), searchFilter); } @@ -2823,8 +3205,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } } - private SearchCriteria buildNetworkSearchCriteria(SearchBuilder sb, String keyword, Long id, Boolean isSystem, Long zoneId, String guestIpType, String trafficType, Long physicalNetworkId, - String aclType, boolean skipProjectNetworks, Boolean restartRequired, Boolean specifyIpRanges) { + private SearchCriteria buildNetworkSearchCriteria(SearchBuilder sb, String keyword, Long id, + Boolean isSystem, Long zoneId, String guestIpType, String trafficType, Long physicalNetworkId, + String aclType, boolean skipProjectNetworks, Boolean restartRequired, Boolean specifyIpRanges, Long vpcId) { SearchCriteria sc = sb.create(); if (isSystem != null) { @@ -2873,6 +3256,10 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag sc.addAnd("specifyIpRanges", SearchCriteria.Op.EQ, specifyIpRanges); } + if (vpcId != null) { + sc.addAnd("vpcId", SearchCriteria.Op.EQ, vpcId); + } + return sc; } @@ -2942,7 +3329,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } // don't allow to delete system network - if (isNetworkSystem(network)) { + if (isNetworkSystem(network) && network.getTrafficType() != TrafficType.Guest) { throw new InvalidParameterValueException("Network " + network + " is system and can't be removed"); } @@ -3007,7 +3394,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag private boolean shutdownNetworkElementsAndResources(ReservationContext context, boolean cleanupElements, NetworkVO network) { // 1) Cleanup all the rules for the network. If it fails, just log the failure and proceed with shutting down -// the elements + // the elements boolean cleanupResult = true; try { cleanupResult = shutdownNetworkResources(network.getId(), context.getAccount(), context.getCaller().getId()); @@ -3164,15 +3551,27 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return success; } - private boolean deleteVlansInNetwork(long networkId, long userId, Account callerAccount) { - List vlans = _vlanDao.listVlansByNetworkId(networkId); + protected boolean deleteVlansInNetwork(long networkId, long userId, Account callerAccount) { + + //cleanup Public vlans + List publicVlans = _vlanDao.listVlansByNetworkId(networkId); boolean result = true; - for (VlanVO vlan : vlans) { + for (VlanVO vlan : publicVlans) { if (!_configMgr.deleteVlanAndPublicIpRange(_accountMgr.getSystemUser().getId(), vlan.getId(), callerAccount)) { s_logger.warn("Failed to delete vlan " + vlan.getId() + ");"); result = false; } } + + //cleanup private vlans + int privateIpAllocCount = _privateIpDao.countAllocatedByNetworkId(networkId); + if (privateIpAllocCount > 0) { + s_logger.warn("Can't delete Private ip range for network " + networkId + " as it has allocated ip addresses"); + result = false; + } else { + _privateIpDao.deleteByNetworkId(networkId); + s_logger.debug("Deleted ip range for private network id=" + networkId); + } return result; } @@ -3665,14 +4064,16 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Override public String getIpInNetwork(long vmId, long networkId) { Nic guestNic = getNicInNetwork(vmId, networkId); - assert (guestNic != null && guestNic.getIp4Address() != null) : "Vm doesn't belong to network associated with ipAddress or ip4 address is null"; + assert (guestNic != null && guestNic.getIp4Address() != null) : "Vm doesn't belong to network associated with " + + "ipAddress or ip4 address is null"; return guestNic.getIp4Address(); } @Override public String getIpInNetworkIncludingRemoved(long vmId, long networkId) { Nic guestNic = getNicInNetworkIncludingRemoved(vmId, networkId); - assert (guestNic != null && guestNic.getIp4Address() != null) : "Vm doesn't belong to network associated with ipAddress or ip4 address is null"; + assert (guestNic != null && guestNic.getIp4Address() != null) : "Vm doesn't belong to network associated with " + + "ipAddress or ip4 address is null"; return guestNic.getIp4Address(); } @@ -3701,8 +4102,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag createNetwork = true; } else if (networks.size() == 1) { guestNetwork = networks.get(0); - }else{ - throw new InvalidParameterValueException("Error, more than 1 Guest Isolated Networks with SourceNAT service enabled found for this account, cannot assosiate the IP range, please provide the network ID"); + } else { + throw new InvalidParameterValueException("Error, more than 1 Guest Isolated Networks with SourceNAT " + + "service enabled found for this account, cannot assosiate the IP range, please provide the network ID"); } } @@ -3710,20 +4112,26 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (createNetwork) { List requiredOfferings = _networkOfferingDao.listByAvailability(Availability.Required, false); if (requiredOfferings.size() < 1) { - throw new CloudRuntimeException("Unable to find network offering with availability=" + Availability.Required + " to automatically create the network as part of createVlanIpRange"); + throw new CloudRuntimeException("Unable to find network offering with availability=" + + Availability.Required + " to automatically create the network as part of createVlanIpRange"); } PhysicalNetwork physicalNetwork = translateZoneIdToPhysicalNetwork(zoneId); if (requiredOfferings.get(0).getState() == NetworkOffering.State.Enabled) { - s_logger.debug("Creating network for account " + owner + " from the network offering id=" + requiredOfferings.get(0).getId() + " as a part of createVlanIpRange process"); - guestNetwork = createGuestNetwork(requiredOfferings.get(0).getId(), owner.getAccountName() + "-network", owner.getAccountName() + "-network", null, null, null, null, owner, false, null, physicalNetwork, zoneId, - ACLType.Account, null); + s_logger.debug("Creating network for account " + owner + " from the network offering id=" + + requiredOfferings.get(0).getId() + " as a part of createVlanIpRange process"); + guestNetwork = createGuestNetwork(requiredOfferings.get(0).getId(), owner.getAccountName() + "-network" + , owner.getAccountName() + "-network", null, null, null, null, owner, null, physicalNetwork, + zoneId, ACLType.Account, + null, null); if (guestNetwork == null) { s_logger.warn("Failed to create default Virtual network for the account " + accountId + "in zone " + zoneId); - throw new CloudRuntimeException("Failed to create a Guest Isolated Networks with SourceNAT service enabled as a part of createVlanIpRange, for the account " + accountId + "in zone " + zoneId); + throw new CloudRuntimeException("Failed to create a Guest Isolated Networks with SourceNAT " + + "service enabled as a part of createVlanIpRange, for the account " + accountId + "in zone " + zoneId); } } else { - throw new CloudRuntimeException("Required network offering id=" + requiredOfferings.get(0).getId() + " is not in " + NetworkOffering.State.Enabled); + throw new CloudRuntimeException("Required network offering id=" + requiredOfferings.get(0).getId() + + " is not in " + NetworkOffering.State.Enabled); } } @@ -3746,6 +4154,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag addr.setSourceNat(false); } addr.setAssociatedWithNetworkId(guestNetwork.getId()); + addr.setVpcId(guestNetwork.getVpcId()); addr.setAllocatedTime(new Date()); addr.setAllocatedInDomainId(owner.getDomainId()); addr.setAllocatedToAccountId(owner.getId()); @@ -3989,7 +4398,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag String guestType = vlan.getVlanType().toString(); - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NET_IP_RELEASE, ip.getAllocatedToAccountId(), ip.getDataCenterId(), addrId, ip.getAddress().addr(), ip.isSourceNat(), guestType, ip.getSystem()); + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NET_IP_RELEASE, + ip.getAllocatedToAccountId(), ip.getDataCenterId(), addrId, ip.getAddress().addr(), + ip.isSourceNat(), guestType, ip.getSystem()); _usageEventDao.persist(usageEvent); } @@ -4339,7 +4750,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return networkDomain; } - private String getAccountNetworkDomain(long accountId, long zoneId) { + @Override + public String getAccountNetworkDomain(long accountId, long zoneId) { String networkDomain = _accountDao.findById(accountId).getNetworkDomain(); if (networkDomain == null) { @@ -4398,8 +4810,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } // static NAT rules can not programmed unless IP is associated with network service provider, so run IP -// association for - // the network so as to ensure IP is associated before applying rules (in add state) + // association for the network so as to ensure IP is associated before applying rules (in add state) applyIpAssociations(network, false, continueOnError, publicIps); // get provider @@ -4615,7 +5026,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Override @DB @ActionEvent(eventType = EventTypes.EVENT_PHYSICAL_NETWORK_CREATE, eventDescription = "Creating Physical Network", create = true) - public PhysicalNetwork createPhysicalNetwork(Long zoneId, String vnetRange, String networkSpeed, List isolationMethods, String broadcastDomainRangeStr, Long domainId, List tags, String name) { + public PhysicalNetwork createPhysicalNetwork(Long zoneId, String vnetRange, String networkSpeed, List + isolationMethods, String broadcastDomainRangeStr, Long domainId, List tags, String name) { // Check if zone exists if (zoneId == null) { @@ -4718,6 +5130,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag // add security group provider to the physical network addDefaultSecurityGroupProviderToPhysicalNetwork(pNetwork.getId()); + // add VPCVirtualRouter as the defualt network service provider + addDefaultVpcVirtualRouterToPhysicalNetwork(pNetwork.getId()); + txn.commit(); return pNetwork; } catch (Exception ex) { @@ -5427,9 +5842,11 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag // release all ip addresses List ipsToRelease = _ipAddressDao.listByAssociatedNetwork(networkId, null); for (IPAddressVO ipToRelease : ipsToRelease) { + if (ipToRelease.getVpcId() != null) { IPAddressVO ip = markIpAsUnavailable(ipToRelease.getId()); assert (ip != null) : "Unable to mark the ip address id=" + ipToRelease.getId() + " as unavailable."; } + } try { if (!applyIpAssociations(network, true)) { @@ -6042,7 +6459,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } else { // locate physicalNetwork with supported traffic type // We can make this assumptions based on the fact that Public/Management/Control traffic types are -// supported only in one physical network in the zone in 3.0 + // supported only in one physical network in the zone in 3.0 for (PhysicalNetworkVO pNtwk : pNtwks) { if (_pNTrafficTypeDao.isTrafficTypeSupported(pNtwk.getId(), network.getTrafficType())) { physicalNetworkId = pNtwk.getId(); @@ -6069,8 +6486,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return networks.get(0); } - @Override - public PhysicalNetworkServiceProvider addDefaultVirtualRouterToPhysicalNetwork(long physicalNetworkId) { + protected PhysicalNetworkServiceProvider addDefaultVirtualRouterToPhysicalNetwork(long physicalNetworkId) { PhysicalNetworkServiceProvider nsp = addProviderToPhysicalNetwork(physicalNetworkId, Network.Provider.VirtualRouter.getName(), null, null); // add instance of the provider @@ -6078,15 +6494,29 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (element == null) { throw new CloudRuntimeException("Unable to find the Network Element implementing the VirtualRouter Provider"); } - element.addElement(nsp.getId()); + element.addElement(nsp.getId(), VirtualRouterProviderType.VirtualRouter); return nsp; } - @Override - public PhysicalNetworkServiceProvider addDefaultSecurityGroupProviderToPhysicalNetwork(long physicalNetworkId) { + protected PhysicalNetworkServiceProvider addDefaultVpcVirtualRouterToPhysicalNetwork(long physicalNetworkId) { - PhysicalNetworkServiceProvider nsp = addProviderToPhysicalNetwork(physicalNetworkId, Network.Provider.SecurityGroupProvider.getName(), null, null); + PhysicalNetworkServiceProvider nsp = addProviderToPhysicalNetwork(physicalNetworkId, + Network.Provider.VPCVirtualRouter.getName(), null, null); + // add instance of the provider + VpcVirtualRouterElement element = (VpcVirtualRouterElement) getElementImplementingProvider(Network.Provider.VPCVirtualRouter.getName()); + if (element == null) { + throw new CloudRuntimeException("Unable to find the Network Element implementing the VPCVirtualRouter Provider"); + } + element.addElement(nsp.getId(), VirtualRouterProviderType.VPCVirtualRouter); + + return nsp; + } + + protected PhysicalNetworkServiceProvider addDefaultSecurityGroupProviderToPhysicalNetwork(long physicalNetworkId) { + + PhysicalNetworkServiceProvider nsp = addProviderToPhysicalNetwork(physicalNetworkId, + Network.Provider.SecurityGroupProvider.getName(), null, null); return nsp; } @@ -6111,7 +6541,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag for (NetworkOfferingServiceMapVO serviceMap : servicesMap) { if (svcProviders.containsKey(serviceMap.getService())) { // FIXME - right now we pick up the first provider from the list, need to add more logic based on -// provider load, etc + // provider load, etc continue; } @@ -6125,7 +6555,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag // check that provider is supported if (checkPhysicalNetwork) { if (!_pNSPDao.isServiceProviderEnabled(physicalNetworkId, provider, service)) { - throw new UnsupportedServiceException("Provider " + provider + " is either not enabled or doesn't support service " + service + " in physical network id=" + physicalNetworkId); + throw new UnsupportedServiceException("Provider " + provider + " is either not enabled or doesn't " + + "support service " + service + " in physical network id=" + physicalNetworkId); } } @@ -6359,7 +6790,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } } - public IpAddress assignSystemIp(long networkId, Account owner, boolean forElasticLb, boolean forElasticIp) throws InsufficientAddressCapacityException { + public IpAddress assignSystemIp(long networkId, Account owner, boolean forElasticLb, boolean forElasticIp) + throws InsufficientAddressCapacityException { Network guestNetwork = getNetwork(networkId); NetworkOffering off = _configMgr.getNetworkOffering(guestNetwork.getNetworkOfferingId()); IpAddress ip = null; @@ -6368,9 +6800,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag try { s_logger.debug("Allocating system IP address for load balancer rule..."); // allocate ip - ip = allocateIP(networkId, owner, true); + ip = allocateIP(owner, true, guestNetwork.getDataCenterId()); // apply ip associations - ip = associateIP(ip.getId()); + ip = associateIP(ip.getId(), networkId, null); } catch (ResourceAllocationException ex) { throw new CloudRuntimeException("Failed to allocate system ip due to ", ex); } catch (ConcurrentOperationException ex) { @@ -6394,7 +6826,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (networkId != null) { if (ip.getSystem()) { UserContext ctx = UserContext.current(); - if (!releasePublicIpAddress(ip.getId(), ctx.getCallerUserId(), ctx.getCaller())) { + if (!disassociatePublicIpAddress(ip.getId(), ctx.getCallerUserId(), ctx.getCaller())) { s_logger.warn("Unable to release system ip address id=" + ip.getId()); success = false; } else { @@ -6491,11 +6923,56 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } } catch (Exception ex) { if (s_logger.isDebugEnabled()) { - s_logger.debug("Failed to retrieve the default label for guest traffic." + "zone: " + dcId + " hypervisor: " + hypervisorType + " due to: " + ex.getMessage()); + s_logger.debug("Failed to retrive the default label for management traffic:" + "zone: " + dcId + + " hypervisor: " + hypervisorType + " due to:" + ex.getMessage()); } } return null; } + + @Override + public List listNetworksByVpc(long vpcId) { + return _networksDao.listByVpc(vpcId); + } + + @Override + public String getDefaultNetworkDomain() { + return _networkDomain; + } + + @Override + public List getNtwkOffDistinctProviders(long networkId) { + List providerNames = _ntwkOfferingSrvcDao.getDistinctProviders(networkId); + List providers = new ArrayList(); + for (String providerName : providerNames) { + providers.add(Network.Provider.getProvider(providerName)); + } + + return providers; + } + + @Override + public boolean isVmPartOfNetwork(long vmId, long ntwkId) { + if (_nicDao.findNonReleasedByInstanceIdAndNetworkId(ntwkId, vmId) != null) { + return true; + } + return false; + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_NET_IP_ASSIGN, eventDescription = "associating Ip", async = true) + public IpAddress associateIP(long ipId, Long networkId, Long vpcId) throws InsufficientAddressCapacityException, + ResourceAllocationException, ResourceUnavailableException, ConcurrentOperationException { + if (vpcId != null) { + return associateIPToVpc(ipId, vpcId); + } + + if (networkId != null) { + return associateIPToGuestNetwork(ipId, networkId); + } + + return null; + } private PhysicalNetwork getOnePhysicalNetworkByZoneAndTrafficType(long zoneId, TrafficType trafficType) { List networkList = _physicalNetworkDao.listByZoneAndTrafficType(zoneId, trafficType); @@ -6512,4 +6989,86 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return networkList.get(0); } + + @Override + public void unassignIPFromVpcNetwork(long ipId) { + IPAddressVO ip = _ipAddressDao.findById(ipId); + Long vpcId = ip.getVpcId(); + + if (vpcId == null) { + return; + } + + ip.setAssociatedWithNetworkId(null); + _ipAddressDao.update(ipId, ip); + s_logger.debug("IP address " + ip + " is no longer associated with the network inside vpc id=" + vpcId); + } + + @Override @DB + public Network createPrivateNetwork(String networkName, String displayText, long physicalNetworkId, + String vlan, String startIp, String endIp, String gateway, String netmask, long networkOwnerId) + throws ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException { + + Account owner = _accountMgr.getAccount(networkOwnerId); + + // Get system network offeirng + NetworkOfferingVO ntwkOff = _systemNetworks.get(NetworkOffering.SystemPrivateGatewayNetworkOffering); + + + // Validate physical network + PhysicalNetwork pNtwk = _physicalNetworkDao.findById(physicalNetworkId); + if (pNtwk == null) { + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find a physical network" + + " having the given id"); + ex.addProxyObject("physical_network", physicalNetworkId, "physicalNetworkId"); + throw ex; + } + + // VALIDATE IP INFO + // if end ip is not specified, default it to startIp + if (!NetUtils.isValidIp(startIp)) { + throw new InvalidParameterValueException("Invalid format for the startIp parameter"); + } + if (endIp == null) { + endIp = startIp; + } else if (!NetUtils.isValidIp(endIp)) { + throw new InvalidParameterValueException("Invalid format for the endIp parameter"); + } + + String cidr = null; + if (!NetUtils.isValidIp(gateway)) { + throw new InvalidParameterValueException("Invalid gateway"); + } + if (!NetUtils.isValidNetmask(netmask)) { + throw new InvalidParameterValueException("Invalid netmask"); + } + + cidr = NetUtils.ipAndNetMaskToCidr(gateway, netmask); + + + Transaction txn = Transaction.currentTxn(); + txn.start(); + //create Guest network + Network privateNetwork = createGuestNetwork(ntwkOff.getId(), networkName, displayText, gateway, cidr, vlan, + null, owner, null, pNtwk, pNtwk.getDataCenterId(), ACLType.Account, null, null); + + //add entry to private_ip_address table + PrivateIpVO privateIp = new PrivateIpVO(startIp, privateNetwork.getId()); + _privateIpDao.persist(privateIp); + + txn.commit(); + s_logger.debug("Private network " + privateNetwork + " is created"); + + return privateNetwork; + } + + @Override + public boolean setupDns(Network network, Provider provider) { + boolean dnsProvided = isProviderSupportServiceInNetwork(network.getId(), Service.Dns, provider ); + boolean dhcpProvided =isProviderSupportServiceInNetwork(network.getId(), Service.Dhcp, + provider); + + boolean setupDns = dnsProvided || dhcpProvided; + return setupDns; + } } diff --git a/server/src/com/cloud/network/NetworkVO.java b/server/src/com/cloud/network/NetworkVO.java index 4dae61a7871..03cec169510 100644 --- a/server/src/com/cloud/network/NetworkVO.java +++ b/server/src/com/cloud/network/NetworkVO.java @@ -75,6 +75,9 @@ public class NetworkVO implements Network, Identity { @Column(name="network_offering_id") long networkOfferingId; + + @Column(name="vpc_id") + Long vpcId; @Column(name="physical_network_id") Long physicalNetworkId; @@ -157,7 +160,8 @@ public class NetworkVO implements Network, Identity { * @param dataCenterId * @param physicalNetworkId TODO */ - public NetworkVO(TrafficType trafficType, Mode mode, BroadcastDomainType broadcastDomainType, long networkOfferingId, State state, long dataCenterId, Long physicalNetworkId) { + public NetworkVO(TrafficType trafficType, Mode mode, BroadcastDomainType broadcastDomainType, long networkOfferingId, + State state, long dataCenterId, Long physicalNetworkId) { this.trafficType = trafficType; this.mode = mode; this.broadcastDomainType = broadcastDomainType; @@ -173,8 +177,11 @@ public class NetworkVO implements Network, Identity { this.uuid = UUID.randomUUID().toString(); } - public NetworkVO(long id, Network that, long offeringId, String guruName, long domainId, long accountId, long related, String name, String displayText, String networkDomain, GuestType guestType, long dcId, Long physicalNetworkId, ACLType aclType, boolean specifyIpRanges) { - this(id, that.getTrafficType(), that.getMode(), that.getBroadcastDomainType(), offeringId, domainId, accountId, related, name, displayText, networkDomain, guestType, dcId, physicalNetworkId, aclType, specifyIpRanges); + public NetworkVO(long id, Network that, long offeringId, String guruName, long domainId, long accountId, + long related, String name, String displayText, String networkDomain, GuestType guestType, long dcId, + Long physicalNetworkId, ACLType aclType, boolean specifyIpRanges, Long vpcId) { + this(id, that.getTrafficType(), that.getMode(), that.getBroadcastDomainType(), offeringId, domainId, accountId, + related, name, displayText, networkDomain, guestType, dcId, physicalNetworkId, aclType, specifyIpRanges, vpcId); this.gateway = that.getGateway(); this.cidr = that.getCidr(); this.broadcastUri = that.getBroadcastUri(); @@ -201,9 +208,12 @@ public class NetworkVO implements Network, Identity { * @param guestType TODO * @param aclType TODO * @param specifyIpRanges TODO + * @param vpcId TODO * @param dataCenterId */ - public NetworkVO(long id, TrafficType trafficType, Mode mode, BroadcastDomainType broadcastDomainType, long networkOfferingId, long domainId, long accountId, long related, String name, String displayText, String networkDomain, GuestType guestType, long dcId, Long physicalNetworkId, ACLType aclType, boolean specifyIpRanges) { + public NetworkVO(long id, TrafficType trafficType, Mode mode, BroadcastDomainType broadcastDomainType, + long networkOfferingId, long domainId, long accountId, long related, String name, String displayText, + String networkDomain, GuestType guestType, long dcId, Long physicalNetworkId, ACLType aclType, boolean specifyIpRanges, Long vpcId) { this(trafficType, mode, broadcastDomainType, networkOfferingId, State.Allocated, dcId, physicalNetworkId); this.domainId = domainId; this.accountId = accountId; @@ -216,6 +226,7 @@ public class NetworkVO implements Network, Identity { this.uuid = UUID.randomUUID().toString(); this.guestType = guestType; this.specifyIpRanges = specifyIpRanges; + this.vpcId = vpcId; } @Override @@ -473,4 +484,9 @@ public class NetworkVO implements Network, Identity { public boolean getSpecifyIpRanges() { return specifyIpRanges; } + + @Override + public Long getVpcId() { + return vpcId; + } } diff --git a/server/src/com/cloud/network/RouterNetworkDaoImpl.java b/server/src/com/cloud/network/RouterNetworkDaoImpl.java new file mode 100644 index 00000000000..dcb6583a313 --- /dev/null +++ b/server/src/com/cloud/network/RouterNetworkDaoImpl.java @@ -0,0 +1,58 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network; + +import java.util.List; + +import com.cloud.utils.db.GenericDao; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.GenericSearchBuilder; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.SearchCriteria.Op; + +/** + * @author Alena Prokharchyk + */ +public class RouterNetworkDaoImpl extends GenericDaoBase implements GenericDao{ + protected final GenericSearchBuilder RouterNetworksSearch; + protected final SearchBuilder AllFieldsSearch; + + public RouterNetworkDaoImpl() { + super(); + + RouterNetworksSearch = createSearchBuilder(Long.class); + RouterNetworksSearch.selectField(RouterNetworksSearch.entity().getNetworkId()); + RouterNetworksSearch.and("routerId", RouterNetworksSearch.entity().getRouterId(), Op.EQ); + RouterNetworksSearch.done(); + + AllFieldsSearch = createSearchBuilder(); + AllFieldsSearch.and("routerId", AllFieldsSearch.entity().getRouterId(), Op.EQ); + AllFieldsSearch.and("networkId", AllFieldsSearch.entity().getNetworkId(), Op.EQ); + AllFieldsSearch.done(); + } + + public List getRouterNetworks(long routerId) { + SearchCriteria sc = RouterNetworksSearch.create(); + sc.setParameters("routerId", routerId); + return customSearch(sc, null); + } + + public RouterNetworkVO findByRouterAndNetwork (long routerId, long networkId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("routerId", routerId); + sc.setParameters("networkId", networkId); + return findOneBy(sc); + } + +} diff --git a/server/src/com/cloud/network/RouterNetworkVO.java b/server/src/com/cloud/network/RouterNetworkVO.java new file mode 100644 index 00000000000..629a5f438ee --- /dev/null +++ b/server/src/com/cloud/network/RouterNetworkVO.java @@ -0,0 +1,72 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.cloud.network.Network.GuestType; + +/** + * @author Alena Prokharchyk + */ + +@Entity +@Table(name="router_network_ref") +public class RouterNetworkVO{ + @Id + @GeneratedValue(strategy=GenerationType.IDENTITY) + long id; + + @Column(name="router_id") + long routerId; + + @Column(name="network_id") + long networkId; + + @Column(name="guest_type") + @Enumerated(value=EnumType.STRING) + Network.GuestType guestType; + + protected RouterNetworkVO() { + } + + public RouterNetworkVO(long routerId, long networkId, GuestType guestType) { + this.networkId = networkId; + this.routerId = routerId; + this.guestType = guestType; + } + + + public long getRouterId() { + return routerId; + } + + public long getNetworkId() { + return networkId; + } + + public Network.GuestType getGuestType() { + return guestType; + } + + public long getId() { + return id; + } +} diff --git a/server/src/com/cloud/network/addr/PublicIp.java b/server/src/com/cloud/network/addr/PublicIp.java index 5322674e19b..11948e5c836 100644 --- a/server/src/com/cloud/network/addr/PublicIp.java +++ b/server/src/com/cloud/network/addr/PublicIp.java @@ -180,4 +180,20 @@ public class PublicIp implements PublicIpAddress { public boolean getSystem() { return _addr.getSystem(); } + + /* (non-Javadoc) + * @see com.cloud.network.IpAddress#getVpcId() + */ + @Override + public Long getVpcId() { + return _addr.getVpcId(); + } + + /* (non-Javadoc) + * @see com.cloud.network.IpAddress#setVpcId(java.lang.Long) + */ + @Override + public void setVpcId(Long vpcId) { + _addr.setVpcId(vpcId); + } } diff --git a/server/src/com/cloud/network/dao/IPAddressDao.java b/server/src/com/cloud/network/dao/IPAddressDao.java index 1b44b16ba9e..54867703f36 100755 --- a/server/src/com/cloud/network/dao/IPAddressDao.java +++ b/server/src/com/cloud/network/dao/IPAddressDao.java @@ -56,4 +56,7 @@ public interface IPAddressDao extends GenericDao { List listByPhysicalNetworkId(long physicalNetworkId); long countFreeIPs(); + + List listByAssociatedVpc(long vpcId, Boolean isSourceNat); + } diff --git a/server/src/com/cloud/network/dao/IPAddressDaoImpl.java b/server/src/com/cloud/network/dao/IPAddressDaoImpl.java index 425c215c430..b2979b05684 100755 --- a/server/src/com/cloud/network/dao/IPAddressDaoImpl.java +++ b/server/src/com/cloud/network/dao/IPAddressDaoImpl.java @@ -67,6 +67,7 @@ public class IPAddressDaoImpl extends GenericDaoBase implemen AllFieldsSearch.and("oneToOneNat", AllFieldsSearch.entity().isOneToOneNat(), Op.EQ); AllFieldsSearch.and("sourcenetwork", AllFieldsSearch.entity().getSourceNetworkId(), Op.EQ); AllFieldsSearch.and("physicalNetworkId", AllFieldsSearch.entity().getPhysicalNetworkId(), Op.EQ); + AllFieldsSearch.and("vpcId", AllFieldsSearch.entity().getVpcId(), Op.EQ); AllFieldsSearch.done(); VlanDbIdSearchUnallocated = createSearchBuilder(); @@ -140,6 +141,7 @@ public class IPAddressDaoImpl extends GenericDaoBase implemen address.setAssociatedWithVmId(null); address.setState(State.Free); address.setAssociatedWithNetworkId(null); + address.setVpcId(null); address.setSystem(false); update(ipAddressId, address); } @@ -299,4 +301,16 @@ public class IPAddressDaoImpl extends GenericDaoBase implemen sc.setJoinParameters("vlans", "vlanType", VlanType.VirtualNetwork); return customSearch(sc, null).get(0); } + + @Override + public List listByAssociatedVpc(long vpcId, Boolean isSourceNat) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("vpcId", vpcId); + + if (isSourceNat != null) { + sc.setParameters("sourceNat", isSourceNat); + } + + return listBy(sc); + } } diff --git a/server/src/com/cloud/network/dao/NetworkDao.java b/server/src/com/cloud/network/dao/NetworkDao.java index df74f238409..299f5ee8a26 100644 --- a/server/src/com/cloud/network/dao/NetworkDao.java +++ b/server/src/com/cloud/network/dao/NetworkDao.java @@ -70,8 +70,6 @@ public interface NetworkDao extends GenericDao { void addDomainToNetwork(long networkId, long domainId, Boolean subdomainAccess); - Long getNetworkCountByOfferingId(long offeringId); - List listByPhysicalNetwork(long physicalNetworkId); List listSecurityGroupEnabledNetworks(); @@ -95,5 +93,9 @@ public interface NetworkDao extends GenericDao { long countNetworksUserCanCreate(long ownerId); List listSourceNATEnabledNetworks(long accountId, long dataCenterId, GuestType type); + + int getNetworkCountByVpcId(long vpcId); + + List listByVpc(long vpcId); } diff --git a/server/src/com/cloud/network/dao/NetworkDaoImpl.java b/server/src/com/cloud/network/dao/NetworkDaoImpl.java index f907ce8116b..8fa107c8710 100644 --- a/server/src/com/cloud/network/dao/NetworkDaoImpl.java +++ b/server/src/com/cloud/network/dao/NetworkDaoImpl.java @@ -56,7 +56,7 @@ public class NetworkDaoImpl extends GenericDaoBase implements N final SearchBuilder AccountNetworkSearch; final SearchBuilder ZoneBroadcastUriSearch; final SearchBuilder ZoneSecurityGroupSearch; - final GenericSearchBuilder CountByOfferingId; + final GenericSearchBuilder CountBy; final SearchBuilder PhysicalNetworkSearch; final SearchBuilder SecurityGroupSearch; final GenericSearchBuilder NetworksRegularUserCanCreateSearch; @@ -88,6 +88,7 @@ public class NetworkDaoImpl extends GenericDaoBase implements N AllFieldsSearch.and("related", AllFieldsSearch.entity().getRelated(), Op.EQ); AllFieldsSearch.and("guestType", AllFieldsSearch.entity().getGuestType(), Op.EQ); AllFieldsSearch.and("physicalNetwork", AllFieldsSearch.entity().getPhysicalNetworkId(), Op.EQ); + AllFieldsSearch.and("vpcId", AllFieldsSearch.entity().getVpcId(), Op.EQ); AllFieldsSearch.done(); AccountSearch = createSearchBuilder(); @@ -126,11 +127,12 @@ public class NetworkDaoImpl extends GenericDaoBase implements N ZoneSecurityGroupSearch.join("services", join1, ZoneSecurityGroupSearch.entity().getId(), join1.entity().getNetworkId(), JoinBuilder.JoinType.INNER); ZoneSecurityGroupSearch.done(); - CountByOfferingId = createSearchBuilder(Long.class); - CountByOfferingId.select(null, Func.COUNT, CountByOfferingId.entity().getId()); - CountByOfferingId.and("offeringId", CountByOfferingId.entity().getNetworkOfferingId(), Op.EQ); - CountByOfferingId.and("removed", CountByOfferingId.entity().getRemoved(), Op.NULL); - CountByOfferingId.done(); + CountBy = createSearchBuilder(Integer.class); + CountBy.select(null, Func.COUNT, CountBy.entity().getId()); + CountBy.and("offeringId", CountBy.entity().getNetworkOfferingId(), Op.EQ); + CountBy.and("vpcId", CountBy.entity().getVpcId(), Op.EQ); + CountBy.and("removed", CountBy.entity().getRemoved(), Op.NULL); + CountBy.done(); PhysicalNetworkSearch = createSearchBuilder(); PhysicalNetworkSearch.and("physicalNetworkId", PhysicalNetworkSearch.entity().getPhysicalNetworkId(), Op.EQ); @@ -363,14 +365,16 @@ public class NetworkDaoImpl extends GenericDaoBase implements N NetworkDomainVO domain = new NetworkDomainVO(networkId, domainId, subdomainAccess); _domainsDao.persist(domain); } - + + @Override - public Long getNetworkCountByOfferingId(long offeringId) { - SearchCriteria sc = CountByOfferingId.create(); - sc.setParameters("offeringId", offeringId); - List results = customSearch(sc, null); + public int getNetworkCountByVpcId(long vpcId) { + SearchCriteria sc = CountBy.create(); + sc.setParameters("vpcId", vpcId); + List results = customSearch(sc, null); return results.get(0); } + @Override public List listSecurityGroupEnabledNetworks() { @@ -458,5 +462,13 @@ public class NetworkDaoImpl extends GenericDaoBase implements N sc.setJoinParameters("services", "service", Service.SourceNat.getName()); return listBy(sc); } + + @Override + public List listByVpc(long vpcId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("vpcId", vpcId); + + return listBy(sc, null); + } } diff --git a/server/src/com/cloud/network/element/JuniperSRXExternalFirewallElement.java b/server/src/com/cloud/network/element/JuniperSRXExternalFirewallElement.java index 0473291d15d..1aa23daef4a 100644 --- a/server/src/com/cloud/network/element/JuniperSRXExternalFirewallElement.java +++ b/server/src/com/cloud/network/element/JuniperSRXExternalFirewallElement.java @@ -266,6 +266,7 @@ public class JuniperSRXExternalFirewallElement extends ExternalFirewallDeviceMan firewallCapabilities.put(Capability.SupportedProtocols, "tcp,udp"); firewallCapabilities.put(Capability.MultipleIps, "true"); firewallCapabilities.put(Capability.TrafficStatistics, "per public ip"); + firewallCapabilities.put(Capability.FirewallType, "perpublicip"); capabilities.put(Service.Firewall, firewallCapabilities); // Disabling VPN for Juniper in Acton as it 1) Was never tested 2) probably just doesn't work diff --git a/server/src/com/cloud/network/element/NetscalerElement.java b/server/src/com/cloud/network/element/NetscalerElement.java index 81d5424d4ab..33a82d479c6 100644 --- a/server/src/com/cloud/network/element/NetscalerElement.java +++ b/server/src/com/cloud/network/element/NetscalerElement.java @@ -270,7 +270,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl firewallCapabilities.put(Capability.TrafficStatistics, "per public ip"); firewallCapabilities.put(Capability.SupportedProtocols, "tcp,udp,icmp"); firewallCapabilities.put(Capability.MultipleIps, "true"); - + firewallCapabilities.put(Capability.FirewallType, "perpublicip"); capabilities.put(Service.Firewall, firewallCapabilities); return capabilities; diff --git a/server/src/com/cloud/network/element/VirtualRouterElement.java b/server/src/com/cloud/network/element/VirtualRouterElement.java index d69ad6f17cc..0feaa984c28 100755 --- a/server/src/com/cloud/network/element/VirtualRouterElement.java +++ b/server/src/com/cloud/network/element/VirtualRouterElement.java @@ -85,11 +85,12 @@ import com.cloud.vm.dao.UserVmDao; import com.google.gson.Gson; @Local(value = NetworkElement.class) -public class VirtualRouterElement extends AdapterBase implements VirtualRouterElementService, DhcpServiceProvider, UserDataServiceProvider, SourceNatServiceProvider, StaticNatServiceProvider, FirewallServiceProvider, +public class VirtualRouterElement extends AdapterBase implements VirtualRouterElementService, DhcpServiceProvider, + UserDataServiceProvider, SourceNatServiceProvider, StaticNatServiceProvider, FirewallServiceProvider, LoadBalancingServiceProvider, PortForwardingServiceProvider, RemoteAccessVPNServiceProvider, IpDeployer { private static final Logger s_logger = Logger.getLogger(VirtualRouterElement.class); - private static final Map> capabilities = setCapabilities(); + protected static final Map> capabilities = setCapabilities(); @Inject NetworkDao _networksDao; @@ -127,8 +128,12 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl if (physicalNetworkId == null) { return false; } + + if (network.getVpcId() != null) { + return false; + } - if (!_networkMgr.isProviderEnabledInPhysicalNetwork(physicalNetworkId, "VirtualRouter")) { + if (!_networkMgr.isProviderEnabledInPhysicalNetwork(physicalNetworkId, Network.Provider.VirtualRouter.getName())) { return false; } @@ -139,7 +144,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl } } else { if (!_networkMgr.isProviderSupportServiceInNetwork(network.getId(), service, getProvider())) { - s_logger.trace("Element " + getProvider().getName() + " doesn't support service " + service.getName() + " in the network " + network); + s_logger.trace("Element " + getProvider().getName() + " doesn't support service " + service.getName() + + " in the network " + network); return false; } } @@ -148,23 +154,32 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl } @Override - public boolean implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws ResourceUnavailableException, ConcurrentOperationException, + public boolean implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) + throws ResourceUnavailableException, ConcurrentOperationException, InsufficientCapacityException { + if (offering.isSystemOnly()) { return false; } Map params = new HashMap(1); - params.put(VirtualMachineProfile.Param.ReProgramNetwork, true); + params.put(VirtualMachineProfile.Param.ReProgramGuestNetworks, true); - _routerMgr.deployVirtualRouter(network, dest, _accountMgr.getAccount(network.getAccountId()), params, offering.getRedundantRouter()); - - return true; + List routers = _routerMgr.deployVirtualRouterInGuestNetwork(network, dest, + _accountMgr.getAccount(network.getAccountId()), params, + offering.getRedundantRouter()); + if ((routers == null) || (routers.size() == 0)) { + throw new ResourceUnavailableException("Can't find at least one running router!", + DataCenter.class, network.getDataCenterId()); + } + + return true; } @Override - public boolean prepare(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, - InsufficientCapacityException, ResourceUnavailableException { + public boolean prepare(Network network, NicProfile nic, VirtualMachineProfile vm, + DeployDestination dest, ReservationContext context) + throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { if (vm.getType() != VirtualMachine.Type.User || vm.getHypervisorType() == HypervisorType.BareMetal) { return false; } @@ -177,17 +192,21 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl if (offering.isSystemOnly()) { return false; } - if (!_networkMgr.isProviderEnabledInPhysicalNetwork(_networkMgr.getPhysicalNetworkId(network), "VirtualRouter")) { + if (!_networkMgr.isProviderEnabledInPhysicalNetwork(_networkMgr.getPhysicalNetworkId(network), getProvider().getName())) { return false; } @SuppressWarnings("unchecked") VirtualMachineProfile uservm = (VirtualMachineProfile) vm; - List routers = _routerMgr.deployVirtualRouter(network, dest, _accountMgr.getAccount(network.getAccountId()), uservm.getParameters(), offering.getRedundantRouter()); + List routers = _routerMgr.deployVirtualRouterInGuestNetwork(network, dest, + _accountMgr.getAccount(network.getAccountId()), + uservm.getParameters(), offering.getRedundantRouter()); if ((routers == null) || (routers.size() == 0)) { - throw new ResourceUnavailableException("Can't find at least one running router!", DataCenter.class, network.getDataCenterId()); + throw new ResourceUnavailableException("Can't find at least one running router!", + DataCenter.class, network.getDataCenterId()); } - return true; + + return true; } @Override @@ -195,7 +214,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl if (canHandle(config, Service.Firewall)) { List routers = _routerDao.listByNetworkAndRole(config.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { - s_logger.debug("Virtual router elemnt doesn't need to apply firewall rules on the backend; virtual router doesn't exist in the network " + config.getId()); + s_logger.debug("Virtual router elemnt doesn't need to apply firewall rules on the backend; virtual " + + "router doesn't exist in the network " + config.getId()); return true; } @@ -265,10 +285,12 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl expire = value; } if ((expire != null) && !containsOnlyNumbers(expire, timeEndChar)) { - throw new InvalidParameterValueException("Failed LB in validation rule id: " + rule.getId() + " Cause: expire is not in timeformat: " + expire); + throw new InvalidParameterValueException("Failed LB in validation rule id: " + rule.getId() + + " Cause: expire is not in timeformat: " + expire); } if ((tablesize != null) && !containsOnlyNumbers(tablesize, "kmg")) { - throw new InvalidParameterValueException("Failed LB in validation rule id: " + rule.getId() + " Cause: tablesize is not in size format: " + tablesize); + throw new InvalidParameterValueException("Failed LB in validation rule id: " + rule.getId() + + " Cause: tablesize is not in size format: " + tablesize); } } else if (StickinessMethodType.AppCookieBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName())) { @@ -294,10 +316,12 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl } if ((length != null) && (!containsOnlyNumbers(length, null))) { - throw new InvalidParameterValueException("Failed LB in validation rule id: " + rule.getId() + " Cause: length is not a number: " + length); + throw new InvalidParameterValueException("Failed LB in validation rule id: " + rule.getId() + + " Cause: length is not a number: " + length); } if ((holdTime != null) && (!containsOnlyNumbers(holdTime, timeEndChar) && !containsOnlyNumbers(holdTime, null))) { - throw new InvalidParameterValueException("Failed LB in validation rule id: " + rule.getId() + " Cause: holdtime is not in timeformat: " + holdTime); + throw new InvalidParameterValueException("Failed LB in validation rule id: " + rule.getId() + + " Cause: holdtime is not in timeformat: " + holdTime); } } } @@ -321,7 +345,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl if (canHandle(network, Service.Lb)) { List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { - s_logger.debug("Virtual router elemnt doesn't need to apply firewall rules on the backend; virtual router doesn't exist in the network " + network.getId()); + s_logger.debug("Virtual router elemnt doesn't need to apply firewall rules on the backend; virtual " + + "router doesn't exist in the network " + network.getId()); return true; } @@ -342,7 +367,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl if (canHandle(network, Service.Vpn)) { List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { - s_logger.debug("Virtual router elemnt doesn't need to apply vpn users on the backend; virtual router doesn't exist in the network " + network.getId()); + s_logger.debug("Virtual router elemnt doesn't need to apply vpn users on the backend; virtual router" + + " doesn't exist in the network " + network.getId()); return null; } return _routerMgr.applyVpnUsers(network, users, routers); @@ -357,7 +383,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl if (canHandle(network, Service.Vpn)) { List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { - s_logger.debug("Virtual router elemnt doesn't need stop vpn on the backend; virtual router doesn't exist in the network " + network.getId()); + s_logger.debug("Virtual router elemnt doesn't need stop vpn on the backend; virtual router doesn't" + + " exist in the network " + network.getId()); return true; } return _routerMgr.startRemoteAccessVpn(network, vpn, routers); @@ -372,7 +399,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl if (canHandle(network, Service.Vpn)) { List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { - s_logger.debug("Virtual router elemnt doesn't need stop vpn on the backend; virtual router doesn't exist in the network " + network.getId()); + s_logger.debug("Virtual router elemnt doesn't need stop vpn on the backend; virtual router doesn't " + + "exist in the network " + network.getId()); return true; } return _routerMgr.deleteRemoteAccessVpn(network, vpn, routers); @@ -383,7 +411,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl } @Override - public boolean applyIps(Network network, List ipAddress, Set services) throws ResourceUnavailableException { + public boolean applyIps(Network network, List ipAddress, Set services) + throws ResourceUnavailableException { boolean canHandle = true; for (Service service : services) { if (!canHandle(network, service)) { @@ -394,7 +423,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl if (canHandle) { List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { - s_logger.debug("Virtual router elemnt doesn't need to associate ip addresses on the backend; virtual router doesn't exist in the network " + network.getId()); + s_logger.debug("Virtual router elemnt doesn't need to associate ip addresses on the backend; virtual " + + "router doesn't exist in the network " + network.getId()); return true; } @@ -421,37 +451,61 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl method = new LbStickinessMethod(StickinessMethodType.LBCookieBased, "This is loadbalancer cookie based stickiness method."); method.addParam("cookie-name", false, "Cookie name passed in http header by the LB to the client.", false); method.addParam("mode", false, - "Valid values: insert, rewrite, prefix. Default value: insert. In the insert mode cookie will be created by the LB. In other modes, cookie will be created by the server and LB modifies it.", false); + "Valid values: insert, rewrite, prefix. Default value: insert. In the insert mode cookie will be created" + + " by the LB. In other modes, cookie will be created by the server and LB modifies it.", false); method.addParam( "nocache", false, - "This option is recommended in conjunction with the insert mode when there is a cache between the client and HAProxy, as it ensures that a cacheable response will be tagged non-cacheable if a cookie needs to be inserted. This is important because if all persistence cookies are added on a cacheable home page for instance, then all customers will then fetch the page from an outer cache and will all share the same persistence cookie, leading to one server receiving much more traffic than others. See also the insert and postonly options. ", + "This option is recommended in conjunction with the insert mode when there is a cache between the client" + + " and HAProxy, as it ensures that a cacheable response will be tagged non-cacheable if a cookie needs " + + "to be inserted. This is important because if all persistence cookies are added on a cacheable home page" + + " for instance, then all customers will then fetch the page from an outer cache and will all share the " + + "same persistence cookie, leading to one server receiving much more traffic than others. See also the " + + "insert and postonly options. ", true); method.addParam( "indirect", false, - "When this option is specified in insert mode, cookies will only be added when the server was not reached after a direct access, which means that only when a server is elected after applying a load-balancing algorithm, or after a redispatch, then the cookie will be inserted. If the client has all the required information to connect to the same server next time, no further cookie will be inserted. In all cases, when the indirect option is used in insert mode, the cookie is always removed from the requests transmitted to the server. The persistence mechanism then becomes totally transparent from the application point of view.", + "When this option is specified in insert mode, cookies will only be added when the server was not reached" + + " after a direct access, which means that only when a server is elected after applying a load-balancing algorithm," + + " or after a redispatch, then the cookie will be inserted. If the client has all the required information" + + " to connect to the same server next time, no further cookie will be inserted. In all cases, when the " + + "indirect option is used in insert mode, the cookie is always removed from the requests transmitted to " + + "the server. The persistence mechanism then becomes totally transparent from the application point of view.", true); method.addParam( "postonly", false, - "This option ensures that cookie insertion will only be performed on responses to POST requests. It is an alternative to the nocache option, because POST responses are not cacheable, so this ensures that the persistence cookie will never get cached.Since most sites do not need any sort of persistence before the first POST which generally is a login request, this is a very efficient method to optimize caching without risking to find a persistence cookie in the cache. See also the insert and nocache options.", + "This option ensures that cookie insertion will only be performed on responses to POST requests. It is an" + + " alternative to the nocache option, because POST responses are not cacheable, so this ensures that the " + + "persistence cookie will never get cached.Since most sites do not need any sort of persistence before the" + + " first POST which generally is a login request, this is a very efficient method to optimize caching " + + "without risking to find a persistence cookie in the cache. See also the insert and nocache options.", true); method.addParam( "domain", false, - "This option allows to specify the domain at which a cookie is inserted. It requires exactly one parameter: a valid domain name. If the domain begins with a dot, the browser is allowed to use it for any host ending with that name. It is also possible to specify several domain names by invoking this option multiple times. Some browsers might have small limits on the number of domains, so be careful when doing that. For the record, sending 10 domains to MSIE 6 or Firefox 2 works as expected.", + "This option allows to specify the domain at which a cookie is inserted. It requires exactly one parameter:" + + " a valid domain name. If the domain begins with a dot, the browser is allowed to use it for any host " + + "ending with that name. It is also possible to specify several domain names by invoking this option multiple" + + " times. Some browsers might have small limits on the number of domains, so be careful when doing that. " + + "For the record, sending 10 domains to MSIE 6 or Firefox 2 works as expected.", false); methodList.add(method); method = new LbStickinessMethod(StickinessMethodType.AppCookieBased, - "This is App session based sticky method. Define session stickiness on an existing application cookie. It can be used only for a specific http traffic"); - method.addParam("cookie-name", false, "This is the name of the cookie used by the application and which LB will have to learn for each new session. Default value: Auto geneared based on ip", false); - method.addParam("length", false, "This is the max number of characters that will be memorized and checked in each cookie value. Default value:52", false); + "This is App session based sticky method. Define session stickiness on an existing application cookie. " + + "It can be used only for a specific http traffic"); + method.addParam("cookie-name", false, "This is the name of the cookie used by the application and which LB will " + + "have to learn for each new session. Default value: Auto geneared based on ip", false); + method.addParam("length", false, "This is the max number of characters that will be memorized and checked in " + + "each cookie value. Default value:52", false); method.addParam( "holdtime", false, - "This is the time after which the cookie will be removed from memory if unused. The value should be in the format Example : 20s or 30m or 4h or 5d . only seconds(s), minutes(m) hours(h) and days(d) are valid , cannot use th combinations like 20h30m. Default value:3h ", + "This is the time after which the cookie will be removed from memory if unused. The value should be in " + + "the format Example : 20s or 30m or 4h or 5d . only seconds(s), minutes(m) hours(h) and days(d) are valid," + + " cannot use th combinations like 20h30m. Default value:3h ", false); method.addParam( "request-learn", @@ -461,18 +515,25 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl method.addParam( "prefix", false, - "When this option is specified, haproxy will match on the cookie prefix (or URL parameter prefix). The appsession value is the data following this prefix. Example : appsession ASPSESSIONID len 64 timeout 3h prefix This will match the cookie ASPSESSIONIDXXXX=XXXXX, the appsession value will be XXXX=XXXXX.", + "When this option is specified, haproxy will match on the cookie prefix (or URL parameter prefix). " + + "The appsession value is the data following this prefix. Example : appsession ASPSESSIONID len 64 timeout 3h prefix This will match the cookie ASPSESSIONIDXXXX=XXXXX, the appsession value will be XXXX=XXXXX.", true); method.addParam( "mode", false, - "This option allows to change the URL parser mode. 2 modes are currently supported : - path-parameters : The parser looks for the appsession in the path parameters part (each parameter is separated by a semi-colon), which is convenient for JSESSIONID for example.This is the default mode if the option is not set. - query-string : In this mode, the parser will look for the appsession in the query string.", + "This option allows to change the URL parser mode. 2 modes are currently supported : - path-parameters " + + ": The parser looks for the appsession in the path parameters part (each parameter is separated by a semi-colon), " + + "which is convenient for JSESSIONID for example.This is the default mode if the option is not set. - query-string :" + + " In this mode, the parser will look for the appsession in the query string.", false); methodList.add(method); - method = new LbStickinessMethod(StickinessMethodType.SourceBased, "This is source based Stickiness method, it can be used for any type of protocol."); - method.addParam("tablesize", false, "Size of table to store source ip addresses. example: tablesize=200k or 300m or 400g. Default value:200k", false); - method.addParam("expire", false, "Entry in source ip table will expire after expire duration. units can be s,m,h,d . example: expire=30m 20s 50h 4d. Default value:3h", false); + method = new LbStickinessMethod(StickinessMethodType.SourceBased, "This is source based Stickiness method, " + + "it can be used for any type of protocol."); + method.addParam("tablesize", false, "Size of table to store source ip addresses. example: tablesize=200k or 300m" + + " or 400g. Default value:200k", false); + method.addParam("expire", false, "Entry in source ip table will expire after expire duration. units can be s,m,h,d ." + + " example: expire=30m 20s 50h 4d. Default value:3h", false); methodList.add(method); Gson gson = new Gson(); @@ -498,12 +559,13 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl firewallCapabilities.put(Capability.TrafficStatistics, "per public ip"); firewallCapabilities.put(Capability.SupportedProtocols, "tcp,udp,icmp"); firewallCapabilities.put(Capability.MultipleIps, "true"); - + firewallCapabilities.put(Capability.FirewallType, "perpublicip"); capabilities.put(Service.Firewall, firewallCapabilities); // Set capabilities for vpn Map vpnCapabilities = new HashMap(); - vpnCapabilities.put(Capability.SupportedVpnTypes, "pptp,l2tp,ipsec"); + vpnCapabilities.put(Capability.SupportedVpnProtocols, "pptp,l2tp,ipsec"); + vpnCapabilities.put(Capability.VpnTypes, "removeaccessvpn"); capabilities.put(Service.Vpn, vpnCapabilities); Map dnsCapabilities = new HashMap(); @@ -531,7 +593,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl if (canHandle(config, Service.StaticNat)) { List routers = _routerDao.listByNetworkAndRole(config.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { - s_logger.debug("Virtual router elemnt doesn't need to apply static nat on the backend; virtual router doesn't exist in the network " + config.getId()); + s_logger.debug("Virtual router elemnt doesn't need to apply static nat on the backend; virtual " + + "router doesn't exist in the network " + config.getId()); return true; } @@ -542,7 +605,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl } @Override - public boolean shutdown(Network network, ReservationContext context, boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException { + public boolean shutdown(Network network, ReservationContext context, boolean cleanup) + throws ConcurrentOperationException, ResourceUnavailableException { List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { return true; @@ -577,7 +641,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl } @Override - public boolean savePassword(Network network, NicProfile nic, VirtualMachineProfile vm) throws ResourceUnavailableException { + public boolean savePassword(Network network, NicProfile nic, VirtualMachineProfile vm) + throws ResourceUnavailableException { if (!canHandle(network, null)) { return false; } @@ -613,13 +678,13 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl } @Override - public VirtualRouterProvider addElement(Long nspId) { - VirtualRouterProviderVO element = _vrProviderDao.findByNspIdAndType(nspId, VirtualRouterProviderType.VirtualRouter); + public VirtualRouterProvider addElement(Long nspId, VirtualRouterProviderType providerType) { + VirtualRouterProviderVO element = _vrProviderDao.findByNspIdAndType(nspId, providerType); if (element != null) { s_logger.debug("There is already a virtual router element with service provider id " + nspId); return null; } - element = new VirtualRouterProviderVO(nspId, VirtualRouterProviderType.VirtualRouter); + element = new VirtualRouterProviderVO(nspId, providerType); _vrProviderDao.persist(element); return element; } @@ -629,7 +694,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl if (canHandle(network, Service.PortForwarding)) { List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { - s_logger.debug("Virtual router elemnt doesn't need to apply firewall rules on the backend; virtual router doesn't exist in the network " + network.getId()); + s_logger.debug("Virtual router elemnt doesn't need to apply firewall rules on the backend; virtual " + + "router doesn't exist in the network " + network.getId()); return true; } @@ -653,7 +719,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl } @Override - public boolean shutdownProviderInstances(PhysicalNetworkServiceProvider provider, ReservationContext context) throws ConcurrentOperationException, + public boolean shutdownProviderInstances(PhysicalNetworkServiceProvider provider, ReservationContext context) + throws ConcurrentOperationException, ResourceUnavailableException { VirtualRouterProviderVO element = _vrProviderDao.findByNspIdAndType(provider.getId(), VirtualRouterProviderType.VirtualRouter); if (element == null) { @@ -687,13 +754,15 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl } @Override - public boolean release(Network network, NicProfile nic, VirtualMachineProfile vm, ReservationContext context) throws ConcurrentOperationException, + public boolean release(Network network, NicProfile nic, VirtualMachineProfile vm, + ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException { return true; } @Override - public boolean addDhcpEntry(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) + public boolean addDhcpEntry(Network network, NicProfile nic, VirtualMachineProfile vm, + DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { if (canHandle(network, Service.Dhcp)) { if (vm.getType() != VirtualMachine.Type.User) { @@ -703,33 +772,7 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl @SuppressWarnings("unchecked") VirtualMachineProfile uservm = (VirtualMachineProfile) vm; - boolean publicNetwork = false; - if (_networkMgr.isProviderSupportServiceInNetwork(network.getId(), Service.SourceNat, getProvider())) { - publicNetwork = true; - } - boolean isPodBased = (dest.getDataCenter().getNetworkType() == NetworkType.Basic || _networkMgr.isSecurityGroupSupportedInNetwork(network)) && - network.getTrafficType() == TrafficType.Guest; - - List routers; - - if (publicNetwork) { - routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); - } else { - Long podId = dest.getPod().getId(); - if (isPodBased) { - routers = _routerDao.listByNetworkAndPodAndRole(network.getId(), podId, Role.VIRTUAL_ROUTER); - } else { - routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); - } - } - - // for Basic zone, add all Running routers - we have to send Dhcp/vmData/password info to them when -// network.dns.basiczone.updates is set to "all" - Long podId = dest.getPod().getId(); - if (isPodBased && _routerMgr.getDnsBasicZoneUpdate().equalsIgnoreCase("all")) { - List allRunningRoutersOutsideThePod = _routerDao.findByNetworkOutsideThePod(network.getId(), podId, State.Running, Role.VIRTUAL_ROUTER); - routers.addAll(allRunningRoutersOutsideThePod); - } + List routers = getRouters(network, dest); if ((routers == null) || (routers.size() == 0)) { throw new ResourceUnavailableException("Can't find at least one router!", DataCenter.class, network.getDataCenterId()); @@ -741,7 +784,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl } @Override - public boolean addPasswordAndUserdata(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) + public boolean addPasswordAndUserdata(Network network, NicProfile nic, VirtualMachineProfile vm, + DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { if (canHandle(network, Service.UserData)) { if (vm.getType() != VirtualMachine.Type.User) { @@ -751,33 +795,7 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl @SuppressWarnings("unchecked") VirtualMachineProfile uservm = (VirtualMachineProfile) vm; - boolean publicNetwork = false; - if (_networkMgr.isProviderSupportServiceInNetwork(network.getId(), Service.SourceNat, getProvider())) { - publicNetwork = true; - } - boolean isPodBased = (dest.getDataCenter().getNetworkType() == NetworkType.Basic || _networkMgr.isSecurityGroupSupportedInNetwork(network)) && - network.getTrafficType() == TrafficType.Guest; - - List routers; - - if (publicNetwork) { - routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); - } else { - Long podId = dest.getPod().getId(); - if (isPodBased) { - routers = _routerDao.listByNetworkAndPodAndRole(network.getId(), podId, Role.VIRTUAL_ROUTER); - } else { - routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); - } - } - - // for Basic zone, add all Running routers - we have to send Dhcp/vmData/password info to them when -// network.dns.basiczone.updates is set to "all" - Long podId = dest.getPod().getId(); - if (isPodBased && _routerMgr.getDnsBasicZoneUpdate().equalsIgnoreCase("all")) { - List allRunningRoutersOutsideThePod = _routerDao.findByNetworkOutsideThePod(network.getId(), podId, State.Running, Role.VIRTUAL_ROUTER); - routers.addAll(allRunningRoutersOutsideThePod); - } + List routers = getRouters(network, dest); if ((routers == null) || (routers.size() == 0)) { throw new ResourceUnavailableException("Can't find at least one router!", DataCenter.class, network.getDataCenterId()); @@ -788,6 +806,39 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl return false; } + protected List getRouters(Network network, DeployDestination dest) { + boolean publicNetwork = false; + if (_networkMgr.isProviderSupportServiceInNetwork(network.getId(), Service.SourceNat, getProvider())) { + publicNetwork = true; + } + boolean isPodBased = (dest.getDataCenter().getNetworkType() == NetworkType.Basic + || _networkMgr.isSecurityGroupSupportedInNetwork(network)) && + network.getTrafficType() == TrafficType.Guest; + + List routers; + + if (publicNetwork) { + routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); + } else { + Long podId = dest.getPod().getId(); + if (isPodBased) { + routers = _routerDao.listByNetworkAndPodAndRole(network.getId(), podId, Role.VIRTUAL_ROUTER); + } else { + routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); + } + } + + // for Basic zone, add all Running routers - we have to send Dhcp/vmData/password info to them when + // network.dns.basiczone.updates is set to "all" + Long podId = dest.getPod().getId(); + if (isPodBased && _routerMgr.getDnsBasicZoneUpdate().equalsIgnoreCase("all")) { + List allRunningRoutersOutsideThePod = _routerDao.findByNetworkOutsideThePod(network.getId(), + podId, State.Running, Role.VIRTUAL_ROUTER); + routers.addAll(allRunningRoutersOutsideThePod); + } + return routers; + } + @Override public List searchForVirtualRouterElement(ListVirtualRouterElementsCmd cmd) { Long id = cmd.getId(); diff --git a/server/src/com/cloud/network/element/VpcVirtualRouterElement.java b/server/src/com/cloud/network/element/VpcVirtualRouterElement.java new file mode 100644 index 00000000000..e5ae27e2675 --- /dev/null +++ b/server/src/com/cloud/network/element/VpcVirtualRouterElement.java @@ -0,0 +1,312 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.element; + + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.ejb.Local; + +import org.apache.log4j.Logger; + +import com.cloud.dc.DataCenter; +import com.cloud.deploy.DeployDestination; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.Network; +import com.cloud.network.Network.Capability; +import com.cloud.network.Network.Provider; +import com.cloud.network.Network.Service; +import com.cloud.network.NetworkService; +import com.cloud.network.PublicIpAddress; +import com.cloud.network.router.VirtualRouter; +import com.cloud.network.router.VpcVirtualNetworkApplianceManager; +import com.cloud.network.vpc.Vpc; +import com.cloud.network.vpc.VpcManager; +import com.cloud.offering.NetworkOffering; +import com.cloud.utils.component.Inject; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.vm.DomainRouterVO; +import com.cloud.vm.NicProfile; +import com.cloud.vm.ReservationContext; +import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachine.Type; +import com.cloud.vm.VirtualMachineProfile; + +/** + * @author Alena Prokharchyk + */ +@Local(value = NetworkElement.class) +public class VpcVirtualRouterElement extends VirtualRouterElement implements VpcProvider{ + private static final Logger s_logger = Logger.getLogger(VpcVirtualRouterElement.class); + @Inject + NetworkService _ntwkService; + @Inject + VpcManager _vpcMgr; + @Inject + VpcVirtualNetworkApplianceManager _vpcRouterMgr; + + + private static final Map> capabilities = setCapabilities(); + + + @Override + protected boolean canHandle(Network network, Service service) { + Long physicalNetworkId = _networkMgr.getPhysicalNetworkId(network); + if (physicalNetworkId == null) { + return false; + } + + if (network.getVpcId() == null) { + return false; + } + + if (!_networkMgr.isProviderEnabledInPhysicalNetwork(physicalNetworkId, Network.Provider.VPCVirtualRouter.getName())) { + return false; + } + + if (service == null) { + if (!_networkMgr.isProviderForNetwork(getProvider(), network.getId())) { + s_logger.trace("Element " + getProvider().getName() + " is not a provider for the network " + network); + return false; + } + } else { + if (!_networkMgr.isProviderSupportServiceInNetwork(network.getId(), service, getProvider())) { + s_logger.trace("Element " + getProvider().getName() + " doesn't support service " + service.getName() + + " in the network " + network); + return false; + } else if (service == Service.Firewall) { + //todo - get capability here + } + } + + return true; + } + + + @Override + public boolean implementVpc(Vpc vpc, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, + ResourceUnavailableException, InsufficientCapacityException { + + Map params = new HashMap(1); + params.put(VirtualMachineProfile.Param.ReProgramGuestNetworks, true); + + _vpcRouterMgr.deployVirtualRouterInVpc(vpc, dest, _accountMgr.getAccount(vpc.getAccountId()), params); + + return true; + } + + @Override + public boolean shutdownVpc(Vpc vpc) throws ConcurrentOperationException, ResourceUnavailableException { + List routers = _routerDao.listRoutersByVpcId(vpc.getId()); + if (routers == null || routers.isEmpty()) { + return true; + } + boolean result = true; + for (DomainRouterVO router : routers) { + result = result && (_routerMgr.destroyRouter(router.getId()) != null); + } + return result; + } + + @Override + public boolean implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) + throws ResourceUnavailableException, ConcurrentOperationException, + InsufficientCapacityException { + + Long vpcId = network.getVpcId(); + if (vpcId == null) { + s_logger.warn("Network " + network + " is not associated with any VPC"); + return false; + } + + Vpc vpc = _vpcMgr.getActiveVpc(vpcId); + if (vpc == null) { + s_logger.warn("Unable to find Enabled VPC by id " + vpcId); + return false; + } + + Map params = new HashMap(1); + params.put(VirtualMachineProfile.Param.ReProgramGuestNetworks, true); + + List routers = _vpcRouterMgr.deployVirtualRouterInVpc(vpc, dest, _accountMgr.getAccount(vpc.getAccountId()), params); + if ((routers == null) || (routers.size() == 0)) { + throw new ResourceUnavailableException("Can't find at least one running router!", + DataCenter.class, network.getDataCenterId()); + } + + return true; + } + + @Override + public boolean prepare(Network network, NicProfile nic, VirtualMachineProfile vm, + DeployDestination dest, ReservationContext context) + throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { + + Long vpcId = network.getVpcId(); + if (vpcId == null) { + s_logger.warn("Network " + network + " is not associated with any VPC"); + return false; + } + + Vpc vpc = _vpcMgr.getActiveVpc(vpcId); + if (vpc == null) { + s_logger.warn("Unable to find Enabled VPC by id " + vpcId); + return false; + } + + Map params = new HashMap(1); + params.put(VirtualMachineProfile.Param.ReProgramGuestNetworks, true); + + List routers = _vpcRouterMgr.deployVirtualRouterInVpc(vpc, dest, + _accountMgr.getAccount(vpc.getAccountId()), params); + if ((routers == null) || (routers.size() == 0)) { + throw new ResourceUnavailableException("Can't find at least one running router!", + DataCenter.class, network.getDataCenterId()); + } + + if (vm.getType() == Type.User) { + for (VirtualRouter router : routers) { + //Add router to guest network + if (!_networkMgr.isVmPartOfNetwork(router.getId(), network.getId())) { + if (!_vpcRouterMgr.addVpcRouterToGuestNetwork(router, network, false)) { + throw new CloudRuntimeException("Failed to add VPC router " + router + " to guest network " + network); + } else { + s_logger.debug("Successfully added VPC router " + router + " to guest network " + network); + } + } + } + } + + return true; + } + + @Override + public boolean shutdown(Network network, ReservationContext context, boolean cleanup) + throws ConcurrentOperationException, ResourceUnavailableException { + return true; + } + + @Override + public boolean destroy(Network config) throws ConcurrentOperationException, ResourceUnavailableException { + boolean success = true; + Long vpcId = config.getVpcId(); + if (vpcId == null) { + s_logger.debug("Network " + config + " doesn't belong to any vpc, so skipping unplug nic part"); + return success; + } + + List routers = _routerDao.listRoutersByVpcId(vpcId); + for (VirtualRouter router : routers) { + //1) Check if router is already a part of the network + if (!_ntwkService.isVmPartOfNetwork(router.getId(), config.getId())) { + s_logger.debug("Router " + router + " is not a part the network " + config); + continue; + } + //2) Call unplugNics in the network service + success = success && _vpcRouterMgr.removeRouterFromGuestNetwork(router, config, false); + if (!success) { + s_logger.warn("Failed to unplug nic in network " + config + " for virtual router " + router); + } else { + s_logger.debug("Successfully unplugged nic in network " + config + " for virtual router " + router); + } + } + + return success; + } + + @Override + public Provider getProvider() { + return Provider.VPCVirtualRouter; + } + + private static Map> setCapabilities() { + Map> capabilities = VirtualRouterElement.capabilities; + + Map sourceNatCapabilities = capabilities.get(Service.SourceNat); + sourceNatCapabilities.put(Capability.RedundantRouter, "false"); + capabilities.put(Service.SourceNat, sourceNatCapabilities); + + Map vpnCapabilities = capabilities.get(Service.Vpn); + vpnCapabilities.put(Capability.VpnTypes, "s2svpn"); + capabilities.put(Service.Vpn, vpnCapabilities); + + Map firewallCapabilities = capabilities.get(Service.Firewall); + firewallCapabilities.put(Capability.FirewallType, "percidr"); + capabilities.put(Service.Firewall, firewallCapabilities); + + return capabilities; + } + + @Override + public Map> getCapabilities() { + return capabilities; + } + + @Override + public boolean createPrivateGateway() { + //TODO - add implementation here + return true; + } + + @Override + public boolean createVpnGateway() { + //TODO - add implementation here + return true; + } + + @Override + public boolean deletePrivateGateway() { + //TODO - add implementation here + return true; + } + + @Override + public boolean deleteVpnGateway() { + //TODO - add implementation here + return true; + } + + @Override + protected List getRouters(Network network, DeployDestination dest) { + return _vpcMgr.getVpcRouters(network.getVpcId()); + } + + @Override + public boolean applyIps(Network network, List ipAddress, Set services) + throws ResourceUnavailableException { + boolean canHandle = true; + for (Service service : services) { + if (!canHandle(network, service)) { + canHandle = false; + break; + } + } + if (canHandle) { + List routers = getRouters(network, null); + if (routers == null || routers.isEmpty()) { + s_logger.debug(this.getName() + " element doesn't need to associate ip addresses on the backend; VPC virtual " + + "router doesn't exist in the network " + network.getId()); + return true; + } + + return _vpcRouterMgr.associateIP(network, ipAddress, routers); + } else { + return false; + } + } +} diff --git a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java b/server/src/com/cloud/network/firewall/FirewallManagerImpl.java index aef6d7ca77e..506b615bd9d 100644 --- a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java +++ b/server/src/com/cloud/network/firewall/FirewallManagerImpl.java @@ -33,6 +33,7 @@ import com.cloud.event.EventTypes; import com.cloud.event.UsageEventVO; import com.cloud.event.dao.EventDao; import com.cloud.event.dao.UsageEventDao; +import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.NetworkRuleConflictException; import com.cloud.exception.ResourceUnavailableException; @@ -131,21 +132,38 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma public FirewallRule createFirewallRule(FirewallRule rule) throws NetworkRuleConflictException { Account caller = UserContext.current().getCaller(); - return createFirewallRule(rule.getSourceIpAddressId(), caller, rule.getXid(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), rule.getSourceCidrList(), rule.getIcmpCode(), - rule.getIcmpType(), null, rule.getType()); + return createFirewallRule(rule.getSourceIpAddressId(), caller, rule.getXid(), rule.getSourcePortStart(), + rule.getSourcePortEnd(), rule.getProtocol(), rule.getSourceCidrList(), rule.getIcmpCode(), + rule.getIcmpType(), null, rule.getType(), rule.getNetworkId()); } @DB @Override @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_OPEN, eventDescription = "creating firewall rule", create = true) - public FirewallRule createFirewallRule(long ipAddrId, Account caller, String xId, Integer portStart, Integer portEnd, String protocol, List sourceCidrList, Integer icmpCode, Integer icmpType, - Long relatedRuleId, FirewallRule.FirewallRuleType type) throws NetworkRuleConflictException { + public FirewallRule createFirewallRule(long ipAddrId, Account caller, String xId, Integer portStart, + Integer portEnd, String protocol, List sourceCidrList, Integer icmpCode, Integer icmpType, + Long relatedRuleId, FirewallRule.FirewallRuleType type, long networkId) throws NetworkRuleConflictException { + IPAddressVO ipAddress = _ipAddressDao.findById(ipAddrId); - // Validate ip address if (ipAddress == null && type == FirewallRule.FirewallRuleType.User) { - throw new InvalidParameterValueException("Unable to create port forwarding rule; ip id=" + ipAddrId + " doesn't exist in the system"); + throw new InvalidParameterValueException("Unable to create port forwarding rule; ip id=" + ipAddrId + + " doesn't exist in the system"); } + + //associate ip address to network (if needed) + if (ipAddress.getAssociatedWithNetworkId() == null) { + s_logger.debug("The ip is not associated with the network id="+ networkId + " so assigning"); + try { + _networkMgr.associateIPToGuestNetwork(ipAddrId, networkId); + } catch (Exception ex) { + s_logger.warn("Failed to associate ip id=" + ipAddrId + " to network id=" + networkId + " as " + + "a part of firewall rule creation"); + return null; + } + } + + _networkMgr.checkIpForService(ipAddress, Service.Firewall); validateFirewallRule(caller, ipAddress, portStart, portEnd, protocol, Purpose.Firewall, type); @@ -158,17 +176,14 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma throw new InvalidParameterValueException("Can't specify start/end port when protocol is ICMP"); } - Long networkId = null; Long accountId = null; Long domainId = null; if (ipAddress != null) { - networkId = ipAddress.getAssociatedWithNetworkId(); accountId = ipAddress.getAllocatedToAccountId(); domainId = ipAddress.getAllocatedInDomainId(); } - _networkMgr.checkIpForService(ipAddress, Service.Firewall); Transaction txn = Transaction.currentTxn(); txn.start(); @@ -369,7 +384,8 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma } @Override - public boolean applyRules(List rules, boolean continueOnError, boolean updateRulesInDB) throws ResourceUnavailableException { + public boolean applyRules(List rules, boolean continueOnError, boolean updateRulesInDB) + throws ResourceUnavailableException { boolean success = true; if (!_networkMgr.applyRules(rules, continueOnError)) { s_logger.warn("Rules are not completely applied"); @@ -380,10 +396,11 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma if (rule.getState() == FirewallRule.State.Revoke) { FirewallRuleVO relatedRule = _firewallDao.findByRelatedId(rule.getId()); if (relatedRule != null) { - s_logger.warn("Can't remove the firewall rule id=" + rule.getId() + " as it has related firewall rule id=" + relatedRule.getId() + "; leaving it in Revoke state"); + s_logger.warn("Can't remove the firewall rule id=" + rule.getId() + + " as it has related firewall rule id=" + relatedRule.getId() + "; leaving it in Revoke state"); success = false; } else { - _firewallDao.remove(rule.getId()); + removeRule(rule); } } else if (rule.getState() == FirewallRule.State.Add) { FirewallRuleVO ruleVO = _firewallDao.findById(rule.getId()); @@ -397,6 +414,23 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma return success; } + @DB + protected void removeRule(FirewallRule rule) { + //Lock ip address + IpAddress ip = _ipAddressDao.findById(rule.getSourceIpAddressId()); + + Transaction txn = Transaction.currentTxn(); + txn.start(); + //remove the rule + _firewallDao.remove(rule.getId()); + if (ip.getVpcId() != null && _firewallDao.listByIp(ip.getId()).isEmpty()) { + //if the rule is the last one for the ip address assigned to VPC, unassign it from the network + _networkMgr.unassignIPFromVpcNetwork(ip.getId()); + } + + txn.commit(); + } + @Override public boolean applyFirewallRules(long ipId, Account caller) throws ResourceUnavailableException { List rules = _firewallDao.listByIpAndPurpose(ipId, Purpose.Firewall); @@ -535,18 +569,21 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma } @Override - public FirewallRule createRuleForAllCidrs(long ipAddrId, Account caller, Integer startPort, Integer endPort, String protocol, Integer icmpCode, Integer icmpType, Long relatedRuleId) + public FirewallRule createRuleForAllCidrs(long ipAddrId, Account caller, + Integer startPort, Integer endPort, String protocol, Integer icmpCode, Integer icmpType, Long relatedRuleId, long networkId) throws NetworkRuleConflictException { // If firwallRule for this port range already exists, return it - List rules = _firewallDao.listByIpPurposeAndProtocolAndNotRevoked(ipAddrId, startPort, endPort, protocol, Purpose.Firewall); + List rules = _firewallDao.listByIpPurposeAndProtocolAndNotRevoked(ipAddrId, startPort, endPort, + protocol, Purpose.Firewall); if (!rules.isEmpty()) { return rules.get(0); } List oneCidr = new ArrayList(); oneCidr.add(NetUtils.ALL_CIDRS); - return createFirewallRule(ipAddrId, caller, null, startPort, endPort, protocol, oneCidr, icmpCode, icmpType, relatedRuleId, FirewallRule.FirewallRuleType.User); + return createFirewallRule(ipAddrId, caller, null, startPort, endPort, protocol, oneCidr, icmpCode, icmpType, + relatedRuleId, FirewallRule.FirewallRuleType.User, networkId); } @Override @@ -654,7 +691,7 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma for (FirewallRuleVO rule : systemRules) { try { this.createFirewallRule(ip.getId(), acct, rule.getXid(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), - rule.getSourceCidrList(), rule.getIcmpCode(), rule.getIcmpType(), rule.getRelated(), FirewallRuleType.System); + rule.getSourceCidrList(), rule.getIcmpCode(), rule.getIcmpType(), rule.getRelated(), FirewallRuleType.System, rule.getNetworkId()); } catch (Exception e) { s_logger.debug("Failed to add system wide firewall rule, due to:" + e.toString()); } diff --git a/server/src/com/cloud/network/guru/GuestNetworkGuru.java b/server/src/com/cloud/network/guru/GuestNetworkGuru.java index f9977102b1f..cb6f045bc68 100755 --- a/server/src/com/cloud/network/guru/GuestNetworkGuru.java +++ b/server/src/com/cloud/network/guru/GuestNetworkGuru.java @@ -42,11 +42,11 @@ import com.cloud.network.Network.State; import com.cloud.network.NetworkManager; import com.cloud.network.NetworkProfile; import com.cloud.network.NetworkVO; -import com.cloud.network.PhysicalNetworkVO; import com.cloud.network.Networks.AddressFormat; import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.Mode; import com.cloud.network.Networks.TrafficType; +import com.cloud.network.PhysicalNetworkVO; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.PhysicalNetworkDao; @@ -114,10 +114,12 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru { protected boolean canHandle(NetworkOffering offering, DataCenter dc) { // This guru handles only Guest Isolated network that supports Source nat service - if (dc.getNetworkType() == NetworkType.Advanced && isMyTrafficType(offering.getTrafficType()) && offering.getGuestType() == Network.GuestType.Isolated) { + if (dc.getNetworkType() == NetworkType.Advanced && isMyTrafficType(offering.getTrafficType()) + && offering.getGuestType() == Network.GuestType.Isolated && !offering.isSystemOnly()) { return true; } else { - s_logger.trace("We only take care of Guest networks of type " + GuestType.Isolated + " in zone of type " + NetworkType.Advanced); + s_logger.trace("We only take care of non-system Guest networks of type " + GuestType.Isolated + " in zone of type " + + NetworkType.Advanced); return false; } } @@ -129,9 +131,11 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru { return null; } - NetworkVO network = new NetworkVO(offering.getTrafficType(), Mode.Dhcp, BroadcastDomainType.Vlan, offering.getId(), State.Allocated, plan.getDataCenterId(), plan.getPhysicalNetworkId()); + NetworkVO network = new NetworkVO(offering.getTrafficType(), Mode.Dhcp, BroadcastDomainType.Vlan, offering.getId(), + State.Allocated, plan.getDataCenterId(), plan.getPhysicalNetworkId()); if (userSpecified != null) { - if ((userSpecified.getCidr() == null && userSpecified.getGateway() != null) || (userSpecified.getCidr() != null && userSpecified.getGateway() == null)) { + if ((userSpecified.getCidr() == null && userSpecified.getGateway() != null) || + (userSpecified.getCidr() != null && userSpecified.getGateway() == null)) { throw new InvalidParameterValueException("cidr and gateway must be specified together."); } @@ -185,54 +189,6 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru { } } -// @Override -// @DB -// public Ip4Address acquireIp4Address(Network network, Ip4Address requestedIp, String reservationId) { -// List ips = _nicDao.listIpAddressInNetwork(network.getId()); -// String[] cidr = network.getCidr().split("/"); -// Set allPossibleIps = NetUtils.getAllIpsFromCidr(cidr[0], Integer.parseInt(cidr[1])); -// Set usedIps = new TreeSet(); -// -// if (requestedIp != null && requestedIp.equals(network.getGateway())) { -// s_logger.warn("Requested ip address " + requestedIp + " is used as a gateway address in network " + network); -// return null; -// } -// -// for (String ip : ips) { -// if (requestedIp != null && requestedIp.equals(ip)) { -// s_logger.warn("Requested ip address " + requestedIp + " is already in use in network " + network); -// return null; -// } -// -// usedIps.add(NetUtils.ip2Long(ip)); -// } -// if (usedIps.size() != 0) { -// allPossibleIps.removeAll(usedIps); -// } -// if (allPossibleIps.isEmpty()) { -// return null; -// } -// -// Long[] array = allPossibleIps.toArray(new Long[allPossibleIps.size()]); -// -// if (requestedIp != null) { -// //check that requested ip has the same cidr -// boolean isSameCidr = NetUtils.sameSubnetCIDR(requestedIp, NetUtils.long2Ip(array[0]), Integer.parseInt(cidr[1])); -// if (!isSameCidr) { -// s_logger.warn("Requested ip address " + requestedIp + " doesn't belong to the network " + network + " cidr"); -// return null; -// } else { -// return requestedIp; -// } -// } -// -// String result; -// do { -// result = NetUtils.long2Ip(array[_rand.nextInt(array.length)]); -// } while (result.split("\\.")[3].equals("1")); -// return result; -// } - public Ip4Address acquireIp4Address(Network network, Ip4Address requestedIp, String reservationId) { List ips = _nicDao.listIpAddressInNetwork(network.getId()); String[] cidr = network.getCidr().split("/"); @@ -303,17 +259,20 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru { if (network.getBroadcastUri() == null) { String vnet = _dcDao.allocateVnet(dcId, physicalNetworkId, network.getAccountId(), reservationId); if (vnet == null) { - throw new InsufficientVirtualNetworkCapcityException("Unable to allocate vnet as a part of network " + network + " implement ", DataCenter.class, dcId); + throw new InsufficientVirtualNetworkCapcityException("Unable to allocate vnet as a " + + "part of network " + network + " implement ", DataCenter.class, dcId); } implemented.setBroadcastUri(BroadcastDomainType.Vlan.toUri(vnet)); - EventUtils.saveEvent(UserContext.current().getCallerUserId(), network.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_ZONE_VLAN_ASSIGN, "Assigned Zone Vlan: "+vnet+ " Network Id: "+network.getId(), 0); + EventUtils.saveEvent(UserContext.current().getCallerUserId(), network.getAccountId(), + EventVO.LEVEL_INFO, EventTypes.EVENT_ZONE_VLAN_ASSIGN, "Assigned Zone Vlan: "+vnet+ " Network Id: "+network.getId(), 0); } else { implemented.setBroadcastUri(network.getBroadcastUri()); } } @Override - public Network implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws InsufficientVirtualNetworkCapcityException { + public Network implement(Network network, NetworkOffering offering, DeployDestination dest, + ReservationContext context) throws InsufficientVirtualNetworkCapcityException { assert (network.getState() == State.Implementing) : "Why are we implementing " + network; long dcId = dest.getDataCenter().getId(); @@ -321,7 +280,8 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru { //get physical network id long physicalNetworkId = _networkMgr.findPhysicalNetworkId(dcId, offering.getTags(), offering.getTrafficType()); - NetworkVO implemented = new NetworkVO(network.getTrafficType(), network.getMode(), network.getBroadcastDomainType(), network.getNetworkOfferingId(), State.Allocated, + NetworkVO implemented = new NetworkVO(network.getTrafficType(), network.getMode(), + network.getBroadcastDomainType(), network.getNetworkOfferingId(), State.Allocated, network.getDataCenterId(), physicalNetworkId); allocateVnet(network, implemented, dcId, physicalNetworkId, context.getReservationId()); @@ -337,10 +297,12 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru { } @Override - public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapcityException, + public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile vm) + throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException { - assert (network.getTrafficType() == TrafficType.Guest) : "Look at my name! Why are you calling me when the traffic type is : " + network.getTrafficType(); + assert (network.getTrafficType() == TrafficType.Guest) : "Look at my name! Why are you calling" + + " me when the traffic type is : " + network.getTrafficType(); if (nic == null) { nic = new NicProfile(ReservationStrategy.Start, null, null, null, null); @@ -351,15 +313,21 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru { if (nic.getIp4Address() == null) { nic.setBroadcastUri(network.getBroadcastUri()); nic.setIsolationUri(network.getBroadcastUri()); - nic.setGateway(network.getGateway()); String guestIp = null; if (network.getSpecifyIpRanges()) { _networkMgr.allocateDirectIp(nic, dc, vm, network, nic.getRequestedIp()); } else { - guestIp = _networkMgr.acquireGuestIpAddress(network, nic.getRequestedIp()); - if (guestIp == null) { - throw new InsufficientVirtualNetworkCapcityException("Unable to acquire Guest IP address for network " + network, DataCenter.class, dc.getId()); + //if Vm is router vm, set ip4 to the network gateway + if (vm.getVirtualMachine().getType() == VirtualMachine.Type.DomainRouter) { + guestIp = network.getGateway(); + } else { + nic.setGateway(network.getGateway()); + guestIp = _networkMgr.acquireGuestIpAddress(network, nic.getRequestedIp()); + if (guestIp == null) { + throw new InsufficientVirtualNetworkCapcityException("Unable to acquire Guest IP" + + " address for network " + network, DataCenter.class, dc.getId()); + } } nic.setIp4Address(guestIp); @@ -393,7 +361,8 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru { } @Override - public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) + public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, + DeployDestination dest, ReservationContext context) throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException { assert (nic.getReservationStrategy() == ReservationStrategy.Start) : "What can I do for nics that are not allocated at start? "; @@ -412,8 +381,10 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru { public void shutdown(NetworkProfile profile, NetworkOffering offering) { s_logger.debug("Releasing vnet for the network id=" + profile.getId()); if (profile.getBroadcastUri() != null && !offering.getSpecifyVlan()) { - _dcDao.releaseVnet(profile.getBroadcastUri().getHost(), profile.getDataCenterId(), profile.getPhysicalNetworkId(), profile.getAccountId(), profile.getReservationId()); - EventUtils.saveEvent(UserContext.current().getCallerUserId(), profile.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_ZONE_VLAN_RELEASE, "Released Zone Vlan: " + _dcDao.releaseVnet(profile.getBroadcastUri().getHost(), profile.getDataCenterId(), + profile.getPhysicalNetworkId(), profile.getAccountId(), profile.getReservationId()); + EventUtils.saveEvent(UserContext.current().getCallerUserId(), profile.getAccountId(), + EventVO.LEVEL_INFO, EventTypes.EVENT_ZONE_VLAN_RELEASE, "Released Zone Vlan: " +profile.getBroadcastUri().getHost()+" for Network: "+profile.getId(), 0); profile.setBroadcastUri(null); } diff --git a/server/src/com/cloud/network/guru/PrivateNetworkGuru.java b/server/src/com/cloud/network/guru/PrivateNetworkGuru.java new file mode 100644 index 00000000000..27c05981a6d --- /dev/null +++ b/server/src/com/cloud/network/guru/PrivateNetworkGuru.java @@ -0,0 +1,215 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.guru; + +import javax.ejb.Local; + +import org.apache.log4j.Logger; + +import com.cloud.configuration.ConfigurationManager; +import com.cloud.dc.DataCenter; +import com.cloud.dc.DataCenter.NetworkType; +import com.cloud.deploy.DeployDestination; +import com.cloud.deploy.DeploymentPlan; +import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.exception.InsufficientVirtualNetworkCapcityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.network.Network; +import com.cloud.network.Network.GuestType; +import com.cloud.network.Network.State; +import com.cloud.network.NetworkProfile; +import com.cloud.network.NetworkVO; +import com.cloud.network.Networks.BroadcastDomainType; +import com.cloud.network.Networks.Mode; +import com.cloud.network.Networks.TrafficType; +import com.cloud.network.vpc.PrivateIpVO; +import com.cloud.network.vpc.Dao.PrivateIpDao; +import com.cloud.offering.NetworkOffering; +import com.cloud.user.Account; +import com.cloud.utils.component.AdapterBase; +import com.cloud.utils.component.Inject; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.net.NetUtils; +import com.cloud.vm.Nic.ReservationStrategy; +import com.cloud.vm.NicProfile; +import com.cloud.vm.ReservationContext; +import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachineProfile; + +@Local(value = NetworkGuru.class) +public class PrivateNetworkGuru extends AdapterBase implements NetworkGuru { + private static final Logger s_logger = Logger.getLogger(PrivateNetworkGuru.class); + @Inject + protected ConfigurationManager _configMgr; + @Inject + protected PrivateIpDao _privateIpDao; + + private static final TrafficType[] _trafficTypes = {TrafficType.Guest}; + + protected PrivateNetworkGuru() { + super(); + } + + @Override + public boolean isMyTrafficType(TrafficType type) { + for (TrafficType t : _trafficTypes) { + if (t == type) { + return true; + } + } + return false; + } + + @Override + public TrafficType[] getSupportedTrafficType() { + return _trafficTypes; + } + + protected boolean canHandle(NetworkOffering offering, DataCenter dc) { + // This guru handles only system Guest network + if (dc.getNetworkType() == NetworkType.Advanced && isMyTrafficType(offering.getTrafficType()) + && offering.getGuestType() == Network.GuestType.Isolated && offering.isSystemOnly()) { + return true; + } else { + s_logger.trace("We only take care of system Guest networks of type " + GuestType.Isolated + " in zone of type " + + NetworkType.Advanced); + return false; + } + } + + @Override + public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) { + DataCenter dc = _configMgr.getZone(plan.getDataCenterId()); + if (!canHandle(offering, dc)) { + return null; + } + + NetworkVO network = new NetworkVO(offering.getTrafficType(), Mode.Dhcp, BroadcastDomainType.Vlan, offering.getId(), + State.Allocated, plan.getDataCenterId(), plan.getPhysicalNetworkId()); + if (userSpecified != null) { + if ((userSpecified.getCidr() == null && userSpecified.getGateway() != null) || + (userSpecified.getCidr() != null && userSpecified.getGateway() == null)) { + throw new InvalidParameterValueException("cidr and gateway must be specified together."); + } + + if (userSpecified.getCidr() != null) { + network.setCidr(userSpecified.getCidr()); + network.setGateway(userSpecified.getGateway()); + } else { + String guestNetworkCidr = dc.getGuestNetworkCidr(); + if (guestNetworkCidr != null) { + String[] cidrTuple = guestNetworkCidr.split("\\/"); + network.setGateway(NetUtils.getIpRangeStartIpFromCidr(cidrTuple[0], Long.parseLong(cidrTuple[1]))); + network.setCidr(guestNetworkCidr); + } else if (dc.getNetworkType() == NetworkType.Advanced) { + throw new CloudRuntimeException("Can't design network " + network + "; guest CIDR is not configured per zone " + dc); + } + } + + if (offering.getSpecifyVlan()) { + network.setBroadcastUri(userSpecified.getBroadcastUri()); + network.setState(State.Setup); + } + } else { + throw new CloudRuntimeException("Can't design network " + network + "; netmask/gateway must be passed in"); + + } + + return network; + } + + @Override + public void deallocate(Network network, NicProfile nic, VirtualMachineProfile vm) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Deallocate network: networkId: " + nic.getNetworkId() + ", ip: " + nic.getIp4Address()); + } + + PrivateIpVO ip = _privateIpDao.findByIpAndSourceNetworkId(nic.getNetworkId(), nic.getIp4Address()); + if (ip != null) { + _privateIpDao.releaseIpAddress(nic.getIp4Address(), nic.getNetworkId()); + } + nic.deallocate(); + } + + + @Override + public Network implement(Network network, NetworkOffering offering, DeployDestination dest, + ReservationContext context) throws InsufficientVirtualNetworkCapcityException { + + return network; + } + + @Override + public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile vm) + throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException { + DataCenter dc = _configMgr.getZone(network.getDataCenterId()); + NetworkOffering offering = _configMgr.getNetworkOffering(network.getNetworkOfferingId()); + if (!canHandle(offering, dc)) { + return null; + } + + if (nic == null) { + nic = new NicProfile(ReservationStrategy.Create, null, null, null, null); + } else if (nic.getIp4Address() == null) { + nic.setStrategy(ReservationStrategy.Start); + } else { + nic.setStrategy(ReservationStrategy.Create); + } + + _privateIpDao.allocateIpAddress(network.getDataCenterId(), network.getId()); + nic.setStrategy(ReservationStrategy.Create); + + return nic; + } + + @Override + public void updateNicProfile(NicProfile profile, Network network) { + DataCenter dc = _configMgr.getZone(network.getDataCenterId()); + if (profile != null) { + profile.setDns1(dc.getDns1()); + profile.setDns2(dc.getDns2()); + } + } + + @Override + public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, + DeployDestination dest, ReservationContext context) + throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException { + if (nic.getIp4Address() == null) { + _privateIpDao.allocateIpAddress(network.getDataCenterId(), network.getId()); + nic.setStrategy(ReservationStrategy.Create); + } + } + + @Override + public boolean release(NicProfile nic, VirtualMachineProfile vm, String reservationId) { + return true; + } + + @Override + public void shutdown(NetworkProfile profile, NetworkOffering offering) { + + } + + @Override + public boolean trash(Network network, NetworkOffering offering, Account owner) { + return true; + } + + @Override + public void updateNetworkProfile(NetworkProfile networkProfile) { + DataCenter dc = _configMgr.getZone(networkProfile.getDataCenterId()); + networkProfile.setDns1(dc.getDns1()); + networkProfile.setDns2(dc.getDns2()); + } +} diff --git a/server/src/com/cloud/network/guru/PublicNetworkGuru.java b/server/src/com/cloud/network/guru/PublicNetworkGuru.java index d26493872cd..d094445c2f8 100755 --- a/server/src/com/cloud/network/guru/PublicNetworkGuru.java +++ b/server/src/com/cloud/network/guru/PublicNetworkGuru.java @@ -132,7 +132,8 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru { } @Override - public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapcityException, + public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile vm) + throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException, ConcurrentOperationException { DataCenter dc = _dcDao.findById(network.getDataCenterId()); @@ -172,7 +173,8 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru { } @Override - public Network implement(Network network, NetworkOffering offering, DeployDestination destination, ReservationContext context) throws InsufficientVirtualNetworkCapcityException { + public Network implement(Network network, NetworkOffering offering, DeployDestination destination, ReservationContext context) + throws InsufficientVirtualNetworkCapcityException { return network; } diff --git a/server/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java b/server/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java index a5d9a39c547..1870518c2a8 100644 --- a/server/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java +++ b/server/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java @@ -39,6 +39,8 @@ import com.cloud.agent.api.check.CheckSshCommand; import com.cloud.agent.api.routing.LoadBalancerConfigCommand; import com.cloud.agent.api.routing.NetworkElementCommand; import com.cloud.agent.api.to.LoadBalancerTO; +import com.cloud.agent.api.to.NicTO; +import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.manager.Commands; import com.cloud.api.commands.CreateLoadBalancerRuleCmd; import com.cloud.configuration.Config; @@ -128,6 +130,7 @@ import com.cloud.vm.VirtualMachineName; import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.VirtualMachineProfile.Param; import com.cloud.vm.dao.DomainRouterDao; +import com.cloud.vm.dao.NicDao; @Local(value = { ElasticLoadBalancerManager.class }) public class ElasticLoadBalancerManagerImpl implements @@ -185,6 +188,8 @@ public class ElasticLoadBalancerManagerImpl implements PhysicalNetworkServiceProviderDao _physicalProviderDao; @Inject VirtualRouterProviderDao _vrProviderDao; + @Inject + NicDao _nicDao; String _name; @@ -224,7 +229,7 @@ public class ElasticLoadBalancerManagerImpl implements Pod pod = podId == null?null:_podDao.findById(podId); Map params = new HashMap( 1); - params.put(VirtualMachineProfile.Param.ReProgramNetwork, true); + params.put(VirtualMachineProfile.Param.ReProgramGuestNetworks, true); Account owner = _accountService.getActiveAccountByName("system", new Long(1)); DeployDestination dest = new DeployDestination(dc, pod, null, null); s_logger.debug("About to deploy ELB vm "); @@ -274,7 +279,7 @@ public class ElasticLoadBalancerManagerImpl implements } private void createApplyLoadBalancingRulesCommands( - List rules, DomainRouterVO elbVm, Commands cmds) { + List rules, DomainRouterVO elbVm, Commands cmds, long guestNetworkId) { LoadBalancerTO[] lbs = new LoadBalancerTO[rules.size()]; @@ -293,7 +298,8 @@ public class ElasticLoadBalancerManagerImpl implements lbs[i++] = lb; } - LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(lbs,elbVm.getPublicIpAddress(),elbVm.getGuestIpAddress(),elbVm.getPrivateIpAddress()); + LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(lbs,elbVm.getPublicIpAddress(), + _nicDao.getIpAddress(guestNetworkId, elbVm.getId()),elbVm.getPrivateIpAddress()); cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, elbVm.getPrivateIpAddress()); cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, @@ -310,9 +316,9 @@ public class ElasticLoadBalancerManagerImpl implements } protected boolean applyLBRules(DomainRouterVO elbVm, - List rules) throws ResourceUnavailableException { + List rules, long guestNetworkId) throws ResourceUnavailableException { Commands cmds = new Commands(OnError.Continue); - createApplyLoadBalancingRulesCommands(rules, elbVm, cmds); + createApplyLoadBalancingRulesCommands(rules, elbVm, cmds, guestNetworkId); // Send commands to elbVm return sendCommandsToRouter(elbVm, cmds); } @@ -357,7 +363,7 @@ public class ElasticLoadBalancerManagerImpl implements lb, dstList, policyList); lbRules.add(loadBalancing); } - return applyLBRules(elbVm, lbRules); + return applyLBRules(elbVm, lbRules, network.getId()); } else if (elbVm.getState() == State.Stopped || elbVm.getState() == State.Stopping) { s_logger.debug("ELB VM is in " @@ -496,8 +502,9 @@ public class ElasticLoadBalancerManagerImpl implements List> networks = new ArrayList>(2); NicProfile guestNic = new NicProfile(); guestNic.setDefaultNic(true); - networks.add(new Pair((NetworkVO) guestNetwork, guestNic)); networks.add(new Pair(controlConfig, null)); + networks.add(new Pair((NetworkVO) guestNetwork, guestNic)); + VMTemplateVO template = _templateDao.findSystemVMTemplate(dcId); @@ -512,8 +519,10 @@ public class ElasticLoadBalancerManagerImpl implements throw new CloudRuntimeException("Cannot find virtual router provider " + typeString + " as service provider " + provider.getId()); } - elbVm = new DomainRouterVO(id, _elasticLbVmOffering.getId(), vrProvider.getId(), VirtualMachineName.getSystemVmName(id, _instance, _elbVmNamePrefix), template.getId(), template.getHypervisorType(), - template.getGuestOSId(), owner.getDomainId(), owner.getId(), guestNetwork.getId(), false, 0, false, RedundantState.UNKNOWN, _elasticLbVmOffering.getOfferHA(), false, VirtualMachine.Type.ElasticLoadBalancerVm); + elbVm = new DomainRouterVO(id, _elasticLbVmOffering.getId(), vrProvider.getId(), + VirtualMachineName.getSystemVmName(id, _instance, _elbVmNamePrefix), template.getId(), template.getHypervisorType(), + template.getGuestOSId(), owner.getDomainId(), owner.getId(), false, 0, false, RedundantState.UNKNOWN, + _elasticLbVmOffering.getOfferHA(), false, VirtualMachine.Type.ElasticLoadBalancerVm, null); elbVm.setRole(Role.LB); elbVm = _itMgr.allocate(elbVm, template, _elasticLbVmOffering, networks, plan, null, owner); //TODO: create usage stats @@ -607,7 +616,7 @@ public class ElasticLoadBalancerManagerImpl implements IPAddressVO ipvo = _ipAddressDao.findById(ipId); ipvo.setAssociatedWithNetworkId(null); _ipAddressDao.update(ipvo.getId(), ipvo); - _networkMgr.releasePublicIpAddress(ipId, userId, caller); + _networkMgr.disassociatePublicIpAddress(ipId, userId, caller); _ipAddressDao.unassignIpAddress(ipId); } @@ -801,7 +810,17 @@ public class ElasticLoadBalancerManagerImpl implements @Override public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) { DomainRouterVO elbVm = profile.getVirtualMachine(); - NetworkVO network = _networkDao.findById(elbVm.getNetworkId()); + + List elbNics = profile.getNics(); + Long guestNtwkId = null; + for (NicProfile routerNic : elbNics) { + if (routerNic.getTrafficType() == TrafficType.Guest) { + guestNtwkId = routerNic.getNetworkId(); + break; + } + } + + NetworkVO guestNetwork = _networkDao.findById(guestNtwkId); DataCenter dc = dest.getDataCenter(); @@ -842,12 +861,13 @@ public class ElasticLoadBalancerManagerImpl implements // ask elb vm to setup SSH on guest network buf.append(" sshonguest=true"); } + } controlNic = nic; } } - String domain = network.getNetworkDomain(); + String domain = guestNetwork.getNetworkDomain(); if (domain != null) { buf.append(" domain=" + domain); } @@ -879,8 +899,6 @@ public class ElasticLoadBalancerManagerImpl implements elbVm.setPublicIpAddress(nic.getIp4Address()); elbVm.setPublicNetmask(nic.getNetmask()); elbVm.setPublicMacAddress(nic.getMacAddress()); - } else if (nic.getTrafficType() == TrafficType.Guest) { - elbVm.setGuestIpAddress(nic.getIp4Address()); } else if (nic.getTrafficType() == TrafficType.Control) { elbVm.setPrivateIpAddress(nic.getIp4Address()); elbVm.setPrivateMacAddress(nic.getMacAddress()); @@ -911,6 +929,7 @@ public class ElasticLoadBalancerManagerImpl implements DataCenterVO dcVo = _dcDao.findById(elbVm.getDataCenterIdToDeployIn()); NicProfile controlNic = null; + Long guestNetworkId = null; if(profile.getHypervisorType() == HypervisorType.VMware && dcVo.getNetworkType() == NetworkType.Basic) { // TODO this is a ugly to test hypervisor type here @@ -918,12 +937,15 @@ public class ElasticLoadBalancerManagerImpl implements for (NicProfile nic : profile.getNics()) { if (nic.getTrafficType() == TrafficType.Guest && nic.getIp4Address() != null) { controlNic = nic; + guestNetworkId = nic.getNetworkId(); } } } else { for (NicProfile nic : profile.getNics()) { if (nic.getTrafficType() == TrafficType.Control && nic.getIp4Address() != null) { controlNic = nic; + } else if (nic.getTrafficType() == TrafficType.Guest) { + guestNetworkId = nic.getNetworkId(); } } } @@ -947,7 +969,7 @@ public class ElasticLoadBalancerManagerImpl implements s_logger.debug("Found " + lbRules.size() + " load balancing rule(s) to apply as a part of ELB vm " + elbVm + " start."); if (!lbRules.isEmpty()) { - createApplyLoadBalancingRulesCommands(lbRules, elbVm, cmds); + createApplyLoadBalancingRulesCommands(lbRules, elbVm, cmds, guestNetworkId); } return true; @@ -974,7 +996,6 @@ public class ElasticLoadBalancerManagerImpl implements } - @Override public Long convertToId(String vmName) { if (!VirtualMachineName.isValidSystemVmName(vmName, _instance, _elbVmNamePrefix)) { @@ -983,4 +1004,20 @@ public class ElasticLoadBalancerManagerImpl implements return VirtualMachineName.getSystemVmId(vmName); } + + @Override + public boolean plugNic(Network network, NicTO nic, VirtualMachineTO vm, + ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException, + InsufficientCapacityException { + //not supported + throw new UnsupportedOperationException("Plug nic is not supported for vm of type " + vm.getType()); + } + + + @Override + public boolean unplugNic(Network network, NicTO nic, VirtualMachineTO vm, + ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException { + //not supported + throw new UnsupportedOperationException("Unplug nic is not supported for vm of type " + vm.getType()); + } } diff --git a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java index f3f72884fc1..e4ddfffda0b 100755 --- a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java +++ b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java @@ -702,7 +702,8 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa // Validate ip address if (ipAddressVo == null) { - throw new InvalidParameterValueException("Unable to create load balance rule; ip id=" + ipAddrId + " doesn't exist in the system"); + throw new InvalidParameterValueException("Unable to create load balance rule; ip id=" + ipAddrId + "" + + " doesn't exist in the system"); } else if (ipAddressVo.isOneToOneNat()) { throw new NetworkRuleConflictException("Can't do load balance on ip address: " + ipAddressVo.getAddress()); } @@ -719,7 +720,14 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa ip = _networkMgr.assignSystemIp(lb.getNetworkId(), lbOwner, true, false); lb.setSourceIpAddressId(ip.getId()); } + + + try { + if (ip.getAssociatedWithNetworkId() == null) { + s_logger.debug("The ip is not associated with the network id="+ lb.getNetworkId() + " so assigning"); + _networkMgr.associateIPToGuestNetwork(ipAddrId, lb.getNetworkId()); + } result = createLoadBalancer(lb, openFirewall); } catch (Exception ex) { s_logger.warn("Failed to create load balancer due to ", ex); @@ -755,10 +763,12 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa if (ipAddr == null || !ipAddr.readyToUse()) { throw new InvalidParameterValueException("Unable to create load balancer rule, invalid IP address id" + sourceIpId); } else if (ipAddr.isOneToOneNat()) { - throw new InvalidParameterValueException("Unable to create load balancer rule; ip id=" + sourceIpId + " has static nat enabled"); + throw new InvalidParameterValueException("Unable to create load balancer rule; ip id=" + sourceIpId + + " has static nat enabled"); } - _firewallMgr.validateFirewallRule(caller.getCaller(), ipAddr, srcPortStart, srcPortEnd, lb.getProtocol(), Purpose.LoadBalancing, FirewallRuleType.User); + _firewallMgr.validateFirewallRule(caller.getCaller(), ipAddr, srcPortStart, srcPortEnd, lb.getProtocol(), + Purpose.LoadBalancing, FirewallRuleType.User); networkId = ipAddr.getAssociatedWithNetworkId(); if (networkId == null) { @@ -784,7 +794,8 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa newRule = _lbDao.persist(newRule); if (openFirewall) { - _firewallMgr.createRuleForAllCidrs(sourceIpId, caller.getCaller(), lb.getSourcePortStart(), lb.getSourcePortEnd(), lb.getProtocol(), null, null, newRule.getId()); + _firewallMgr.createRuleForAllCidrs(sourceIpId, caller.getCaller(), lb.getSourcePortStart(), + lb.getSourcePortEnd(), lb.getProtocol(), null, null, newRule.getId(), networkId); } boolean success = true; @@ -931,7 +942,7 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesMa boolean success = true; if (ip.getSystem()) { s_logger.debug("Releasing system ip address " + lb.getSourceIpAddressId() + " as a part of delete lb rule"); - if (!_networkMgr.releasePublicIpAddress(lb.getSourceIpAddressId(), UserContext.current().getCallerUserId(), UserContext.current().getCaller())) { + if (!_networkMgr.disassociatePublicIpAddress(lb.getSourceIpAddressId(), UserContext.current().getCallerUserId(), UserContext.current().getCaller())) { s_logger.warn("Unable to release system ip address id=" + lb.getSourceIpAddressId() + " as a part of delete lb rule"); success = false; } else { diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java index 052cd0f7389..56ceac1309c 100644 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java @@ -24,7 +24,6 @@ import com.cloud.network.PublicIpAddress; import com.cloud.network.RemoteAccessVpn; import com.cloud.network.VirtualNetworkApplianceService; import com.cloud.network.VpnUser; -import com.cloud.network.Network.Provider; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.StaticNat; import com.cloud.user.Account; @@ -33,7 +32,6 @@ import com.cloud.uservm.UserVm; import com.cloud.utils.component.Manager; import com.cloud.vm.DomainRouterVO; import com.cloud.vm.NicProfile; -import com.cloud.vm.ReservationContext; import com.cloud.vm.VirtualMachineProfile; /** @@ -58,35 +56,42 @@ public interface VirtualNetworkApplianceManager extends Manager, VirtualNetworkA * @param routers TODO * */ - boolean savePasswordToRouter(Network network, NicProfile nic, VirtualMachineProfile profile, List routers) throws ResourceUnavailableException; - - boolean getRouterStatistics(long vmId, Map netStats, Map diskStats); - - List getRouters(long accountId, long zoneId); + boolean savePasswordToRouter(Network network, NicProfile nic, VirtualMachineProfile profile, + List routers) throws ResourceUnavailableException; + + List deployVirtualRouterInGuestNetwork(Network guestNetwork, DeployDestination dest, Account owner, + Map params, boolean isRedundant) throws InsufficientCapacityException, + ResourceUnavailableException, ConcurrentOperationException; - List deployVirtualRouter(Network guestNetwork, DeployDestination dest, Account owner, Map params, boolean isRedundant) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException; + boolean startRemoteAccessVpn(Network network, RemoteAccessVpn vpn, List routers) + throws ResourceUnavailableException; - boolean startRemoteAccessVpn(Network network, RemoteAccessVpn vpn, List routers) throws ResourceUnavailableException; - - boolean deleteRemoteAccessVpn(Network network, RemoteAccessVpn vpn, List routers) throws ResourceUnavailableException; + boolean deleteRemoteAccessVpn(Network network, RemoteAccessVpn vpn, List routers) + throws ResourceUnavailableException; - boolean associateIP (Network network, final List ipAddress, List routers) throws ResourceUnavailableException; + boolean associateIP (Network network, final List ipAddress, + List routers) throws ResourceUnavailableException; - boolean applyFirewallRules(Network network, final List rules, List routers) throws ResourceUnavailableException; + boolean applyFirewallRules(Network network, final List rules, + List routers) throws ResourceUnavailableException; List getRoutersForNetwork(long networkId); - String[] applyVpnUsers(Network network, List users, List routers) throws ResourceUnavailableException; + String[] applyVpnUsers(Network network, List users, List routers) + throws ResourceUnavailableException; - VirtualRouter stop(VirtualRouter router, boolean forced, User callingUser, Account callingAccount) throws ConcurrentOperationException, ResourceUnavailableException; + VirtualRouter stop(VirtualRouter router, boolean forced, User callingUser, Account callingAccount) + throws ConcurrentOperationException, ResourceUnavailableException; String getDnsBasicZoneUpdate(); - boolean applyStaticNats(Network network, final List rules, List routers) throws ResourceUnavailableException; + boolean applyStaticNats(Network network, final List rules, List routers) + throws ResourceUnavailableException; - boolean applyDhcpEntry(Network config, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, List routers) throws ResourceUnavailableException; + boolean applyDhcpEntry(Network config, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, + List routers) throws ResourceUnavailableException; - boolean applyUserData(Network config, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, List routers) throws ResourceUnavailableException; - - long getDefaultVirtualRouterServiceOfferingId(); + boolean applyUserData(Network config, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, + List routers) throws ResourceUnavailableException; + } diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index d044d4f3525..a6415b0fb66 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -67,8 +67,10 @@ import com.cloud.agent.api.routing.VpnUsersCfgCommand; import com.cloud.agent.api.to.FirewallRuleTO; import com.cloud.agent.api.to.IpAddressTO; import com.cloud.agent.api.to.LoadBalancerTO; +import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.PortForwardingRuleTO; import com.cloud.agent.api.to.StaticNatRuleTO; +import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.manager.Commands; import com.cloud.alert.AlertManager; import com.cloud.api.commands.UpgradeRouterCmd; @@ -95,10 +97,10 @@ import com.cloud.deploy.DeploymentPlan; import com.cloud.deploy.DeploymentPlanner.ExcludeList; import com.cloud.event.ActionEvent; import com.cloud.event.EventTypes; -import com.cloud.event.dao.EventDao; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.ConnectionException; +import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InsufficientServerCapacityException; import com.cloud.exception.InsufficientVirtualNetworkCapcityException; @@ -132,7 +134,6 @@ import com.cloud.network.VirtualRouterProvider.VirtualRouterProviderType; import com.cloud.network.VpnUser; import com.cloud.network.VpnUserVO; import com.cloud.network.addr.PublicIp; -import com.cloud.network.dao.FirewallRulesCidrsDao; import com.cloud.network.dao.FirewallRulesDao; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.LoadBalancerDao; @@ -163,13 +164,11 @@ import com.cloud.resource.ResourceManager; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.GuestOSVO; -import com.cloud.storage.StorageManager; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.Volume.Type; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.GuestOSDao; import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VMTemplateHostDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; @@ -197,6 +196,7 @@ import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.MacAddress; import com.cloud.utils.net.NetUtils; import com.cloud.vm.DomainRouterVO; +import com.cloud.vm.Nic; import com.cloud.vm.NicProfile; import com.cloud.vm.NicVO; import com.cloud.vm.ReservationContext; @@ -214,13 +214,13 @@ import com.cloud.vm.dao.DomainRouterDao; import com.cloud.vm.dao.NicDao; import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.UserVmDetailsDao; -import com.cloud.vm.dao.VMInstanceDao; /** * VirtualNetworkApplianceManagerImpl manages the different types of virtual network appliances available in the Cloud Stack. */ @Local(value = { VirtualNetworkApplianceManager.class, VirtualNetworkApplianceService.class }) -public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplianceManager, VirtualNetworkApplianceService, VirtualMachineGuru, Listener { +public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplianceManager, VirtualNetworkApplianceService, + VirtualMachineGuru, Listener { private static final Logger s_logger = Logger.getLogger(VirtualNetworkApplianceManagerImpl.class); String _name; @@ -245,24 +245,16 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian @Inject UserStatisticsDao _userStatsDao = null; @Inject - VolumeDao _volsDao = null; - @Inject HostDao _hostDao = null; @Inject - EventDao _eventDao = null; - @Inject ConfigurationDao _configDao; @Inject HostPodDao _podDao = null; @Inject - VMTemplateHostDao _vmTemplateHostDao = null; - @Inject UserStatsLogDao _userStatsLogDao = null; @Inject AgentManager _agentMgr; @Inject - StorageManager _storageMgr; - @Inject AlertManager _alertMgr; @Inject AccountManager _accountMgr; @@ -273,8 +265,6 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian @Inject UserVmDao _userVmDao; @Inject - FirewallRulesDao _firewallRulesDao; - @Inject UserStatisticsDao _statsDao = null; @Inject NetworkOfferingDao _networkOfferingDao = null; @@ -299,14 +289,10 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian @Inject RemoteAccessVpnDao _vpnDao; @Inject - VMInstanceDao _instanceDao; - @Inject NicDao _nicDao; @Inject VolumeDao _volumeDao = null; @Inject - FirewallRulesCidrsDao _firewallCidrsDao; - @Inject UserVmDetailsDao _vmDetailsDao; @Inject ClusterDao _clusterDao; @@ -328,7 +314,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian int _routerStatsInterval = 300; int _routerCheckInterval = 30; - private ServiceOfferingVO _offering; + protected ServiceOfferingVO _offering; private String _dnsBasicZoneUpdates = "all"; private boolean _disable_rp_filter = false; @@ -344,11 +330,6 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian Account _systemAcct; - @Override - public List getRouters(long accountId, long dataCenterId) { - return _routerDao.findBy(accountId, dataCenterId); - } - @Override public boolean sendSshKeysToHost(Long hostId, String pubKey, String prvKey) { ModifySshKeysCommand cmd = new ModifySshKeysCommand(pubKey, prvKey); @@ -426,7 +407,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian // Check that the service offering being upgraded to has the same storage pool preference as the VM's current service // offering if (currentServiceOffering.getUseLocalStorage() != newServiceOffering.getUseLocalStorage()) { - throw new InvalidParameterValueException("Can't upgrade, due to new local storage status : " + newServiceOffering.getUseLocalStorage() + " is different from " + throw new InvalidParameterValueException("Can't upgrade, due to new local storage status : " + + newServiceOffering.getUseLocalStorage() + " is different from " + "curruent local storage status: " + currentServiceOffering.getUseLocalStorage()); } @@ -500,7 +482,11 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian final Transaction txn = Transaction.currentTxn(); try { txn.start(); - final UserStatisticsVO userStats = _userStatsDao.lock(router.getAccountId(), router.getDataCenterIdToDeployIn(), router.getNetworkId(), null, router.getId(), router.getType().toString()); + //FIXME!!! - UserStats command should grab bytesSent/Received for all guest interfaces of the VR + List routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId()); + for (Long guestNtwkId : routerGuestNtwkIds) { + final UserStatisticsVO userStats = _userStatsDao.lock(router.getAccountId(), router.getDataCenterIdToDeployIn(), + guestNtwkId, null, router.getId(), router.getType().toString()); if (userStats != null) { final RebootAnswer sa = (RebootAnswer) answer; final Long received = sa.getBytesReceived(); @@ -535,6 +521,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } else { s_logger.warn("User stats were not created for account " + router.getAccountId() + " and dc " + router.getDataCenterIdToDeployIn()); } + } + txn.commit(); } catch (final Exception e) { txn.rollback(); @@ -542,28 +530,9 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } } - @Override - public boolean getRouterStatistics(final long vmId, final Map netStats, final Map diskStats) { - final DomainRouterVO router = _routerDao.findById(vmId); - - if (router == null || router.getState() != State.Running || router.getHostId() == null) { - return true; - } - - /* - * final GetVmStatsCommand cmd = new GetVmStatsCommand(router, router.getInstanceName()); final Answer answer = - * _agentMgr.easySend(router.getHostId(), cmd); if (answer == null) { return false; } - * - * final GetVmStatsAnswer stats = (GetVmStatsAnswer)answer; - * - * netStats.putAll(stats.getNetworkStats()); diskStats.putAll(stats.getDiskStats()); - */ - - return true; - } - @Override @ActionEvent(eventType = EventTypes.EVENT_ROUTER_REBOOT, eventDescription = "rebooting router Vm", async = true) - public VirtualRouter rebootRouter(long routerId, boolean reprogramNetwork) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { + public VirtualRouter rebootRouter(long routerId, boolean reprogramNetwork) throws ConcurrentOperationException, + ResourceUnavailableException, InsufficientCapacityException { Account caller = UserContext.current().getCaller(); // verify parameters @@ -577,7 +546,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian // Can reboot domain router only in Running state if (router == null || router.getState() != State.Running) { s_logger.warn("Unable to reboot, virtual router is not in the right state " + router.getState()); - throw new ResourceUnavailableException("Unable to reboot domR, it is not in right state " + router.getState(), DataCenter.class, router.getDataCenterIdToDeployIn()); + throw new ResourceUnavailableException("Unable to reboot domR, it is not in right state " + router.getState(), + DataCenter.class, router.getDataCenterIdToDeployIn()); } UserVO user = _userDao.findById(UserContext.current().getCallerUserId()); @@ -640,7 +610,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian _itMgr.registerGuru(VirtualMachine.Type.DomainRouter, this); boolean useLocalStorage = Boolean.parseBoolean(configs.get(Config.SystemVMUseLocalStorage.key())); - _offering = new ServiceOfferingVO("System Offering For Software Router", 1, _routerRamSize, _routerCpuMHz, null, null, true, null, useLocalStorage, true, null, true, VirtualMachine.Type.DomainRouter, true); + _offering = new ServiceOfferingVO("System Offering For Software Router", 1, _routerRamSize, _routerCpuMHz, null, + null, true, null, useLocalStorage, true, null, true, VirtualMachine.Type.DomainRouter, true); _offering.setUniqueName(ServiceOffering.routerDefaultOffUniqueName); _offering = _serviceOfferingDao.persistSystemServiceOffering(_offering); @@ -708,7 +679,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian endDate = cal.getTime().getTime(); } - _networkStatsUpdateExecutor.scheduleAtFixedRate(new NetworkStatsUpdateTask(), (endDate - System.currentTimeMillis()), (_usageAggregationRange * 60 * 1000), TimeUnit.MILLISECONDS); + _networkStatsUpdateExecutor.scheduleAtFixedRate(new NetworkStatsUpdateTask(), (endDate - System.currentTimeMillis()), + (_usageAggregationRange * 60 * 1000), TimeUnit.MILLISECONDS); if (_routerCheckInterval > 0) { _checkExecutor.scheduleAtFixedRate(new CheckRouterTask(), _routerCheckInterval, _routerCheckInterval, TimeUnit.SECONDS); @@ -736,12 +708,13 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian return VirtualMachineName.getRouterId(vmName); } - private VmDataCommand generateVmDataCommand(VirtualRouter router, String vmPrivateIpAddress, String userData, String serviceOffering, String zoneName, String guestIpAddress, String vmName, - String vmInstanceName, long vmId, String publicKey) { + private VmDataCommand generateVmDataCommand(VirtualRouter router, String vmPrivateIpAddress, String userData, + String serviceOffering, String zoneName, String guestIpAddress, String vmName, + String vmInstanceName, long vmId, String publicKey, long guestNetworkId) { VmDataCommand cmd = new VmDataCommand(vmPrivateIpAddress, vmName); cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, router.getGuestIpAddress()); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(guestNetworkId, router.getId())); cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); @@ -792,9 +765,14 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian for (DomainRouterVO router : routers) { String privateIP = router.getPrivateIpAddress(); + if (privateIP != null) { + List routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId()); + + for (Long guestNtwkId : routerGuestNtwkIds) { final NetworkUsageCommand usageCmd = new NetworkUsageCommand(privateIP, router.getHostName()); - UserStatisticsVO previousStats = _statsDao.findBy(router.getAccountId(), router.getDataCenterIdToDeployIn(), router.getNetworkId(), null, router.getId(), router.getType().toString()); + UserStatisticsVO previousStats = _statsDao.findBy(router.getAccountId(), + router.getDataCenterIdToDeployIn(), guestNtwkId, null, router.getId(), router.getType().toString()); NetworkUsageAnswer answer = null; try { answer = (NetworkUsageAnswer) _agentMgr.easySend(router.getHostId(), usageCmd); @@ -815,21 +793,27 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian continue; } txn.start(); - UserStatisticsVO stats = _statsDao.lock(router.getAccountId(), router.getDataCenterIdToDeployIn(), router.getNetworkId(), null, router.getId(), router.getType().toString()); + UserStatisticsVO stats = _statsDao.lock(router.getAccountId(), + router.getDataCenterIdToDeployIn(), guestNtwkId, null, router.getId(), router.getType().toString()); if (stats == null) { s_logger.warn("unable to find stats for account: " + router.getAccountId()); continue; } if(previousStats != null - && ((previousStats.getCurrentBytesReceived() != stats.getCurrentBytesReceived()) || (previousStats.getCurrentBytesSent() != stats.getCurrentBytesSent()))){ - s_logger.debug("Router stats changed from the time NetworkUsageCommand was sent. Ignoring current answer. Router: "+answer.getRouterName()+" Rcvd: " + answer.getBytesReceived()+ "Sent: " +answer.getBytesSent()); + && ((previousStats.getCurrentBytesReceived() != stats.getCurrentBytesReceived()) + || (previousStats.getCurrentBytesSent() != stats.getCurrentBytesSent()))){ + s_logger.debug("Router stats changed from the time NetworkUsageCommand was sent. " + + "Ignoring current answer. Router: "+answer.getRouterName()+" Rcvd: " + + answer.getBytesReceived()+ "Sent: " +answer.getBytesSent()); continue; } if (stats.getCurrentBytesReceived() > answer.getBytesReceived()) { if (s_logger.isDebugEnabled()) { - s_logger.debug("Received # of bytes that's less than the last one. Assuming something went wrong and persisting it. Router: "+answer.getRouterName()+" Reported: " + answer.getBytesReceived() + s_logger.debug("Received # of bytes that's less than the last one. " + + "Assuming something went wrong and persisting it. Router: " + + answer.getRouterName()+" Reported: " + answer.getBytesReceived() + " Stored: " + stats.getCurrentBytesReceived()); } stats.setNetBytesReceived(stats.getNetBytesReceived() + stats.getCurrentBytesReceived()); @@ -837,7 +821,9 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian stats.setCurrentBytesReceived(answer.getBytesReceived()); if (stats.getCurrentBytesSent() > answer.getBytesSent()) { if (s_logger.isDebugEnabled()) { - s_logger.debug("Received # of bytes that's less than the last one. Assuming something went wrong and persisting it. Router: "+answer.getRouterName()+" Reported: " + answer.getBytesSent() + s_logger.debug("Received # of bytes that's less than the last one. " + + "Assuming something went wrong and persisting it. Router: " + + answer.getRouterName()+" Reported: " + answer.getBytesSent() + " Stored: " + stats.getCurrentBytesSent()); } stats.setNetBytesSent(stats.getNetBytesSent() + stats.getCurrentBytesSent()); @@ -847,13 +833,15 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian txn.commit(); } catch (Exception e) { txn.rollback(); - s_logger.warn("Unable to update user statistics for account: " + router.getAccountId() + " Rx: " + answer.getBytesReceived() + "; Tx: " + answer.getBytesSent()); + s_logger.warn("Unable to update user statistics for account: " + router.getAccountId() + + " Rx: " + answer.getBytesReceived() + "; Tx: " + answer.getBytesSent()); } finally { txn.close(); } } } } + } } catch (Exception e) { s_logger.warn("Error while collecting network stats", e); } @@ -909,9 +897,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } finally { scanLock.releaseRef(); } - } - } @@ -1038,12 +1024,15 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian if (!router.getIsRedundantRouter()) { continue; } - long networkId = router.getNetworkId(); - if (checkedNetwork.contains(networkId)) { + + List routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId()); + + for (Long routerGuestNtwkId : routerGuestNtwkIds) { + if (checkedNetwork.contains(routerGuestNtwkId)) { continue; } - checkedNetwork.add(networkId); - List checkingRouters = _routerDao.listByNetworkAndRole(networkId, Role.VIRTUAL_ROUTER); + checkedNetwork.add(routerGuestNtwkId); + List checkingRouters = _routerDao.listByNetworkAndRole(routerGuestNtwkId, Role.VIRTUAL_ROUTER); if (checkingRouters.size() != 2) { continue; } @@ -1072,13 +1061,17 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } } } + } private void checkDuplicateMaster(List routers) { Map networkRouterMaps = new HashMap(); for (DomainRouterVO router : routers) { + List routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId()); + + for (Long routerGuestNtwkId : routerGuestNtwkIds) { if (router.getRedundantState() == RedundantState.MASTER) { - if (networkRouterMaps.containsKey(router.getNetworkId())) { - DomainRouterVO dupRouter = networkRouterMaps.get(router.getNetworkId()); + if (networkRouterMaps.containsKey(routerGuestNtwkId)) { + DomainRouterVO dupRouter = networkRouterMaps.get(routerGuestNtwkId); String title = "More than one redundant virtual router is in MASTER state! Router " + router.getHostName() + " and router " + dupRouter.getHostName(); String context = "Virtual router (name: " + router.getHostName() + ", id: " + router.getId() + " and router (name: " + dupRouter.getHostName() + ", id: " + router.getId() + ") are both in MASTER state! If the problem persist, restart both of routers. "; @@ -1086,7 +1079,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian _alertMgr.sendAlert(AlertManager.ALERT_TYPE_DOMAIN_ROUTER, router.getDataCenterIdToDeployIn(), router.getPodIdToDeployIn(), title, context); _alertMgr.sendAlert(AlertManager.ALERT_TYPE_DOMAIN_ROUTER, dupRouter.getDataCenterIdToDeployIn(), dupRouter.getPodIdToDeployIn(), title, context); } else { - networkRouterMaps.put(router.getNetworkId(), router); + networkRouterMaps.put(routerGuestNtwkId, router); + } } } } @@ -1095,7 +1089,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian @Override public void run() { try { - final List routers = _routerDao.listVirtualByHostId(null); + final List routers = _routerDao.listIsolatedByHostId(null); s_logger.debug("Found " + routers.size() + " routers. "); updateRoutersRedundantState(routers); @@ -1110,9 +1104,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } } - public static boolean isAdmin(short accountType) { - return ((accountType == Account.ACCOUNT_TYPE_ADMIN) || (accountType == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) || (accountType == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN) || (accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN)); - } + private final int DEFAULT_PRIORITY = 100; private final int DEFAULT_DELTA = 2; @@ -1165,7 +1157,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian for (HostVO h : hosts) { if (h.getStatus() == Status.Up) { - s_logger.debug("Pick up host that has hypervisor type " + h.getHypervisorType() + " in cluster " + cv.getId() + " to start domain router for OVM"); + s_logger.debug("Pick up host that has hypervisor type " + h.getHypervisorType() + " in cluster " + + cv.getId() + " to start domain router for OVM"); return h.getHypervisorType(); } } @@ -1173,51 +1166,33 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian String errMsg = "Cannot find an available cluster in Pod " + podId - + " to start domain router for Ovm. \n Ovm won't support any system vm including domain router, please make sure you have a cluster with hypervisor type of any of xenserver/KVM/Vmware in the same pod with Ovm cluster. And there is at least one host in UP status in that cluster."; + + " to start domain router for Ovm. \n Ovm won't support any system vm including domain router, " + + "please make sure you have a cluster with hypervisor type of any of xenserver/KVM/Vmware in the same pod" + + " with Ovm cluster. And there is at least one host in UP status in that cluster."; throw new CloudRuntimeException(errMsg); } @DB - protected List findOrDeployVirtualRouters(Network guestNetwork, DeployDestination dest, Account owner, boolean isRedundant, Map params) throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { + protected List findOrDeployVirtualRouterInGuestNetwork(Network guestNetwork, DeployDestination dest, Account owner, + boolean isRedundant, Map params) throws ConcurrentOperationException, + InsufficientCapacityException, ResourceUnavailableException { - Network network = _networkDao.acquireInLockTable(guestNetwork.getId()); - if (network == null) { - throw new ConcurrentOperationException("Unable to lock network " + guestNetwork.getId()); - } + assert guestNetwork.getState() == Network.State.Implemented || guestNetwork.getState() == Network.State.Setup || + guestNetwork.getState() == Network.State.Implementing : "Network is not yet fully implemented: " + + guestNetwork; + assert guestNetwork.getTrafficType() == TrafficType.Guest; - long dcId = dest.getDataCenter().getId(); - DataCenterDeployment plan = new DataCenterDeployment(dcId); - boolean isPodBased = (dest.getDataCenter().getNetworkType() == NetworkType.Basic || _networkMgr.areServicesSupportedInNetwork(guestNetwork.getId(), Service.SecurityGroup)) && guestNetwork.getTrafficType() == TrafficType.Guest; - boolean publicNetwork = false; - if (_networkMgr.isProviderSupportServiceInNetwork(guestNetwork.getId(), Service.SourceNat, Provider.VirtualRouter)) { - publicNetwork = true; - } - if (isRedundant && !publicNetwork) { - s_logger.error("Didn't support redundant virtual router without public network!"); - return null; - } - List routers; - Long podId = null; - if (isPodBased) { - Pod pod = dest.getPod(); - if (pod != null) { - podId = pod.getId(); - } - } - if (publicNetwork) { - routers = _routerDao.listByNetworkAndRole(guestNetwork.getId(), Role.VIRTUAL_ROUTER); - } else { - if (isPodBased && podId != null) { - routers = _routerDao.listByNetworkAndPodAndRole(guestNetwork.getId(), podId, Role.VIRTUAL_ROUTER); - plan = new DataCenterDeployment(dcId, podId, null, null, null, null); - } else { - routers = _routerDao.listByNetworkAndRole(guestNetwork.getId(), Role.VIRTUAL_ROUTER); - plan = new DataCenterDeployment(dcId); - } - } - try { + //1) Get deployment plan and find out the list of routers + boolean isPodBased = (dest.getDataCenter().getNetworkType() == NetworkType.Basic || + _networkMgr.areServicesSupportedInNetwork(guestNetwork.getId(), Service.SecurityGroup)) + && guestNetwork.getTrafficType() == TrafficType.Guest; + Pair> planAndRouters = getDeploymentPlanAndRouters(isPodBased, dest, guestNetwork.getId()); + DeploymentPlan plan = planAndRouters.first(); + List routers = planAndRouters.second(); + + //2) Figure out required routers count int routerCount = 1; if (isRedundant) { routerCount = 2; @@ -1231,7 +1206,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } /* If old network is redundant but new is single router, then routers.size() = 2 but routerCount = 1 */ - if (routers.size() >= routerCount || (isPodBased && podId == null)) { + if (routers.size() >= routerCount || (isPodBased)) { return routers; } @@ -1239,89 +1214,97 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian s_logger.error("Too much redundant routers!"); } - NicProfile defaultNic = new NicProfile(); - //if source nat service is supported by the network, get the source nat ip address - if (publicNetwork) { - PublicIp sourceNatIp = _networkMgr.assignSourceNatIpAddress(owner, guestNetwork, _accountMgr.getSystemUser().getId()); - defaultNic.setDefaultNic(true); - defaultNic.setIp4Address(sourceNatIp.getAddress().addr()); - defaultNic.setGateway(sourceNatIp.getGateway()); - defaultNic.setNetmask(sourceNatIp.getNetmask()); - defaultNic.setMacAddress(sourceNatIp.getMacAddress()); - defaultNic.setBroadcastType(BroadcastDomainType.Vlan); - defaultNic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(sourceNatIp.getVlanTag())); - defaultNic.setIsolationUri(IsolationType.Vlan.toUri(sourceNatIp.getVlanTag())); - defaultNic.setDeviceId(2); + Network network = _networkDao.acquireInLockTable(guestNetwork.getId()); + if (network == null) { + throw new ConcurrentOperationException("Unable to lock network " + guestNetwork.getId()); } + try { + //Check if providers are supported in the physical networks + VirtualRouterProviderType type = VirtualRouterProviderType.VirtualRouter; + Long physicalNetworkId = _networkMgr.getPhysicalNetworkId(network); + PhysicalNetworkServiceProvider provider = _physicalProviderDao.findByServiceProvider(physicalNetworkId, type.toString()); + if (provider == null) { + throw new CloudRuntimeException("Cannot find service provider " + type.toString() + " in physical network " + physicalNetworkId); + } + VirtualRouterProvider vrProvider = _vrProviderDao.findByNspIdAndType(provider.getId(), type); + if (vrProvider == null) { + throw new CloudRuntimeException("Cannot find virtual router provider " + type.toString()+ " as service provider " + provider.getId()); + } + + if (_networkMgr.isNetworkSystem(guestNetwork) || guestNetwork.getGuestType() == Network.GuestType.Shared) { + owner = _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM); + } + + //Check if public network has to be set on VR + boolean publicNetwork = false; + if (_networkMgr.isProviderSupportServiceInNetwork(guestNetwork.getId(), Service.SourceNat, Provider.VirtualRouter)) { + publicNetwork = true; + } + if (isRedundant && !publicNetwork) { + s_logger.error("Didn't support redundant virtual router without public network!"); + return null; + } + + + + Long offeringId = _networkOfferingDao.findById(guestNetwork.getNetworkOfferingId()).getServiceOfferingId(); + if (offeringId == null) { + offeringId = _offering.getId(); + } + + PublicIp sourceNatIp = null; + if (publicNetwork) { + sourceNatIp = _networkMgr.assignSourceNatIpAddressToGuestNetwork(owner, guestNetwork); + } + + //Check if control network has to be set on VR + boolean controlNetwork = true; + if ( dest.getDataCenter().getNetworkType() == NetworkType.Basic ) { + // in basic mode, use private network as control network + controlNetwork = false; + } + + //3) deploy virtual router(s) int count = routerCount - routers.size(); - for (int i = 0; i < count; i++) { - long id = _routerDao.getNextInSequence(Long.class, "id"); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Creating the router " + id); + DomainRouterVO router = deployRouter(owner, dest, plan, params, isRedundant, vrProvider, offeringId, + null, sourceNatIp, publicNetwork, controlNetwork, guestNetwork, new Pair(publicNetwork, sourceNatIp)); + //add router to router network map + if (!_routerDao.isRouterPartOfGuestNetwork(router.getId(), network.getId())) { + DomainRouterVO routerVO = _routerDao.findById(router.getId()); + _routerDao.addRouterToGuestNetwork(routerVO, network); + } + routers.add(router); + } + } finally { + if (network != null) { + _networkDao.releaseFromLockTable(network.getId()); + } + } + return routers; } - DomainRouterVO router = null; + protected DomainRouterVO deployRouter(Account owner, DeployDestination dest, DeploymentPlan plan, Map params, + boolean isRedundant, VirtualRouterProvider vrProvider, long svcOffId, + Long vpcId, PublicIp sourceNatIp, boolean setupPublicNetwork, boolean setupControlNetwork, Network guestNetwork, + Pair publicNetwork) throws ConcurrentOperationException, + InsufficientAddressCapacityException, InsufficientServerCapacityException, InsufficientCapacityException, + StorageUnavailableException, ResourceUnavailableException { + + long id = _routerDao.getNextInSequence(Long.class, "id"); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Creating the router " + id + " in datacenter " + dest.getDataCenter()); + } + + //1) Create router networks + List> networks = createRouterNetworks(owner, isRedundant, plan, setupControlNetwork, + guestNetwork, publicNetwork); - List offerings = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemControlNetwork); - NetworkOfferingVO controlOffering = offerings.get(0); - NetworkVO controlConfig = _networkMgr.setupNetwork(_systemAcct, controlOffering, plan, null, null, false).get(0); + + ServiceOfferingVO routerOffering = _serviceOfferingDao.findById(svcOffId); - List> networks = new ArrayList>(3); - if (publicNetwork) { - NetworkOfferingVO publicOffering = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemPublicNetwork).get(0); - List publicNetworks = _networkMgr.setupNetwork(_systemAcct, publicOffering, plan, null, null, false); - networks.add(new Pair(publicNetworks.get(0), defaultNic)); - } - - String defaultNetworkStartIp = null; - if (guestNetwork.getCidr() != null && !publicNetwork) { - String startIp = _networkMgr.getStartIpAddress(guestNetwork.getId()); - if (startIp != null && _ipAddressDao.findByIpAndSourceNetworkId(guestNetwork.getId(), startIp).getAllocatedTime() == null) { - defaultNetworkStartIp = startIp; - } else if (s_logger.isDebugEnabled()){ - s_logger.debug("First ip " + startIp + " in network id=" + guestNetwork.getId() + " is already allocated, can't use it for domain router; will get random ip address from the range"); - } - } - - NicProfile gatewayNic = new NicProfile(defaultNetworkStartIp); - if (publicNetwork) { - if (isRedundant) { - gatewayNic.setIp4Address(_networkMgr.acquireGuestIpAddress(guestNetwork, null)); - } else { - gatewayNic.setIp4Address(guestNetwork.getGateway()); - } - gatewayNic.setBroadcastUri(guestNetwork.getBroadcastUri()); - gatewayNic.setBroadcastType(guestNetwork.getBroadcastDomainType()); - gatewayNic.setIsolationUri(guestNetwork.getBroadcastUri()); - gatewayNic.setMode(guestNetwork.getMode()); - String gatewayCidr = guestNetwork.getCidr(); - gatewayNic.setNetmask(NetUtils.getCidrNetmask(gatewayCidr)); - } else { - gatewayNic.setDefaultNic(true); - } - - networks.add(new Pair((NetworkVO) guestNetwork, gatewayNic)); - networks.add(new Pair(controlConfig, null)); - - Long offering_id = _networkOfferingDao.findById(guestNetwork.getNetworkOfferingId()).getServiceOfferingId(); - if (offering_id == null) { - offering_id = _offering.getId(); - } - VirtualRouterProviderType type = VirtualRouterProviderType.VirtualRouter; - Long physicalNetworkId = _networkMgr.getPhysicalNetworkId(network); - PhysicalNetworkServiceProvider provider = _physicalProviderDao.findByServiceProvider(physicalNetworkId, type.toString()); - if (provider == null) { - throw new CloudRuntimeException("Cannot find service provider " + type.toString() + " in physical network " + physicalNetworkId); - } - VirtualRouterProvider vrProvider = _vrProviderDao.findByNspIdAndType(provider.getId(), type); - if (vrProvider == null) { - throw new CloudRuntimeException("Cannot find virtual router provider " + type.toString()+ " as service provider " + provider.getId()); - } - ServiceOfferingVO routerOffering = _serviceOfferingDao.findById(offering_id); - - //Router is the network element, we don't know the hypervisor type yet. + //2) Router is the network element, we don't know the hypervisor type yet. //Try to allocate the domR twice using diff hypervisors, and when failed both times, throw the exception up List supportedHypervisors = new ArrayList(); HypervisorType defaults = _resourceMgr.getDefaultHypervisor(dest.getDataCenter().getId()); @@ -1336,20 +1319,22 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian supportedHypervisors.add(dest.getCluster().getHypervisorType()); } } else { - supportedHypervisors = _resourceMgr.getSupportedHypervisorTypes(dest.getDataCenter().getId(), true, podId); + supportedHypervisors = _resourceMgr.getSupportedHypervisorTypes(dest.getDataCenter().getId(), true, + plan.getPodId()); } if (supportedHypervisors.isEmpty()) { - if (podId != null) { - throw new InsufficientServerCapacityException("Unable to create virtual router, there are no clusters in the pod ", Pod.class, podId); + if (plan.getPodId() != null) { + throw new InsufficientServerCapacityException("Unable to create virtual router, " + + "there are no clusters in the pod ", Pod.class, plan.getPodId()); } - throw new InsufficientServerCapacityException("Unable to create virtual router, there are no clusters in the zone ", DataCenter.class, dest.getDataCenter().getId()); + throw new InsufficientServerCapacityException("Unable to create virtual router, " + + "there are no clusters in the zone ", DataCenter.class, dest.getDataCenter().getId()); } int allocateRetry = 0; int startRetry = 0; - - + DomainRouterVO router = null; for (Iterator iter = supportedHypervisors.iterator();iter.hasNext();) { HypervisorType hType = iter.next(); try { @@ -1367,8 +1352,10 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian offerHA = false; } - router = new DomainRouterVO(id, routerOffering.getId(), vrProvider.getId(), VirtualMachineName.getRouterName(id, _instance), template.getId(), template.getHypervisorType(), - template.getGuestOSId(), owner.getDomainId(), owner.getId(), guestNetwork.getId(), isRedundant, 0, false, RedundantState.UNKNOWN, offerHA, false); + router = new DomainRouterVO(id, routerOffering.getId(), vrProvider.getId(), + VirtualMachineName.getRouterName(id, _instance), template.getId(), template.getHypervisorType(), + template.getGuestOSId(), owner.getDomainId(), owner.getId(), isRedundant, 0, false, + RedundantState.UNKNOWN, offerHA, false, vpcId); router.setRole(Role.VIRTUAL_ROUTER); router = _itMgr.allocate(router, template, routerOffering, networks, plan, null, owner); } catch (InsufficientCapacityException ex) { @@ -1387,7 +1374,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian break; } catch (InsufficientCapacityException ex) { if (startRetry < 2 && iter.hasNext()) { - s_logger.debug("Failed to start the domR " + router + " with hypervisor type " + hType + ", destroying it and recreating one more time"); + s_logger.debug("Failed to start the domR " + router + " with hypervisor type " + hType + ", " + + "destroying it and recreating one more time"); //destroy the router destroyRouter(router.getId()); continue; @@ -1399,18 +1387,118 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } } - routers.add(router); - - } - } finally { - if (network != null) { - _networkDao.releaseFromLockTable(network.getId()); - } - } - return routers; + return router; } - private DomainRouterVO startVirtualRouter(DomainRouterVO router, User user, Account caller, Map params) throws StorageUnavailableException, InsufficientCapacityException, + protected List> createRouterNetworks(Account owner, boolean isRedundant, + DeploymentPlan plan, boolean setupControlNetwork, Network guestNetwork, Pair publicNetwork) throws ConcurrentOperationException, + InsufficientAddressCapacityException { + + + boolean setupPublicNetwork = false; + if (publicNetwork != null) { + setupPublicNetwork = publicNetwork.first(); + } + + //Form networks + List> networks = new ArrayList>(3); + + //1) Guest network + boolean hasGuestNetwork = false; + if (guestNetwork != null) { + s_logger.debug("Adding nic for Virtual Router in Guest network " + guestNetwork); + String defaultNetworkStartIp = null; + if (guestNetwork.getCidr() != null && !setupPublicNetwork) { + String startIp = _networkMgr.getStartIpAddress(guestNetwork.getId()); + if (startIp != null && _ipAddressDao.findByIpAndSourceNetworkId(guestNetwork.getId(), startIp).getAllocatedTime() == null) { + defaultNetworkStartIp = startIp; + } else if (s_logger.isDebugEnabled()){ + s_logger.debug("First ip " + startIp + " in network id=" + guestNetwork.getId() + + " is already allocated, can't use it for domain router; will get random ip address from the range"); + } + } + + NicProfile gatewayNic = new NicProfile(defaultNetworkStartIp); + if (setupPublicNetwork) { + if (isRedundant) { + gatewayNic.setIp4Address(_networkMgr.acquireGuestIpAddress(guestNetwork, null)); + } else { + gatewayNic.setIp4Address(guestNetwork.getGateway()); + } + gatewayNic.setBroadcastUri(guestNetwork.getBroadcastUri()); + gatewayNic.setBroadcastType(guestNetwork.getBroadcastDomainType()); + gatewayNic.setIsolationUri(guestNetwork.getBroadcastUri()); + gatewayNic.setMode(guestNetwork.getMode()); + String gatewayCidr = guestNetwork.getCidr(); + gatewayNic.setNetmask(NetUtils.getCidrNetmask(gatewayCidr)); + } else { + gatewayNic.setDefaultNic(true); + } + networks.add(new Pair((NetworkVO) guestNetwork, gatewayNic)); + hasGuestNetwork = true; + } + + //2) Control network + if (setupControlNetwork) { + s_logger.debug("Adding nic for Virtual Router in Control network "); + List offerings = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemControlNetwork); + NetworkOfferingVO controlOffering = offerings.get(0); + NetworkVO controlConfig = _networkMgr.setupNetwork(_systemAcct, controlOffering, plan, null, null, false).get(0); + networks.add(new Pair(controlConfig, null)); + } + + //3) Public network + if (setupPublicNetwork) { + PublicIp sourceNatIp = publicNetwork.second(); + s_logger.debug("Adding nic for Virtual Router in Public network "); + //if source nat service is supported by the network, get the source nat ip address + NicProfile defaultNic = new NicProfile(); + defaultNic.setDefaultNic(true); + defaultNic.setIp4Address(sourceNatIp.getAddress().addr()); + defaultNic.setGateway(sourceNatIp.getGateway()); + defaultNic.setNetmask(sourceNatIp.getNetmask()); + defaultNic.setMacAddress(sourceNatIp.getMacAddress()); + defaultNic.setBroadcastType(BroadcastDomainType.Vlan); + defaultNic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(sourceNatIp.getVlanTag())); + defaultNic.setIsolationUri(IsolationType.Vlan.toUri(sourceNatIp.getVlanTag())); + if (hasGuestNetwork) { + defaultNic.setDeviceId(2); + } + NetworkOfferingVO publicOffering = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemPublicNetwork).get(0); + List publicNetworks = _networkMgr.setupNetwork(_systemAcct, publicOffering, plan, null, null, false); + networks.add(new Pair(publicNetworks.get(0), defaultNic)); + } + + + return networks; + } + + + protected Pair> getDeploymentPlanAndRouters(boolean isPodBased, + DeployDestination dest, long guestNetworkId) { + long dcId = dest.getDataCenter().getId(); + List routers = null; + DeploymentPlan plan = new DataCenterDeployment(dcId); + if (isPodBased) { + Pod pod = dest.getPod(); + Long podId = null; + if (pod != null) { + podId = pod.getId(); + } else { + throw new CloudRuntimeException("Pod id is expected in deployment destination"); + } + routers = _routerDao.listByNetworkAndPodAndRole(guestNetworkId, podId, Role.VIRTUAL_ROUTER); + plan = new DataCenterDeployment(dcId, podId, null, null, null, null); + } else { + routers = _routerDao.listByNetworkAndRole(guestNetworkId, Role.VIRTUAL_ROUTER); + } + + return new Pair>(plan, routers); + } + + + private DomainRouterVO startVirtualRouter(DomainRouterVO router, User user, Account caller, Map params) + throws StorageUnavailableException, InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { if (router.getRole() != Role.VIRTUAL_ROUTER || !router.getIsRedundantRouter()) { @@ -1477,23 +1565,18 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } @Override - public List deployVirtualRouter(Network guestNetwork, DeployDestination dest, Account owner, Map params, boolean isRedundant) throws InsufficientCapacityException, + public List deployVirtualRouterInGuestNetwork(Network guestNetwork, DeployDestination dest, Account owner, + Map params, boolean isRedundant) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { - if (_networkMgr.isNetworkSystem(guestNetwork) || guestNetwork.getGuestType() == Network.GuestType.Shared) { - owner = _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM); - } - if(dest != null){ - if (s_logger.isDebugEnabled()) { - s_logger.debug("Starting a router for " + guestNetwork + " in datacenter:" + dest.getDataCenter()); - } - } + List routers = findOrDeployVirtualRouterInGuestNetwork + (guestNetwork, dest, owner, isRedundant, params); - assert guestNetwork.getState() == Network.State.Implemented || guestNetwork.getState() == Network.State.Setup || guestNetwork.getState() == Network.State.Implementing : "Network is not yet fully implemented: " - + guestNetwork; - assert guestNetwork.getTrafficType() == TrafficType.Guest; + return startRouters(params, routers); + } - List routers = findOrDeployVirtualRouters(guestNetwork, dest, owner, isRedundant, params); + protected List startRouters(Map params, List routers) throws StorageUnavailableException, InsufficientCapacityException, ConcurrentOperationException, + ResourceUnavailableException { List runningRouters = null; if (routers != null) { @@ -1522,97 +1605,53 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } @Override - public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) { + public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, + ReservationContext context) { + + boolean dnsProvided = true; + boolean dhcpProvided = true; + boolean publicNetwork = false; + DataCenterVO dc = _dcDao.findById(dest.getDataCenter().getId()); + _dcDao.loadDetails(dc); + //1) Set router details DomainRouterVO router = profile.getVirtualMachine(); Map details = _vmDetailsDao.findDetails(router.getId()); router.setDetails(details); - NetworkVO network = _networkDao.findById(router.getNetworkId()); - String type = null; - String dhcpRange = null; - String rpFilter = " "; - DataCenter dc = dest.getDataCenter(); - DataCenterVO dcVO = _dcDao.findById(dc.getId()); - _dcDao.loadDetails(dcVO); - - if (dc.getNetworkType() == NetworkType.Advanced) { - String cidr = network.getCidr(); - if (cidr != null) { - dhcpRange = NetUtils.getDhcpRange(cidr); - } - } - - String rpValue = _configDao.getValue(Config.NetworkRouterRpFilter.key()); - if (rpValue != null && rpValue.equalsIgnoreCase("true")) { - _disable_rp_filter = true; - }else - { - _disable_rp_filter = false; - } - - boolean publicNetwork = false; - if (_networkMgr.isProviderSupportServiceInNetwork(network.getId(), Service.SourceNat, Provider.VirtualRouter)) { - publicNetwork = true; - } - if (!publicNetwork) { - type = "dhcpsrvr"; - } else { - type = "router"; - if (_disable_rp_filter) { - rpFilter=" disable_rp_filter=true"; - } - } + //2) Prepare boot loader elements related with Control network StringBuilder buf = profile.getBootArgsBuilder(); - buf.append(" template=domP type=" + type+rpFilter); + buf.append(" template=domP"); buf.append(" name=").append(profile.getHostName()); if (Boolean.valueOf(_configDao.getValue("system.vm.random.password"))) { buf.append(" vmpassword=").append(_configDao.getValue("system.vm.password")); } - boolean isRedundant = router.getIsRedundantRouter(); - if (isRedundant) { - buf.append(" redundant_router=1"); - List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); - try { - int priority = getUpdatedPriority(network, routers, router); - router.setPriority(priority); - } catch (InsufficientVirtualNetworkCapcityException e) { - s_logger.error("Failed to get update priority!", e); - throw new CloudRuntimeException("Failed to get update priority!"); - } - } NicProfile controlNic = null; String defaultDns1 = null; String defaultDns2 = null; - for (NicProfile nic : profile.getNics()) { int deviceId = nic.getDeviceId(); buf.append(" eth").append(deviceId).append("ip=").append(nic.getIp4Address()); buf.append(" eth").append(deviceId).append("mask=").append(nic.getNetmask()); + if (nic.isDefaultNic()) { buf.append(" gateway=").append(nic.getGateway()); defaultDns1 = nic.getDns1(); defaultDns2 = nic.getDns2(); - - if (dc.getNetworkType() == NetworkType.Basic) { - long cidrSize = NetUtils.getCidrSize(nic.getNetmask()); - String cidr = NetUtils.getCidrSubNet(nic.getGateway(), cidrSize); - if (cidr != null) { - dhcpRange = NetUtils.getIpRangeStartIpFromCidr(cidr, cidrSize); - } - } } + if (nic.getTrafficType() == TrafficType.Management) { buf.append(" localgw=").append(dest.getPod().getGateway()); } else if (nic.getTrafficType() == TrafficType.Control) { - + controlNic = nic; // DOMR control command is sent over management server in VMware if (dest.getHost().getHypervisorType() == HypervisorType.VMware) { if (s_logger.isInfoEnabled()) { - s_logger.info("Check if we need to add management server explicit route to DomR. pod cidr: " + dest.getPod().getCidrAddress() + "/" + dest.getPod().getCidrSize() + s_logger.info("Check if we need to add management server explicit route to DomR. pod cidr: " + + dest.getPod().getCidrAddress() + "/" + dest.getPod().getCidrSize() + ", pod gateway: " + dest.getPod().getGateway() + ", management host: " + _mgmt_host); } @@ -1633,47 +1672,62 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian // ask domR to setup SSH on guest network buf.append(" sshonguest=true"); } + + } + } else if (nic.getTrafficType() == TrafficType.Guest) { + dnsProvided = _networkMgr.isProviderSupportServiceInNetwork(nic.getNetworkId(), Service.Dns, Provider.VirtualRouter); + dhcpProvided = _networkMgr.isProviderSupportServiceInNetwork(nic.getNetworkId(), Service.Dhcp, Provider.VirtualRouter); + //build bootloader parameter for the guest + buf.append(createGuestBootLoadArgs(nic, defaultDns1, defaultDns2, router)); + } else if (nic.getTrafficType() == TrafficType.Public) { + publicNetwork = true; + } } - controlNic = nic; - } else if (nic.getTrafficType() == TrafficType.Guest && isRedundant) { - Network net = _networkMgr.getNetwork(nic.getNetworkId()); - buf.append(" guestgw=").append(net.getGateway()); - String brd = NetUtils.long2Ip(NetUtils.ip2Long(nic.getIp4Address()) | ~NetUtils.ip2Long(nic.getNetmask())); - buf.append(" guestbrd=").append(brd); - buf.append(" guestcidrsize=").append(NetUtils.getCidrSize(nic.getNetmask())); - buf.append(" router_pr=").append(router.getPriority()); + if (controlNic == null) { + throw new CloudRuntimeException("Didn't start a control port"); } + + String rpValue = _configDao.getValue(Config.NetworkRouterRpFilter.key()); + if (rpValue != null && rpValue.equalsIgnoreCase("true")) { + _disable_rp_filter = true; + }else { + _disable_rp_filter = false; } - if (dhcpRange != null) { - buf.append(" dhcprange=" + dhcpRange); + String rpFilter = " "; + String type = null; + if (router.getVpcId() != null) { + type = "vpcrouter"; + if (_disable_rp_filter) { + rpFilter=" disable_rp_filter=true"; } - String domain = network.getNetworkDomain(); - if (domain != null) { - buf.append(" domain=" + domain); + } else if (!publicNetwork) { + type = "dhcpsrvr"; + } else { + type = "router"; + if (_disable_rp_filter) { + rpFilter=" disable_rp_filter=true"; } - String domain_suffix = dcVO.getDetail(ZoneConfig.DnsSearchOrder.getName()); + } + + if (_disable_rp_filter) { + rpFilter=" disable_rp_filter=true"; + } + + buf.append(" type=" + type + rpFilter); + + String domain_suffix = dc.getDetail(ZoneConfig.DnsSearchOrder.getName()); if (domain_suffix != null) { buf.append(" dnssearchorder=").append(domain_suffix); } -// if (!network.isDefault() && network.getGuestType() == Network.GuestType.Shared) { -// buf.append(" defaultroute=false"); -// -// String virtualNetworkElementNicIP = _networkMgr.getIpOfNetworkElementInVirtualNetwork(network.getAccountId(), network.getDataCenterId()); -// if (network.getGuestType() != Network.GuestType.Shared && virtualNetworkElementNicIP != null) { -// defaultDns1 = virtualNetworkElementNicIP; -// } else { -// s_logger.debug("No Virtual network found for account id=" + network.getAccountId() + " so setting dns to the dns of the network id=" + network.getId()); -// } -// } else { -// buf.append(" defaultroute=true"); -// } - - boolean dnsProvided = _networkMgr.isProviderSupportServiceInNetwork(network.getId(), Service.Dns, Provider.VirtualRouter); - boolean dhcpProvided = _networkMgr.isProviderSupportServiceInNetwork(network.getId(), Service.Dhcp, Provider.VirtualRouter); - /* If virtual router didn't provide DNS service but provide DHCP service, we need to override the DHCP response to return DNS server rather than + if (profile.getHypervisorType() == HypervisorType.VMware) { + buf.append(" extra_pubnics=" + _routerExtraPublicNics); + } + + /* If virtual router didn't provide DNS service but provide DHCP service, we need to override the DHCP response + * to return DNS server rather than * virtual router itself. */ if (dnsProvided || dhcpProvided) { buf.append(" dns1=").append(defaultDns1); @@ -1693,23 +1747,93 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } } - if(profile.getHypervisorType() == HypervisorType.VMware) { - buf.append(" extra_pubnics=" + _routerExtraPublicNics); - } - if (s_logger.isDebugEnabled()) { s_logger.debug("Boot Args for " + profile + ": " + buf.toString()); } - if (controlNic == null) { - throw new CloudRuntimeException("Didn't start a control port"); + return true; } - return true; + + protected StringBuilder createGuestBootLoadArgs(NicProfile guestNic, String defaultDns1, + String defaultDns2, DomainRouterVO router) { + long guestNetworkId = guestNic.getNetworkId(); + NetworkVO guestNetwork = _networkDao.findById(guestNetworkId); + String dhcpRange = null; + DataCenterVO dc = _dcDao.findById(guestNetwork.getDataCenterId()); + + StringBuilder buf = new StringBuilder(); + + boolean isRedundant = router.getIsRedundantRouter(); + if (isRedundant) { + buf.append(" redundant_router=1"); + List routers = _routerDao.listByNetworkAndRole(guestNetwork.getId(), Role.VIRTUAL_ROUTER); + try { + int priority = getUpdatedPriority(guestNetwork, routers, router); + router.setPriority(priority); + } catch (InsufficientVirtualNetworkCapcityException e) { + s_logger.error("Failed to get update priority!", e); + throw new CloudRuntimeException("Failed to get update priority!"); + } + Network net = _networkMgr.getNetwork(guestNic.getNetworkId()); + buf.append(" guestgw=").append(net.getGateway()); + String brd = NetUtils.long2Ip(NetUtils.ip2Long(guestNic.getIp4Address()) | ~NetUtils.ip2Long(guestNic.getNetmask())); + buf.append(" guestbrd=").append(brd); + buf.append(" guestcidrsize=").append(NetUtils.getCidrSize(guestNic.getNetmask())); + buf.append(" router_pr=").append(router.getPriority()); + } + + //setup network domain + String domain = guestNetwork.getNetworkDomain(); + if (domain != null) { + buf.append(" domain=" + domain); + } + + //setup dhcp range + if (dc.getNetworkType() == NetworkType.Basic) { + if (guestNic.isDefaultNic()) { + long cidrSize = NetUtils.getCidrSize(guestNic.getNetmask()); + String cidr = NetUtils.getCidrSubNet(guestNic.getGateway(), cidrSize); + if (cidr != null) { + dhcpRange = NetUtils.getIpRangeStartIpFromCidr(cidr, cidrSize); + } + } + } else if (dc.getNetworkType() == NetworkType.Advanced) { + String cidr = guestNetwork.getCidr(); + if (cidr != null) { + dhcpRange = NetUtils.getDhcpRange(cidr); + } + } + + if (dhcpRange != null) { + buf.append(" dhcprange=" + dhcpRange); + } + + return buf; + } + + + protected String getGuestDhcpRange(NicProfile guestNic, Network guestNetwork, DataCenter dc) { + String dhcpRange = null; + //setup dhcp range + if (dc.getNetworkType() == NetworkType.Basic) { + long cidrSize = NetUtils.getCidrSize(guestNic.getNetmask()); + String cidr = NetUtils.getCidrSubNet(guestNic.getGateway(), cidrSize); + if (cidr != null) { + dhcpRange = NetUtils.getIpRangeStartIpFromCidr(cidr, cidrSize); + } + } else if (dc.getNetworkType() == NetworkType.Advanced) { + String cidr = guestNetwork.getCidr(); + if (cidr != null) { + dhcpRange = NetUtils.getDhcpRange(cidr); + } + } + return dhcpRange; } @Override - public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) throws ResourceUnavailableException { + public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile profile, + DeployDestination dest, ReservationContext context) throws ResourceUnavailableException { DomainRouterVO router = profile.getVirtualMachine(); List nics = profile.getNics(); @@ -1718,8 +1842,6 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian router.setPublicIpAddress(nic.getIp4Address()); router.setPublicNetmask(nic.getNetmask()); router.setPublicMacAddress(nic.getMacAddress()); - } else if (nic.getTrafficType() == TrafficType.Guest) { - router.setGuestIpAddress(nic.getIp4Address()); } else if (nic.getTrafficType() == TrafficType.Control) { router.setPrivateIpAddress(nic.getIp4Address()); router.setPrivateMacAddress(nic.getMacAddress()); @@ -1771,9 +1893,9 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian cmds.addCommand("networkUsage", new NetworkUsageCommand(controlNic.getIp4Address(), router.getHostName(), "create")); // restart network if restartNetwork = false is not specified in profile parameters - boolean reprogramNetwork = true; - if (profile.getParameter(Param.ReProgramNetwork) != null && (Boolean) profile.getParameter(Param.ReProgramNetwork) == false) { - reprogramNetwork = false; + boolean reprogramGuestNtwks = true; + if (profile.getParameter(Param.ReProgramGuestNetworks) != null && (Boolean) profile.getParameter(Param.ReProgramGuestNetworks) == false) { + reprogramGuestNtwks = false; } VirtualRouterProvider vrProvider = _vrProviderDao.findById(router.getElementId()); @@ -1785,23 +1907,24 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian throw new CloudRuntimeException("Cannot find related provider of virtual router provider: " + vrProvider.getType().toString()); } - if (reprogramNetwork) { + List routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId()); + for (Long guestNetworkId : routerGuestNtwkIds) { + if (reprogramGuestNtwks) { s_logger.debug("Resending ipAssoc, port forwarding, load balancing rules as a part of Virtual router start"); - long networkId = router.getNetworkId(); long ownerId = router.getAccountId(); - long zoneId = router.getDataCenterIdToDeployIn(); - final List userIps = _networkMgr.listPublicIpAddressesInVirtualNetwork(ownerId, zoneId, null, networkId); + final List userIps = _networkMgr.listPublicIpsAssignedToGuestNtwk(ownerId, guestNetworkId, null); List allPublicIps = new ArrayList(); if (userIps != null && !userIps.isEmpty()) { for (IPAddressVO userIp : userIps) { - PublicIp publicIp = new PublicIp(userIp, _vlanDao.findById(userIp.getVlanId()), NetUtils.createSequenceBasedMacAddress(userIp.getMacAddress())); + PublicIp publicIp = new PublicIp(userIp, _vlanDao.findById(userIp.getVlanId()), + NetUtils.createSequenceBasedMacAddress(userIp.getMacAddress())); allPublicIps.add(publicIp); } } //Get public Ips that should be handled by router - Network network = _networkDao.findById(networkId); + Network network = _networkDao.findById(guestNetworkId); Map> ipToServices = _networkMgr.getIpToServices(allPublicIps, false, false); Map> providerToIpList = _networkMgr.getProviderToIpList(network, ipToServices); // Only cover virtual router for now, if ELB use it this need to be modified @@ -1818,33 +1941,33 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian List firewallRules = new ArrayList(); // Re-apply public ip addresses - should come before PF/LB/VPN - if (_networkMgr.isProviderSupportServiceInNetwork(router.getNetworkId(), Service.Firewall, provider)) { + if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.Firewall, provider)) { createAssociateIPCommands(router, publicIps, cmds, 0); } //Get information about all the rules (StaticNats and StaticNatRules; PFVPN to reapply on domR start) for (PublicIp ip : publicIps) { - if (_networkMgr.isProviderSupportServiceInNetwork(router.getNetworkId(), Service.PortForwarding, provider)) { + if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.PortForwarding, provider)) { pfRules.addAll(_pfRulesDao.listForApplication(ip.getId())); } - if (_networkMgr.isProviderSupportServiceInNetwork(router.getNetworkId(), Service.StaticNat, provider)) { + if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.StaticNat, provider)) { staticNatFirewallRules.addAll(_rulesDao.listByIpAndPurpose(ip.getId(), Purpose.StaticNat)); } - if (_networkMgr.isProviderSupportServiceInNetwork(router.getNetworkId(), Service.Firewall, provider)) { + if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.Firewall, provider)) { firewallRules.addAll(_rulesDao.listByIpAndPurpose(ip.getId(), Purpose.Firewall)); } - if (_networkMgr.isProviderSupportServiceInNetwork(router.getNetworkId(), Service.Vpn, provider)) { + if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.Vpn, provider)) { RemoteAccessVpn vpn = _vpnDao.findById(ip.getId()); if (vpn != null) { vpns.add(vpn); } } - if (_networkMgr.isProviderSupportServiceInNetwork(router.getNetworkId(), Service.StaticNat, provider)) { + if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.StaticNat, provider)) { if (ip.isOneToOneNat()) { - String dstIp = _networkMgr.getIpInNetwork(ip.getAssociatedWithVmId(), networkId); - StaticNatImpl staticNat = new StaticNatImpl(ip.getAccountId(), ip.getDomainId(), networkId, ip.getId(), dstIp, false); + String dstIp = _networkMgr.getIpInNetwork(ip.getAssociatedWithVmId(), guestNetworkId); + StaticNatImpl staticNat = new StaticNatImpl(ip.getAccountId(), ip.getDomainId(), guestNetworkId, ip.getId(), dstIp, false); staticNats.add(staticNat); } } @@ -1853,19 +1976,19 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian //Re-apply static nats s_logger.debug("Found " + staticNats.size() + " static nat(s) to apply as a part of domR " + router + " start."); if (!staticNats.isEmpty()) { - createApplyStaticNatCommands(staticNats, router, cmds); + createApplyStaticNatCommands(staticNats, router, cmds, guestNetworkId); } //Re-apply firewall rules s_logger.debug("Found " + staticNats.size() + " firewall rule(s) to apply as a part of domR " + router + " start."); if (!firewallRules.isEmpty()) { - createFirewallRulesCommands(firewallRules, router, cmds); + createFirewallRulesCommands(firewallRules, router, cmds, guestNetworkId); } // Re-apply port forwarding rules s_logger.debug("Found " + pfRules.size() + " port forwarding rule(s) to apply as a part of domR " + router + " start."); if (!pfRules.isEmpty()) { - createApplyPortForwardingRulesCommands(pfRules, router, cmds); + createApplyPortForwardingRulesCommands(pfRules, router, cmds, guestNetworkId); } // Re-apply static nat rules @@ -1875,7 +1998,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian for (FirewallRule rule : staticNatFirewallRules) { staticNatRules.add(_rulesMgr.buildStaticNatRule(rule, false)); } - createApplyStaticNatRulesCommands(staticNatRules, router, cmds); + createApplyStaticNatRulesCommands(staticNatRules, router, cmds, guestNetworkId); } // Re-apply vpn rules @@ -1886,9 +2009,9 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } } - List lbs = _loadBalancerDao.listByNetworkId(networkId); + List lbs = _loadBalancerDao.listByNetworkId(guestNetworkId); List lbRules = new ArrayList(); - if (_networkMgr.isProviderSupportServiceInNetwork(router.getNetworkId(), Service.Lb, provider)) { + if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.Lb, provider)) { // Re-apply load balancing rules for (LoadBalancerVO lb : lbs) { List dstList = _lbMgr.getExistingDestinations(lb.getId()); @@ -1900,29 +2023,33 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian s_logger.debug("Found " + lbRules.size() + " load balancing rule(s) to apply as a part of domR " + router + " start."); if (!lbRules.isEmpty()) { - createApplyLoadBalancingRulesCommands(lbRules, router, cmds); + createApplyLoadBalancingRulesCommands(lbRules, router, cmds, guestNetworkId); } } + } - if (_networkMgr.isProviderSupportServiceInNetwork(router.getNetworkId(), Service.Dhcp, provider)) { + if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.Dhcp, provider)) { // Resend dhcp s_logger.debug("Reapplying dhcp entries as a part of domR " + router + " start..."); - createDhcpEntryCommandsForVMs(router, cmds); + createDhcpEntryCommandsForVMs(router, cmds, guestNetworkId); } - if (_networkMgr.isProviderSupportServiceInNetwork(router.getNetworkId(), Service.UserData, provider)) { + if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.UserData, provider)) { // Resend user data s_logger.debug("Reapplying vm data (userData and metaData) entries as a part of domR " + router + " start..."); - createVmDataCommandForVMs(router, cmds); + createVmDataCommandForVMs(router, cmds, guestNetworkId); + } } return true; } @Override - public boolean finalizeStart(VirtualMachineProfile profile, long hostId, Commands cmds, ReservationContext context) { + public boolean finalizeStart(VirtualMachineProfile profile, long hostId, Commands cmds, + ReservationContext context) { DomainRouterVO router = profile.getVirtualMachine(); + boolean result = true; Answer answer = cmds.getAnswer("checkSsh"); @@ -1938,16 +2065,29 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian if (result == false) { return result; } + + //Get guest networks info + List guestNetworks = new ArrayList(); + + List routerNics = _nicDao.listByVmId(profile.getId()); + for (Nic routerNic : routerNics) { + Network network = _networkMgr.getNetwork(routerNic.getNetworkId()); + if (network.getTrafficType() == TrafficType.Guest) { + guestNetworks.add(network); + } + } + answer = cmds.getAnswer("getDomRVersion"); if (answer != null && answer instanceof GetDomRVersionAnswer) { GetDomRVersionAnswer versionAnswer = (GetDomRVersionAnswer)answer; if (answer == null || !answer.getResult()) { - s_logger.warn("Unable to get the template/scripts version of router " + router.getInstanceName() + " due to: " + versionAnswer.getDetails()); + s_logger.warn("Unable to get the template/scripts version of router " + router.getInstanceName() + + " due to: " + versionAnswer.getDetails()); result = false; } else { router.setTemplateVersion(versionAnswer.getTemplateVersion()); router.setScriptsVersion(versionAnswer.getScriptsVersion()); - router = _routerDao.persist(router); + router = _routerDao.persist(router, guestNetworks); } } else { result = false; @@ -1971,16 +2111,19 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian @Override - public boolean startRemoteAccessVpn(Network network, RemoteAccessVpn vpn, List routers) throws ResourceUnavailableException { + public boolean startRemoteAccessVpn(Network network, RemoteAccessVpn vpn, List routers) + throws ResourceUnavailableException { if (routers == null || routers.isEmpty()) { s_logger.warn("Failed to start remote access VPN: no router found for account and zone"); - throw new ResourceUnavailableException("Failed to start remote access VPN: no router found for account and zone", DataCenter.class, network.getDataCenterId()); + throw new ResourceUnavailableException("Failed to start remote access VPN: no router found for account and zone", + DataCenter.class, network.getDataCenterId()); } for (VirtualRouter router : routers) { if (router.getState() != State.Running) { s_logger.warn("Failed to start remote access VPN: router not in right state " + router.getState()); - throw new ResourceUnavailableException("Failed to start remote access VPN: router not in right state " + router.getState(), DataCenter.class, network.getDataCenterId()); + throw new ResourceUnavailableException("Failed to start remote access VPN: router not in right state " + + router.getState(), DataCenter.class, network.getDataCenterId()); } Commands cmds = new Commands(OnError.Stop); @@ -1994,16 +2137,20 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } Answer answer = cmds.getAnswer("users"); if (!answer.getResult()) { - s_logger.error("Unable to start vpn: unable add users to vpn in zone " + router.getDataCenterIdToDeployIn() + " for account " + vpn.getAccountId() + " on domR: " + router.getInstanceName() + s_logger.error("Unable to start vpn: unable add users to vpn in zone " + router.getDataCenterIdToDeployIn() + + " for account " + vpn.getAccountId() + " on domR: " + router.getInstanceName() + " due to " + answer.getDetails()); - throw new ResourceUnavailableException("Unable to start vpn: Unable to add users to vpn in zone " + router.getDataCenterIdToDeployIn() + " for account " + vpn.getAccountId() + " on domR: " + throw new ResourceUnavailableException("Unable to start vpn: Unable to add users to vpn in zone " + + router.getDataCenterIdToDeployIn() + " for account " + vpn.getAccountId() + " on domR: " + router.getInstanceName() + " due to " + answer.getDetails(), DataCenter.class, router.getDataCenterIdToDeployIn()); } answer = cmds.getAnswer("startVpn"); if (!answer.getResult()) { - s_logger.error("Unable to start vpn in zone " + router.getDataCenterIdToDeployIn() + " for account " + vpn.getAccountId() + " on domR: " + router.getInstanceName() + " due to " + s_logger.error("Unable to start vpn in zone " + router.getDataCenterIdToDeployIn() + " for account " + + vpn.getAccountId() + " on domR: " + router.getInstanceName() + " due to " + answer.getDetails()); - throw new ResourceUnavailableException("Unable to start vpn in zone " + router.getDataCenterIdToDeployIn() + " for account " + vpn.getAccountId() + " on domR: " + router.getInstanceName() + throw new ResourceUnavailableException("Unable to start vpn in zone " + router.getDataCenterIdToDeployIn() + + " for account " + vpn.getAccountId() + " on domR: " + router.getInstanceName() + " due to " + answer.getDetails(), DataCenter.class, router.getDataCenterIdToDeployIn()); } @@ -2013,7 +2160,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian @Override - public boolean deleteRemoteAccessVpn(Network network, RemoteAccessVpn vpn, List routers) throws ResourceUnavailableException { + public boolean deleteRemoteAccessVpn(Network network, RemoteAccessVpn vpn, List routers) + throws ResourceUnavailableException { if (routers == null || routers.isEmpty()) { s_logger.warn("Failed to delete remote access VPN: no router found for account and zone"); throw new ResourceUnavailableException("Failed to delete remote access VPN", DataCenter.class, network.getDataCenterId()); @@ -2025,9 +2173,10 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian Commands cmds = new Commands(OnError.Continue); IpAddress ip = _networkMgr.getIp(vpn.getServerAddressId()); - RemoteAccessVpnCfgCommand removeVpnCmd = new RemoteAccessVpnCfgCommand(false, ip.getAddress().addr(), vpn.getLocalIp(), vpn.getIpRange(), vpn.getIpsecPresharedKey()); + RemoteAccessVpnCfgCommand removeVpnCmd = new RemoteAccessVpnCfgCommand(false, ip.getAddress().addr(), + vpn.getLocalIp(), vpn.getIpRange(), vpn.getIpsecPresharedKey()); removeVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - removeVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, router.getGuestIpAddress()); + removeVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(network.getId(), router.getId())); removeVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); @@ -2041,7 +2190,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian continue; } else { s_logger.warn("Failed to delete remote access VPN: domR " + router + " is not in right state " + router.getState()); - throw new ResourceUnavailableException("Failed to delete remote access VPN: domR is not in right state " + router.getState(), DataCenter.class, network.getDataCenterId()); + throw new ResourceUnavailableException("Failed to delete remote access VPN: domR is not in right state " + + router.getState(), DataCenter.class, network.getDataCenterId()); } } @@ -2049,7 +2199,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } - private DomainRouterVO start(DomainRouterVO router, User user, Account caller, Map params, DeploymentPlan planToDeploy) throws StorageUnavailableException, InsufficientCapacityException, + private DomainRouterVO start(DomainRouterVO router, User user, Account caller, Map params, DeploymentPlan planToDeploy) + throws StorageUnavailableException, InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { s_logger.debug("Starting router " + router); if (_itMgr.start(router, params, user, caller, planToDeploy) != null) { @@ -2074,7 +2225,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } @Override - public boolean applyDhcpEntry(Network network, final NicProfile nic, VirtualMachineProfile profile, DeployDestination dest, List routers) + public boolean applyDhcpEntry(Network network, final NicProfile nic, VirtualMachineProfile profile, + DeployDestination dest, List routers) throws ResourceUnavailableException { _userVmDao.loadDetails((UserVmVO) profile.getVirtualMachine()); @@ -2084,7 +2236,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian boolean podLevelException = false; //for user vm in Basic zone we should try to re-deploy vm in a diff pod if it fails to deploy in original pod; so throwing exception with Pod scope - if (isZoneBasic && podId != null && updatedProfile.getVirtualMachine().getType() == VirtualMachine.Type.User && network.getTrafficType() == TrafficType.Guest && network.getGuestType() == Network.GuestType.Shared) { + if (isZoneBasic && podId != null && updatedProfile.getVirtualMachine().getType() == VirtualMachine.Type.User + && network.getTrafficType() == TrafficType.Guest && network.getGuestType() == Network.GuestType.Shared) { podLevelException = true; } @@ -2137,7 +2290,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian boolean podLevelException = false; //for user vm in Basic zone we should try to re-deploy vm in a diff pod if it fails to deploy in original pod; so throwing exception with Pod scope - if (isZoneBasic && podId != null && updatedProfile.getVirtualMachine().getType() == VirtualMachine.Type.User && network.getTrafficType() == TrafficType.Guest && network.getGuestType() == Network.GuestType.Shared) { + if (isZoneBasic && podId != null && updatedProfile.getVirtualMachine().getType() == VirtualMachine.Type.User + && network.getTrafficType() == TrafficType.Guest && network.getGuestType() == Network.GuestType.Shared) { podLevelException = true; } @@ -2160,15 +2314,6 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian @Override public DomainRouterVO persist(DomainRouterVO router) { DomainRouterVO virtualRouter = _routerDao.persist(router); - // Creating stats entry for router - UserStatisticsVO stats = _userStatsDao.findBy(virtualRouter.getAccountId(), virtualRouter.getDataCenterIdToDeployIn(), router.getNetworkId(), null, router.getId(), router.getType().toString()); - if (stats == null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Creating user statistics for the account: " + virtualRouter.getAccountId() + " Router Id: " + router.getId()); - } - stats = new UserStatisticsVO(virtualRouter.getAccountId(), virtualRouter.getDataCenterIdToDeployIn(), null, router.getId(), router.getType().toString(), router.getNetworkId()); - _userStatsDao.persist(stats); - } return virtualRouter; } @@ -2177,7 +2322,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian public String[] applyVpnUsers(Network network, List users, List routers) throws ResourceUnavailableException { if (routers == null || routers.isEmpty()) { s_logger.warn("Failed to add/remove VPN users: no router found for account and zone"); - throw new ResourceUnavailableException("Unable to assign ip addresses, domR doesn't exist for network " + network.getId(), DataCenter.class, network.getDataCenterId()); + throw new ResourceUnavailableException("Unable to assign ip addresses, domR doesn't exist for network " + + network.getId(), DataCenter.class, network.getDataCenterId()); } boolean agentResults = true; @@ -2185,7 +2331,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian for (DomainRouterVO router : routers) { if (router.getState() != State.Running) { s_logger.warn("Failed to add/remove VPN users: router not in running state"); - throw new ResourceUnavailableException("Unable to assign ip addresses, domR is not in right state " + router.getState(), DataCenter.class, network.getDataCenterId()); + throw new ResourceUnavailableException("Unable to assign ip addresses, domR is not in right state " + + router.getState(), DataCenter.class, network.getDataCenterId()); } Commands cmds = new Commands(OnError.Continue); @@ -2203,7 +2350,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian cmd.setAccessDetail(NetworkElementCommand.ACCOUNT_ID, String.valueOf(router.getAccountId())); cmd.setAccessDetail(NetworkElementCommand.GUEST_NETWORK_CIDR, network.getCidr()); cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, router.getGuestIpAddress()); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(network.getId(), router.getId())); cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); @@ -2249,7 +2396,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } @Override - public VirtualRouter startRouter(long routerId, boolean reprogramNetwork) throws ResourceUnavailableException, InsufficientCapacityException, ConcurrentOperationException { + public VirtualRouter startRouter(long routerId, boolean reprogramNetwork) throws ResourceUnavailableException, + InsufficientCapacityException, ConcurrentOperationException { Account caller = UserContext.current().getCaller(); User callerUser = _accountMgr.getActiveUser(UserContext.current().getCallerUserId()); @@ -2284,9 +2432,9 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian UserVO user = _userDao.findById(UserContext.current().getCallerUserId()); Map params = new HashMap(); if (reprogramNetwork) { - params.put(Param.ReProgramNetwork, true); + params.put(Param.ReProgramGuestNetworks, true); } else { - params.put(Param.ReProgramNetwork, false); + params.put(Param.ReProgramGuestNetworks, false); } VirtualRouter virtualRouter = startVirtualRouter(router, user, caller, params); if(virtualRouter == null){ @@ -2348,7 +2496,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian String vmGuestAddress = null; - IpAddressTO ip = new IpAddressTO(ipAddr.getAccountId(), ipAddr.getAddress().addr(), add, firstIP, sourceNat, vlanId, vlanGateway, vlanNetmask, vifMacAddress, vmGuestAddress, networkRate, ipAddr.isOneToOneNat()); + IpAddressTO ip = new IpAddressTO(ipAddr.getAccountId(), ipAddr.getAddress().addr(), add, firstIP, + sourceNat, vlanId, vlanGateway, vlanNetmask, vifMacAddress, vmGuestAddress, networkRate, ipAddr.isOneToOneNat()); ip.setTrafficType(network.getTrafficType()); ip.setNetworkName(_networkMgr.getNetworkTag(router.getHypervisorType(), network)); @@ -2360,7 +2509,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } IpAssocCommand cmd = new IpAssocCommand(ipsToSend); cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, router.getGuestIpAddress()); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(ipAddrList.get(0).getNetworkId(), router.getId())); cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); @@ -2369,7 +2518,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } } - private void createApplyPortForwardingRulesCommands(List rules, VirtualRouter router, Commands cmds) { + private void createApplyPortForwardingRulesCommands(List rules, VirtualRouter router, Commands cmds, long guestNetworkId) { List rulesTO = null; if (rules != null) { rulesTO = new ArrayList(); @@ -2382,7 +2531,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian SetPortForwardingRulesCommand cmd = new SetPortForwardingRulesCommand(rulesTO); cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, router.getGuestIpAddress()); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(guestNetworkId, router.getId())); cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); @@ -2390,7 +2539,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian cmds.addCommand(cmd); } - private void createApplyStaticNatRulesCommands(List rules, VirtualRouter router, Commands cmds) { + private void createApplyStaticNatRulesCommands(List rules, VirtualRouter router, Commands cmds, long guestNetworkId) { List rulesTO = null; if (rules != null) { rulesTO = new ArrayList(); @@ -2403,14 +2552,14 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(rulesTO); cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, router.getGuestIpAddress()); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(guestNetworkId, router.getId())); cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); cmds.addCommand(cmd); } - private void createApplyLoadBalancingRulesCommands(List rules, VirtualRouter router, Commands cmds) { + private void createApplyLoadBalancingRulesCommands(List rules, VirtualRouter router, Commands cmds, long guestNetworkId) { LoadBalancerTO[] lbs = new LoadBalancerTO[rules.size()]; int i = 0; @@ -2433,7 +2582,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian RouterPublicIp = domr.getPublicIpAddress(); } - LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(lbs,RouterPublicIp, router.getGuestIpAddress(),router.getPrivateIpAddress()); + LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(lbs,RouterPublicIp, getRouterIpInNetwork(guestNetworkId, router.getId()),router.getPrivateIpAddress()); cmd.lbStatsVisibility = _configDao.getValue(Config.NetworkLBHaproxyStatsVisbility.key()); cmd.lbStatsUri = _configDao.getValue(Config.NetworkLBHaproxyStatsUri.key()); @@ -2442,7 +2591,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, router.getGuestIpAddress()); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(guestNetworkId, router.getId())); cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); @@ -2464,14 +2613,15 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian VpnUsersCfgCommand addUsersCmd = new VpnUsersCfgCommand(addUsers, removeUsers); addUsersCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - addUsersCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, router.getGuestIpAddress()); + addUsersCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(vpn.getNetworkId(), router.getId())); addUsersCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); IpAddress ip = _networkMgr.getIp(vpn.getServerAddressId()); - RemoteAccessVpnCfgCommand startVpnCmd = new RemoteAccessVpnCfgCommand(true, ip.getAddress().addr(), vpn.getLocalIp(), vpn.getIpRange(), vpn.getIpsecPresharedKey()); + RemoteAccessVpnCfgCommand startVpnCmd = new RemoteAccessVpnCfgCommand(true, ip.getAddress().addr(), + vpn.getLocalIp(), vpn.getIpRange(), vpn.getIpsecPresharedKey()); startVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - startVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, router.getGuestIpAddress()); + startVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(vpn.getNetworkId(), router.getId())); startVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); startVpnCmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); @@ -2489,7 +2639,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian final String encodedPassword = PasswordGenerator.rot13(password); SavePasswordCommand cmd = new SavePasswordCommand(encodedPassword, nic.getIp4Address(), profile.getVirtualMachine().getHostName()); cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, router.getGuestIpAddress()); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(nic.getNetworkId(), router.getId())); cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); @@ -2503,13 +2653,12 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian String zoneName = _dcDao.findById(router.getDataCenterIdToDeployIn()).getName(); cmds.addCommand("vmdata", generateVmDataCommand(router, nic.getIp4Address(), vm.getUserData(), serviceOffering, zoneName, nic.getIp4Address(), - vm.getHostName(), vm.getInstanceName(), vm.getId(), publicKey)); + vm.getHostName(), vm.getInstanceName(), vm.getId(), publicKey, nic.getNetworkId())); } - private void createVmDataCommandForVMs(DomainRouterVO router, Commands cmds) { - long networkId = router.getNetworkId(); - List vms = _userVmDao.listByNetworkIdAndStates(networkId, State.Running, State.Migrating, State.Stopping); + private void createVmDataCommandForVMs(DomainRouterVO router, Commands cmds, long guestNetworkId) { + List vms = _userVmDao.listByNetworkIdAndStates(guestNetworkId, State.Running, State.Migrating, State.Stopping); DataCenterVO dc = _dcDao.findById(router.getDataCenterIdToDeployIn()); for (UserVmVO vm : vms) { boolean createVmData = true; @@ -2518,7 +2667,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } if (createVmData) { - NicVO nic = _nicDao.findByInstanceIdAndNetworkId(networkId, vm.getId()); + NicVO nic = _nicDao.findByInstanceIdAndNetworkId(guestNetworkId, vm.getId()); if (nic != null) { s_logger.debug("Creating user data entry for vm " + vm + " on domR " + router); createVmDataCommand(router, vm, nic, null, cmds); @@ -2544,23 +2693,23 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian dhcpCommand.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); dhcpCommand.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); - dhcpCommand.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, router.getGuestIpAddress()); + dhcpCommand.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(nic.getNetworkId(), router.getId())); dhcpCommand.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); cmds.addCommand("dhcp", dhcpCommand); } - private void createDhcpEntryCommandsForVMs(DomainRouterVO router, Commands cmds) { - long networkId = router.getNetworkId(); - List vms = _userVmDao.listByNetworkIdAndStates(networkId, State.Running, State.Migrating, State.Stopping); + private void createDhcpEntryCommandsForVMs(DomainRouterVO router, Commands cmds, long guestNetworkId) { + List vms = _userVmDao.listByNetworkIdAndStates(guestNetworkId, State.Running, State.Migrating, State.Stopping); DataCenterVO dc = _dcDao.findById(router.getDataCenterIdToDeployIn()); for (UserVmVO vm : vms) { boolean createDhcp = true; - if (dc.getNetworkType() == NetworkType.Basic && router.getPodIdToDeployIn().longValue() != vm.getPodIdToDeployIn().longValue() && _dnsBasicZoneUpdates.equalsIgnoreCase("pod")) { + if (dc.getNetworkType() == NetworkType.Basic && router.getPodIdToDeployIn().longValue() != vm.getPodIdToDeployIn().longValue() + && _dnsBasicZoneUpdates.equalsIgnoreCase("pod")) { createDhcp = false; } if (createDhcp) { - NicVO nic = _nicDao.findByInstanceIdAndNetworkId(networkId, vm.getId()); + NicVO nic = _nicDao.findByInstanceIdAndNetworkId(guestNetworkId, vm.getId()); if (nic != null) { s_logger.debug("Creating dhcp entry for vm " + vm + " on domR " + router + "."); createDhcpEntryCommand(router, vm, nic, cmds); @@ -2569,7 +2718,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } } - private boolean sendCommandsToRouter(final VirtualRouter router, Commands cmds) throws AgentUnavailableException { + protected boolean sendCommandsToRouter(final VirtualRouter router, Commands cmds) throws AgentUnavailableException { Answer[] answers = null; try { answers = _agentMgr.send(router.getHostId(), cmds); @@ -2609,10 +2758,12 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian return; } if (!connectedRouters.get(0).getIsRedundantRouter()) { - throw new ResourceUnavailableException("Who is calling this with non-redundant router or non-domain router?", DataCenter.class, connectedRouters.get(0).getDataCenterIdToDeployIn()); + throw new ResourceUnavailableException("Who is calling this with non-redundant router or non-domain router?", + DataCenter.class, connectedRouters.get(0).getDataCenterIdToDeployIn()); } if (!disconnectedRouters.get(0).getIsRedundantRouter()) { - throw new ResourceUnavailableException("Who is calling this with non-redundant router or non-domain router?", DataCenter.class, disconnectedRouters.get(0).getDataCenterIdToDeployIn()); + throw new ResourceUnavailableException("Who is calling this with non-redundant router or non-domain router?", + DataCenter.class, disconnectedRouters.get(0).getDataCenterIdToDeployIn()); } DomainRouterVO connectedRouter = (DomainRouterVO)connectedRouters.get(0); @@ -2649,7 +2800,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } @Override - public boolean associateIP(Network network, final List ipAddress, List routers) throws ResourceUnavailableException { + public boolean associateIP(Network network, final List ipAddress, List routers) + throws ResourceUnavailableException { if (ipAddress == null || ipAddress.isEmpty()) { s_logger.debug("No ip association rules to be applied for network " + network.getId()); return true; @@ -2683,13 +2835,13 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList,policyList); lbRules.add(loadBalancing); } - return sendLBRules(router, lbRules); + return sendLBRules(router, lbRules, network.getId()); } else if (rules.get(0).getPurpose() == Purpose.PortForwarding) { - return sendPortForwardingRules(router, (List) rules); + return sendPortForwardingRules(router, (List) rules, network.getId()); } else if (rules.get(0).getPurpose() == Purpose.StaticNat) { - return sendStaticNatRules(router, (List) rules); + return sendStaticNatRules(router, (List) rules, network.getId()); } else if (rules.get(0).getPurpose() == Purpose.Firewall) { - return sendFirewallRules(router, (List) rules); + return sendFirewallRules(router, (List) rules, network.getId()); } else { s_logger.warn("Unable to apply rules of purpose: " + rules.get(0).getPurpose()); return false; @@ -2698,21 +2850,21 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian }); } - protected boolean sendLBRules(VirtualRouter router, List rules) throws ResourceUnavailableException { + protected boolean sendLBRules(VirtualRouter router, List rules, long guestNetworkId) throws ResourceUnavailableException { Commands cmds = new Commands(OnError.Continue); - createApplyLoadBalancingRulesCommands(rules, router, cmds); + createApplyLoadBalancingRulesCommands(rules, router, cmds, guestNetworkId); return sendCommandsToRouter(router, cmds); } - protected boolean sendPortForwardingRules(VirtualRouter router, List rules) throws ResourceUnavailableException { + protected boolean sendPortForwardingRules(VirtualRouter router, List rules, long guestNetworkId) throws ResourceUnavailableException { Commands cmds = new Commands(OnError.Continue); - createApplyPortForwardingRulesCommands(rules, router, cmds); + createApplyPortForwardingRulesCommands(rules, router, cmds, guestNetworkId); return sendCommandsToRouter(router, cmds); } - protected boolean sendStaticNatRules(VirtualRouter router, List rules) throws ResourceUnavailableException { + protected boolean sendStaticNatRules(VirtualRouter router, List rules, long guestNetworkId) throws ResourceUnavailableException { Commands cmds = new Commands(OnError.Continue); - createApplyStaticNatRulesCommands(rules, router, cmds); + createApplyStaticNatRulesCommands(rules, router, cmds, guestNetworkId); return sendCommandsToRouter(router, cmds); } @@ -2726,7 +2878,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian return vrs; } - private void createFirewallRulesCommands(List rules, VirtualRouter router, Commands cmds) { + private void createFirewallRulesCommands(List rules, VirtualRouter router, Commands cmds, long guestNetworkId) { List rulesTO = null; if (rules != null) { rulesTO = new ArrayList(); @@ -2739,7 +2891,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian SetFirewallRulesCommand cmd = new SetFirewallRulesCommand(rulesTO); cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, router.getGuestIpAddress()); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(guestNetworkId, router.getId())); cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); @@ -2747,9 +2899,9 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } - protected boolean sendFirewallRules(VirtualRouter router, List rules) throws ResourceUnavailableException { + protected boolean sendFirewallRules(VirtualRouter router, List rules, long guestNetworkId) throws ResourceUnavailableException { Commands cmds = new Commands(OnError.Continue); - createFirewallRulesCommands(rules, router, cmds); + createFirewallRulesCommands(rules, router, cmds, guestNetworkId); return sendCommandsToRouter(router, cmds); } @@ -2758,11 +2910,12 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian return _dnsBasicZoneUpdates; } - private interface RuleApplier { + protected interface RuleApplier { boolean execute(Network network, VirtualRouter router) throws ResourceUnavailableException; } - private boolean applyRules(Network network, List routers, String typeString, boolean isPodLevelException, Long podId, boolean failWhenDisconnect, RuleApplier applier) throws ResourceUnavailableException { + protected boolean applyRules(Network network, List routers, String typeString, + boolean isPodLevelException, Long podId, boolean failWhenDisconnect, RuleApplier applier) throws ResourceUnavailableException { if (routers == null || routers.isEmpty()) { s_logger.warn("Unable to apply " + typeString + ", virtual router doesn't exist in the network " + network.getId()); throw new ResourceUnavailableException("Unable to apply " + typeString , DataCenter.class, network.getDataCenterId()); @@ -2784,10 +2937,12 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian if (router.isStopPending()) { if (_hostDao.findById(router.getHostId()).getStatus() == Status.Up) { - throw new ResourceUnavailableException("Unable to process due to the stop pending router " + router.getInstanceName() + " haven't been stopped after it's host coming back!", + throw new ResourceUnavailableException("Unable to process due to the stop pending router " + + router.getInstanceName() + " haven't been stopped after it's host coming back!", DataCenter.class, router.getDataCenterIdToDeployIn()); } - s_logger.debug("Router " + router.getInstanceName() + " is stop pending, so not sending apply " + typeString + " commands to the backend"); + s_logger.debug("Router " + router.getInstanceName() + " is stop pending, so not sending apply " + + typeString + " commands to the backend"); continue; } try { @@ -2803,17 +2958,21 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian if (isZoneBasic && isPodLevelException) { throw new ResourceUnavailableException("Unable to apply " + typeString + " on router ", Pod.class, podId); } - throw new ResourceUnavailableException("Unable to apply " + typeString + " on router ", DataCenter.class, router.getDataCenterIdToDeployIn()); + throw new ResourceUnavailableException("Unable to apply " + typeString + " on router ", DataCenter.class, + router.getDataCenterIdToDeployIn()); } } else if (router.getState() == State.Stopped || router.getState() == State.Stopping) { - s_logger.debug("Router " + router.getInstanceName() + " is in " + router.getState() + ", so not sending apply " + typeString + " commands to the backend"); + s_logger.debug("Router " + router.getInstanceName() + " is in " + router.getState() + + ", so not sending apply " + typeString + " commands to the backend"); } else { s_logger.warn("Unable to apply " + typeString +", virtual router is not in the right state " + router.getState()); if (isZoneBasic && isPodLevelException) { - throw new ResourceUnavailableException("Unable to apply " + typeString + ", virtual router is not in the right state", Pod.class, podId); + throw new ResourceUnavailableException("Unable to apply " + typeString + + ", virtual router is not in the right state", Pod.class, podId); } - throw new ResourceUnavailableException("Unable to apply " + typeString + ", virtual router is not in the right state", DataCenter.class, router.getDataCenterIdToDeployIn()); + throw new ResourceUnavailableException("Unable to apply " + typeString + + ", virtual router is not in the right state", DataCenter.class, router.getDataCenterIdToDeployIn()); } } @@ -2850,32 +3009,33 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian return applyRules(network, routers, "static nat rules", false, null, false, new RuleApplier() { @Override public boolean execute(Network network, VirtualRouter router) throws ResourceUnavailableException { - return applyStaticNat(router, rules); + return applyStaticNat(router, rules, network.getId()); } }); } - protected boolean applyStaticNat(VirtualRouter router, List rules) throws ResourceUnavailableException { + protected boolean applyStaticNat(VirtualRouter router, List rules, long guestNetworkId) throws ResourceUnavailableException { Commands cmds = new Commands(OnError.Continue); - createApplyStaticNatCommands(rules, router, cmds); + createApplyStaticNatCommands(rules, router, cmds, guestNetworkId); return sendCommandsToRouter(router, cmds); } - private void createApplyStaticNatCommands(List rules, VirtualRouter router, Commands cmds) { + private void createApplyStaticNatCommands(List rules, VirtualRouter router, Commands cmds, long guestNetworkId) { List rulesTO = null; if (rules != null) { rulesTO = new ArrayList(); for (StaticNat rule : rules) { IpAddress sourceIp = _networkMgr.getIp(rule.getSourceIpAddressId()); - StaticNatRuleTO ruleTO = new StaticNatRuleTO(0, sourceIp.getAddress().addr(), null, null, rule.getDestIpAddress(), null, null, null, rule.isForRevoke(), false); + StaticNatRuleTO ruleTO = new StaticNatRuleTO(0, sourceIp.getAddress().addr(), null, + null, rule.getDestIpAddress(), null, null, null, rule.isForRevoke(), false); rulesTO.add(ruleTO); } } SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(rulesTO); cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, router.getGuestIpAddress()); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(guestNetworkId, router.getId())); cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); @@ -2906,7 +3066,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { UserContext context = UserContext.current(); context.setAccountId(1); - List routers = _routerDao.listVirtualByHostId(host.getId()); + List routers = _routerDao.listIsolatedByHostId(host.getId()); for (DomainRouterVO router : routers) { if (router.isStopPending()) { State state = router.getState(); @@ -2933,6 +3093,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } @Override + public boolean processDisconnect(long agentId, Status state) { return false; } @@ -2942,15 +3103,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian return false; } - @Override - public long getDefaultVirtualRouterServiceOfferingId() { - if (_offering != null) { - return _offering.getId(); - } - return 0; - } - - private String getRouterControlIp(long routerId) { + protected String getRouterControlIp(long routerId) { String routerControlIpAddress = null; List nics = _nicDao.listByVmId(routerId); for (NicVO n : nics) { @@ -2968,4 +3121,26 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian return routerControlIpAddress; } + + + protected String getRouterIpInNetwork(long networkId, long instanceId) { + return _nicDao.getIpAddress(networkId, instanceId); + } + + + @Override + public boolean plugNic(Network network, NicTO nic, VirtualMachineTO vm, ReservationContext context, DeployDestination dest) + throws ConcurrentOperationException, ResourceUnavailableException, + InsufficientCapacityException { + //not supported + throw new UnsupportedOperationException("Plug nic is not supported for vm of type " + vm.getType()); + } + + @Override + public boolean unplugNic(Network network, NicTO nic, VirtualMachineTO vm, ReservationContext context, DeployDestination dest) + throws ConcurrentOperationException, ResourceUnavailableException { + //not supported + throw new UnsupportedOperationException("Unplug nic is not supported for vm of type " + vm.getType()); + } + } diff --git a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java new file mode 100644 index 00000000000..68164138d11 --- /dev/null +++ b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java @@ -0,0 +1,47 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.router; + +import java.util.List; +import java.util.Map; + +import com.cloud.deploy.DeployDestination; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.VpcVirtualNetworkApplianceService; +import com.cloud.network.vpc.Vpc; +import com.cloud.user.Account; +import com.cloud.vm.DomainRouterVO; +import com.cloud.vm.VirtualMachineProfile.Param; + +/** + * @author Alena Prokharchyk + */ +public interface VpcVirtualNetworkApplianceManager extends VirtualNetworkApplianceManager, VpcVirtualNetworkApplianceService{ + + /** + * @param vpc + * @param dest + * @param owner + * @param params + * @return + * @throws InsufficientCapacityException + * @throws ConcurrentOperationException + * @throws ResourceUnavailableException + */ + List deployVirtualRouterInVpc(Vpc vpc, DeployDestination dest, Account owner, Map params) + throws InsufficientCapacityException, ConcurrentOperationException, + ResourceUnavailableException; + +} diff --git a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java new file mode 100644 index 00000000000..bc7d3e00213 --- /dev/null +++ b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java @@ -0,0 +1,705 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.router; + +import java.net.URI; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.ejb.Local; + +import org.apache.log4j.Logger; + +import com.cloud.agent.AgentManager.OnError; +import com.cloud.agent.api.PlugNicAnswer; +import com.cloud.agent.api.PlugNicCommand; +import com.cloud.agent.api.SetupGuestNetworkAnswer; +import com.cloud.agent.api.SetupGuestNetworkCommand; +import com.cloud.agent.api.UnPlugNicAnswer; +import com.cloud.agent.api.UnPlugNicCommand; +import com.cloud.agent.api.routing.IpAssocVpcCommand; +import com.cloud.agent.api.routing.NetworkElementCommand; +import com.cloud.agent.api.routing.SetSourceNatCommand; +import com.cloud.agent.api.to.IpAddressTO; +import com.cloud.agent.api.to.NicTO; +import com.cloud.agent.api.to.VirtualMachineTO; +import com.cloud.agent.manager.Commands; +import com.cloud.dc.DataCenterVO; +import com.cloud.deploy.DataCenterDeployment; +import com.cloud.deploy.DeployDestination; +import com.cloud.deploy.DeploymentPlan; +import com.cloud.exception.AgentUnavailableException; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InsufficientServerCapacityException; +import com.cloud.exception.InsufficientVirtualNetworkCapcityException; +import com.cloud.exception.OperationTimedoutException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.exception.StorageUnavailableException; +import com.cloud.network.IPAddressVO; +import com.cloud.network.IpAddress; +import com.cloud.network.Network; +import com.cloud.network.Network.Provider; +import com.cloud.network.Network.Service; +import com.cloud.network.NetworkService; +import com.cloud.network.Networks.BroadcastDomainType; +import com.cloud.network.Networks.IsolationType; +import com.cloud.network.Networks.TrafficType; +import com.cloud.network.PhysicalNetwork; +import com.cloud.network.PhysicalNetworkServiceProvider; +import com.cloud.network.PublicIpAddress; +import com.cloud.network.VirtualRouterProvider; +import com.cloud.network.VirtualRouterProvider.VirtualRouterProviderType; +import com.cloud.network.VpcVirtualNetworkApplianceService; +import com.cloud.network.addr.PublicIp; +import com.cloud.network.dao.PhysicalNetworkDao; +import com.cloud.network.router.VirtualRouter.Role; +import com.cloud.network.vpc.Vpc; +import com.cloud.network.vpc.Dao.VpcDao; +import com.cloud.network.vpc.Dao.VpcOfferingDao; +import com.cloud.user.Account; +import com.cloud.utils.Pair; +import com.cloud.utils.component.Inject; +import com.cloud.utils.db.DB; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.net.NetUtils; +import com.cloud.vm.DomainRouterVO; +import com.cloud.vm.Nic; +import com.cloud.vm.NicProfile; +import com.cloud.vm.ReservationContext; +import com.cloud.vm.VirtualMachineProfile; +import com.cloud.vm.VirtualMachineProfile.Param; + +/** + * @author Alena Prokharchyk + */ + +@Local(value = {VpcVirtualNetworkApplianceManager.class, VpcVirtualNetworkApplianceService.class}) +public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplianceManagerImpl implements VpcVirtualNetworkApplianceManager{ + private static final Logger s_logger = Logger.getLogger(VpcVirtualNetworkApplianceManagerImpl.class); + + @Inject + VpcDao _vpcDao = null; + @Inject + VpcOfferingDao _vpcOffDao = null; + @Inject + PhysicalNetworkDao _pNtwkDao = null; + @Inject + NetworkService _ntwkService = null; + + @Override + public List deployVirtualRouterInVpc(Vpc vpc, DeployDestination dest, Account owner, + Map params) throws InsufficientCapacityException, + ConcurrentOperationException, ResourceUnavailableException { + + List routers = findOrDeployVirtualRouterInVpc(vpc, dest, owner, params); + + return startRouters(params, routers); + } + + @DB + protected List findOrDeployVirtualRouterInVpc(Vpc vpc, DeployDestination dest, Account owner, + Map params) throws ConcurrentOperationException, + InsufficientCapacityException, ResourceUnavailableException { + + s_logger.debug("Deploying Virtual Router in VPC "+ vpc); + Vpc vpcLock = _vpcDao.acquireInLockTable(vpc.getId()); + if (vpcLock == null) { + throw new ConcurrentOperationException("Unable to lock vpc " + vpc.getId()); + } + + //1) Get deployment plan and find out the list of routers + Pair> planAndRouters = getDeploymentPlanAndRouters(vpc.getId(), dest); + DeploymentPlan plan = planAndRouters.first(); + List routers = planAndRouters.second(); + try { + //2) Return routers if exist + if (routers.size() >= 1) { + return routers; + } + + Long offeringId = _vpcOffDao.findById(vpc.getVpcOfferingId()).getServiceOfferingId(); + if (offeringId == null) { + offeringId = _offering.getId(); + } + //3) Deploy Virtual Router + List pNtwks = _pNtwkDao.listByZone(vpc.getZoneId()); + + VirtualRouterProvider vpcVrProvider = null; + + for (PhysicalNetwork pNtwk : pNtwks) { + PhysicalNetworkServiceProvider provider = _physicalProviderDao.findByServiceProvider(pNtwk.getId(), + VirtualRouterProviderType.VPCVirtualRouter.toString()); + if (provider == null) { + throw new CloudRuntimeException("Cannot find service provider " + + VirtualRouterProviderType.VPCVirtualRouter.toString() + " in physical network " + pNtwk.getId()); + } + vpcVrProvider = _vrProviderDao.findByNspIdAndType(provider.getId(), + VirtualRouterProviderType.VPCVirtualRouter); + if (vpcVrProvider != null) { + break; + } + } + + PublicIp sourceNatIp = _networkMgr.assignSourceNatIpAddressToVpc(owner, vpc); + + DomainRouterVO router = deployVpcRouter(owner, dest, plan, params, false, vpcVrProvider, offeringId, + vpc.getId(), sourceNatIp); + routers.add(router); + + } finally { + if (vpcLock != null) { + _vpcDao.releaseFromLockTable(vpc.getId()); + } + } + return routers; + } + + protected Pair> getDeploymentPlanAndRouters(long vpcId, DeployDestination dest) { + long dcId = dest.getDataCenter().getId(); + + DeploymentPlan plan = new DataCenterDeployment(dcId); + List routers = _routerDao.listRoutersByVpcId(vpcId); + + return new Pair>(plan, routers); + } + + @Override + public boolean addVpcRouterToGuestNetwork(VirtualRouter router, Network network, boolean isRedundant) + throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { + boolean dnsProvided = _networkMgr.isProviderSupportServiceInNetwork(network.getId(), Service.Dns, Provider.VPCVirtualRouter); + boolean dhcpProvided = _networkMgr.isProviderSupportServiceInNetwork(network.getId(), Service.Dhcp, + Provider.VPCVirtualRouter); + + boolean setupDns = dnsProvided || dhcpProvided; + + return addVpcRouterToGuestNetwork(router, network, isRedundant, setupDns); + } + + protected boolean addVpcRouterToGuestNetwork(VirtualRouter router, Network network, boolean isRedundant, boolean setupDns) + throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { + + if (network.getTrafficType() != TrafficType.Guest) { + s_logger.warn("Network " + network + " is not of type " + TrafficType.Guest); + return false; + } + + //Add router to the Guest network + boolean result = true; + try { + if (!_routerDao.isRouterPartOfGuestNetwork(router.getId(), network.getId())) { + DomainRouterVO routerVO = _routerDao.findById(router.getId()); + _routerDao.addRouterToGuestNetwork(routerVO, network); + } + + NicProfile guestNic = _itMgr.addVmToNetwork(router, network, null); + //setup guest network + if (guestNic != null) { + result = setupVpcGuestNetwork(network, router, true, isRedundant, guestNic, setupDns); + } else { + s_logger.warn("Failed to add router " + router + " to guest network " + network); + result = false; + } + } catch (Exception ex) { + s_logger.warn("Failed to add router " + router + " to network " + network + " due to ", ex); + result = false; + } finally { + if (!result) { + s_logger.debug("Removing the router " + router + " from network " + network + " as a part of cleanup"); + if (removeRouterFromGuestNetwork(router, network, isRedundant)) { + s_logger.debug("Removed the router " + router + " from network " + network + " as a part of cleanup"); + } else { + s_logger.warn("Failed to remove the router " + router + " from network " + network + " as a part of cleanup"); + } + } + } + + return result; + } + + @Override + public boolean removeRouterFromGuestNetwork(VirtualRouter router, Network network, boolean isRedundant) + throws ConcurrentOperationException, ResourceUnavailableException { + if (network.getTrafficType() != TrafficType.Guest) { + s_logger.warn("Network " + network + " is not of type " + TrafficType.Guest); + return false; + } + + //Check if router is a part of the Guest network + if (!_networkMgr.isVmPartOfNetwork(router.getId(), network.getId())) { + s_logger.debug("Router " + router + " is not a part of the Guest network " + network); + return true; + } + + boolean result = setupVpcGuestNetwork(network, router, false, isRedundant, _networkMgr.getNicProfile(router, network.getId()), false); + if (!result) { + s_logger.warn("Failed to destroy guest network config " + network + " on router " + router); + return false; + } + + result = result && _itMgr.removeVmFromNetwork(router, network, null); + + if (result) { + if (result) { + //check if router is already part of network + if (_routerDao.isRouterPartOfGuestNetwork(router.getId(), network.getId())) { + s_logger.debug("Removing router " + router + " from network" + network); + _routerDao.removeRouterFromNetwork(router.getId(), network.getId()); + } + } + } + return result; + } + + protected boolean addPublicIpToVpc(VirtualRouter router, Network publicNetwork, PublicIp ipAddress) + throws ConcurrentOperationException,ResourceUnavailableException, InsufficientCapacityException { + + if (publicNetwork.getTrafficType() != TrafficType.Public) { + s_logger.warn("Network " + publicNetwork + " is not of type " + TrafficType.Public); + return false; + } + + //Add router to the Public network + boolean result = true; + try { + NicProfile defaultNic = new NicProfile(); + if (ipAddress.isSourceNat()) { + defaultNic.setDefaultNic(true); + } + defaultNic.setIp4Address(ipAddress.getAddress().addr()); + defaultNic.setGateway(ipAddress.getGateway()); + defaultNic.setNetmask(ipAddress.getNetmask()); + defaultNic.setMacAddress(ipAddress.getMacAddress()); + defaultNic.setBroadcastType(BroadcastDomainType.Vlan); + defaultNic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ipAddress.getVlanTag())); + defaultNic.setIsolationUri(IsolationType.Vlan.toUri(ipAddress.getVlanTag())); + + NicProfile publicNic = _itMgr.addVmToNetwork(router, publicNetwork, defaultNic); + //setup public network + if (publicNic != null) { + publicNic.setDefaultNic(true); + if (ipAddress != null) { + IPAddressVO ipVO = _ipAddressDao.findById(ipAddress.getId()); + PublicIp publicIp = new PublicIp(ipVO, _vlanDao.findById(ipVO.getVlanId()), + NetUtils.createSequenceBasedMacAddress(ipVO.getMacAddress())); + result = associtePublicIpInVpc(publicNetwork, router, false, publicIp); + } + } else { + result = false; + s_logger.warn("Failed to plug nic for " + ipAddress + " to VPC router " + router); + } + } catch (Exception ex) { + s_logger.warn("Failed to add ip address " + ipAddress + " from the public network " + publicNetwork + + " to VPC router " + router + " due to ", ex); + result = false; + } + + return result; + } + + + protected boolean removePublicIpFromVpcRouter(VirtualRouter router, Network publicNetwork, PublicIp ipAddress) + throws ConcurrentOperationException, ResourceUnavailableException { + + if (publicNetwork.getTrafficType() != TrafficType.Public) { + s_logger.warn("Network " + publicNetwork + " is not of type " + TrafficType.Public); + return false; + } + + boolean result = true; + IPAddressVO ipVO = _ipAddressDao.findById(ipAddress.getId()); + _networkMgr.markIpAsUnavailable(ipVO.getId()); + PublicIp publicIp = new PublicIp(ipVO, _vlanDao.findById(ipVO.getVlanId()), + NetUtils.createSequenceBasedMacAddress(ipVO.getMacAddress())); + result = associtePublicIpInVpc(publicNetwork, router, false, publicIp); + + if (!result) { + s_logger.warn("Failed to disassociate public ip " + ipAddress + " from router " + router); + return false; + } + + URI broadcastUri = BroadcastDomainType.Vlan.toUri(ipAddress.getVlanTag()); + if (_itMgr.removeVmFromNetwork(router, publicNetwork, broadcastUri)) { + s_logger.debug("Successfully removed router " + router + " from vlan " + ipAddress.getVlanTag() +" of public network " + publicNetwork); + return true; + } else { + s_logger.warn("Failed to remove router " + router + " from vlan " + ipAddress.getVlanTag() +" of public network " + publicNetwork); + return false; + } + } + + protected boolean associtePublicIpInVpc(Network network, VirtualRouter router, boolean add, PublicIp ipAddress) + throws ConcurrentOperationException, ResourceUnavailableException{ + + List publicIps = new ArrayList(1); + publicIps.add(ipAddress); + Commands cmds = new Commands(OnError.Stop); + createVpcAssociateIPCommands(router, publicIps, cmds, 0); + + if (sendCommandsToRouter(router, cmds)) { + s_logger.debug("Successfully applied ip association for ip " + ipAddress + " in vpc network " + network); + return true; + } else { + s_logger.warn("Failed to associate ip address " + ipAddress + " in vpc network " + network); + return false; + } + } + + + @Override + public boolean finalizeStart(VirtualMachineProfile profile, long hostId, Commands cmds, + ReservationContext context) { + + + + if (!super.finalizeStart(profile, hostId, cmds, context)) { + return false; + } else if (profile.getVirtualMachine().getVpcId() == null) { + return true; + } + + DomainRouterVO router = profile.getVirtualMachine(); + + //Get guest nic info + Map guestNics = new HashMap(); + Map publicNics = new HashMap(); + + List routerNics = _nicDao.listByVmId(profile.getId()); + for (Nic routerNic : routerNics) { + Network network = _networkMgr.getNetwork(routerNic.getNetworkId()); + if (network.getTrafficType() == TrafficType.Guest) { + guestNics.put(routerNic, network); + } else if (network.getTrafficType() == TrafficType.Public) { + publicNics.put(routerNic, network); + } + } + + try { + //add VPC router to public and guest networks + for (Nic publicNic : publicNics.keySet()) { + Network publicNtwk = publicNics.get(publicNic); + IPAddressVO userIp = _ipAddressDao.findByIpAndSourceNetworkId(publicNtwk.getId(), + publicNic.getIp4Address()); + PublicIp publicIp = new PublicIp(userIp, _vlanDao.findById(userIp.getVlanId()), + NetUtils.createSequenceBasedMacAddress(userIp.getMacAddress())); + if (!addPublicIpToVpc(router, publicNtwk, publicIp)) { + s_logger.warn("Failed to add router router " + router + " to public network " + publicNtwk); + return false; + } + } + + for (Nic guestNic : guestNics.keySet()) { + Network guestNtwk = guestNics.get(guestNic); + boolean setupDns = _networkMgr.setupDns(guestNtwk, Provider.VPCVirtualRouter); + + if (!addVpcRouterToGuestNetwork(router, guestNtwk, false, setupDns)) { + s_logger.warn("Failed to add router router " + router + " to guest network " + guestNtwk); + return false; + } + } + } catch (Exception ex) { + s_logger.warn("Failed to add router " + router + " to network due to exception ", ex); + return false; + } + + return true; + } + + protected DomainRouterVO deployVpcRouter(Account owner, DeployDestination dest, DeploymentPlan plan, Map params, + boolean isRedundant, VirtualRouterProvider vrProvider, long svcOffId, + Long vpcId, PublicIp sourceNatIp) throws ConcurrentOperationException, + InsufficientAddressCapacityException, InsufficientServerCapacityException, InsufficientCapacityException, + StorageUnavailableException, ResourceUnavailableException { + + DomainRouterVO router = + super.deployRouter(owner, dest, plan, params, isRedundant, vrProvider, svcOffId, vpcId, sourceNatIp, + false, true, null, null); + + //Plug public nic + if (router != null && sourceNatIp != null) { + Network publicNetwork = _networkDao.listByZoneAndTrafficType(dest.getDataCenter().getId(), TrafficType.Public).get(0); + if (!addPublicIpToVpc(router, publicNetwork, sourceNatIp)) { + s_logger.warn("Failed to add router " + router + " to public network in zone " + dest.getDataCenter() + " cleaninig up"); + destroyRouter(router.getId()); + return null; + } + + } + + return router; + } + + @Override + public boolean plugNic(Network network, NicTO nic, VirtualMachineTO vm, + ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException, + InsufficientCapacityException { + boolean result = true; + + try { + PlugNicCommand plugNicCmd = new PlugNicCommand(vm, nic); + + Commands cmds = new Commands(OnError.Stop); + cmds.addCommand("plugnic", plugNicCmd); + _agentMgr.send(dest.getHost().getId(), cmds); + + PlugNicAnswer plugNicAnswer = cmds.getAnswer(PlugNicAnswer.class); + if (!(plugNicAnswer != null && plugNicAnswer.getResult())) { + s_logger.warn("Unable to plug nic for vm " + vm.getHostName()); + result = false; + } + + } catch (OperationTimedoutException e) { + throw new AgentUnavailableException("Unable to plug nic for router " + vm.getHostName() + " in network " + network, + dest.getHost().getId(), e); + } + + return result; + } + + @Override + public boolean unplugNic(Network network, NicTO nic, VirtualMachineTO vm, + ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException { + + boolean result = true; + DomainRouterVO router = _routerDao.findById(vm.getId()); + try { + UnPlugNicCommand unplugNicCmd = new UnPlugNicCommand(vm, nic); + Commands cmds = new Commands(OnError.Stop); + cmds.addCommand("unplugnic", unplugNicCmd); + _agentMgr.send(dest.getHost().getId(), cmds); + + UnPlugNicAnswer unplugNicAnswer = cmds.getAnswer(UnPlugNicAnswer.class); + if (!(unplugNicAnswer != null && unplugNicAnswer.getResult())) { + s_logger.warn("Unable to unplug nic from router " + router); + result = false; + } + + } catch (OperationTimedoutException e) { + throw new AgentUnavailableException("Unable to unplug nic from rotuer " + router + " from network " + network, + dest.getHost().getId(), e); + } + + return result; + } + + protected boolean setupVpcGuestNetwork(Network network, VirtualRouter router, boolean add, boolean isRedundant, + NicProfile guestNic, boolean setupDns) + throws ConcurrentOperationException, ResourceUnavailableException{ + + String networkDomain = network.getNetworkDomain(); + String dhcpRange = getGuestDhcpRange(guestNic, network, _configMgr.getZone(network.getDataCenterId())); + + boolean result = true; + + Nic nic = _nicDao.findByInstanceIdAndNetworkId(network.getId(), router.getId()); + long guestVlanTag = Long.parseLong(nic.getBroadcastUri().getHost()); + + String brd = NetUtils.long2Ip(NetUtils.ip2Long(guestNic.getIp4Address()) | ~NetUtils.ip2Long(guestNic.getNetmask())); + Integer priority = null; + if (isRedundant) { + List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); + try { + getUpdatedPriority(network, routers, _routerDao.findById(router.getId())); + } catch (InsufficientVirtualNetworkCapcityException e) { + s_logger.error("Failed to get update priority!", e); + throw new CloudRuntimeException("Failed to get update priority!"); + } + } + + String defaultDns1 = null; + String defaultDns2 = null; + + if (setupDns) { + defaultDns1 = guestNic.getDns1(); + defaultDns2 = guestNic.getDns2(); + } + + NicProfile nicProfile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), + _networkMgr.getNetworkRate(network.getId(), router.getId()), + _networkMgr.isSecurityGroupSupportedInNetwork(network), _networkMgr.getNetworkTag(router.getHypervisorType(), network)); + + SetupGuestNetworkCommand setupCmd = new SetupGuestNetworkCommand(dhcpRange, networkDomain, isRedundant, priority, + defaultDns1, defaultDns2, add, _itMgr.toNicTO(nicProfile, router.getHypervisorType())); + setupCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); + setupCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(network.getId(), router.getId())); + setupCmd.setAccessDetail(NetworkElementCommand.GUEST_VLAN_TAG, String.valueOf(guestVlanTag)); + setupCmd.setAccessDetail(NetworkElementCommand.GUEST_NETWORK_GATEWAY, network.getGateway()); + setupCmd.setAccessDetail(NetworkElementCommand.GUEST_BRIDGE, brd); + setupCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + + Commands cmds = new Commands(OnError.Stop); + cmds.addCommand("setupguestnetwork", setupCmd); + sendCommandsToRouter(router, cmds); + + SetupGuestNetworkAnswer setupAnswer = cmds.getAnswer(SetupGuestNetworkAnswer.class); + String setup = add ? "set" : "destroy"; + if (!(setupAnswer != null && setupAnswer.getResult())) { + s_logger.warn("Unable to " + setup + " guest network on router " + router); + result = false; + } + + return result; + } + + private void createVpcAssociateIPCommands(final VirtualRouter router, final List ips, + Commands cmds, long vmId) { + + Pair sourceNatIpAdd = null; + Boolean addSourceNat = null; + // Ensure that in multiple vlans case we first send all ip addresses of vlan1, then all ip addresses of vlan2, etc.. + Map> vlanIpMap = new HashMap>(); + for (final PublicIpAddress ipAddress : ips) { + String vlanTag = ipAddress.getVlanTag(); + ArrayList ipList = vlanIpMap.get(vlanTag); + if (ipList == null) { + ipList = new ArrayList(); + } + //VR doesn't support release for sourceNat IP address; so reset the state + if (ipAddress.isSourceNat() && ipAddress.getState() == IpAddress.State.Releasing) { + ipAddress.setState(IpAddress.State.Allocated); + } + ipList.add(ipAddress); + vlanIpMap.put(vlanTag, ipList); + } + + for (Map.Entry> vlanAndIp : vlanIpMap.entrySet()) { + List ipAddrList = vlanAndIp.getValue(); + + // Get network rate - required for IpAssoc + Integer networkRate = _networkMgr.getNetworkRate(ipAddrList.get(0).getNetworkId(), router.getId()); + Network network = _networkMgr.getNetwork(ipAddrList.get(0).getNetworkId()); + + IpAddressTO[] ipsToSend = new IpAddressTO[ipAddrList.size()]; + int i = 0; + + for (final PublicIpAddress ipAddr : ipAddrList) { + boolean add = (ipAddr.getState() == IpAddress.State.Releasing ? false : true); + + IpAddressTO ip = new IpAddressTO(ipAddr.getAccountId(), ipAddr.getAddress().addr(), add, false, + ipAddr.isSourceNat(), ipAddr.getVlanTag(), ipAddr.getGateway(), ipAddr.getNetmask(), ipAddr.getMacAddress(), + null, networkRate, ipAddr.isOneToOneNat()); + + ip.setTrafficType(network.getTrafficType()); + ip.setNetworkName(_networkMgr.getNetworkTag(router.getHypervisorType(), network)); + ipsToSend[i++] = ip; + if (ipAddr.isSourceNat()) { + sourceNatIpAdd = new Pair(ip, ipAddr.getNetworkId()); + addSourceNat = add; + } + } + IpAssocVpcCommand cmd = new IpAssocVpcCommand(ipsToSend); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(ipAddrList.get(0).getNetworkId(), router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); + cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); + + cmds.addCommand("IPAssocVpcCommand", cmd); + } + + //set source nat ip + if (sourceNatIpAdd != null) { + IpAddressTO sourceNatIp = sourceNatIpAdd.first(); + Long networkId = sourceNatIpAdd.second(); + SetSourceNatCommand cmd = new SetSourceNatCommand(sourceNatIp, addSourceNat); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(networkId, router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn()); + cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); + cmds.addCommand("SetSourceNatCommand", cmd); + } + } + + @Override + public boolean associateIP(Network network, final List ipAddress, List routers) + throws ResourceUnavailableException { + if (ipAddress == null || ipAddress.isEmpty()) { + s_logger.debug("No ip association rules to be applied for network " + network.getId()); + return true; + } + + //1) check which nics need to be plugged and plug them + for (PublicIpAddress ip : ipAddress) { + for (VirtualRouter router : routers) { + URI broadcastUri = BroadcastDomainType.Vlan.toUri(ip.getVlanTag()); + Nic nic = _nicDao.findByInstanceIdNetworkIdAndBroadcastUri(network.getId(), router.getId(), + broadcastUri.toString()); + if (nic != null) { + //have to plug the nic(s) + NicProfile defaultNic = new NicProfile(); + if (ip.isSourceNat()) { + defaultNic.setDefaultNic(true); + } + defaultNic.setIp4Address(ip.getAddress().addr()); + defaultNic.setGateway(ip.getGateway()); + defaultNic.setNetmask(ip.getNetmask()); + defaultNic.setMacAddress(ip.getMacAddress()); + defaultNic.setBroadcastType(BroadcastDomainType.Vlan); + defaultNic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ip.getVlanTag())); + defaultNic.setIsolationUri(IsolationType.Vlan.toUri(ip.getVlanTag())); + + NicProfile publicNic = null; + Network publicNtwk = null; + try { + publicNtwk = _networkMgr.getNetwork(ip.getNetworkId()); + publicNic = _itMgr.addVmToNetwork(router, publicNtwk, defaultNic); + } catch (ConcurrentOperationException e) { + s_logger.warn("Failed to add router " + router + " to vlan " + ip.getVlanTag() + + " in public network " + publicNtwk + " due to ", e); + } catch (InsufficientCapacityException e) { + s_logger.warn("Failed to add router " + router + " to vlan " + ip.getVlanTag() + + " in public network " + publicNtwk + " due to ", e); + } finally { + if (publicNic == null) { + s_logger.warn("Failed to add router " + router + " to vlan " + ip.getVlanTag() + + " in public network " + publicNtwk); + return false; + } + } + } + } + } + + //2) apply the ips + return applyRules(network, routers, "vpc ip association", false, null, false, new RuleApplier() { + @Override + public boolean execute(Network network, VirtualRouter router) throws ResourceUnavailableException { + Commands cmds = new Commands(OnError.Continue); + createVpcAssociateIPCommands(router, ipAddress, cmds, 0); + return sendCommandsToRouter(router, cmds); + } + }); + } + + +// @Override +// public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, +// ReservationContext context) { +// //remove public and guest nics as we will plug them later +// Iterator it = profile.getNics().iterator(); +// while (it.hasNext()) { +// NicProfile nic = it.next(); +// if (nic.getTrafficType() == TrafficType.Public || nic.getTrafficType() == TrafficType.Guest) { +// s_logger.debug("Removing nic of type " + nic.getTrafficType() + " from the nics passed on vm start. " + +// "The nic will be plugged later"); +// it.remove(); +// } +// } +// +// return super.finalizeVirtualMachineProfile(profile, dest, context); +// } +} diff --git a/server/src/com/cloud/network/rules/FirewallManager.java b/server/src/com/cloud/network/rules/FirewallManager.java index 2de4d062087..58e8750500b 100644 --- a/server/src/com/cloud/network/rules/FirewallManager.java +++ b/server/src/com/cloud/network/rules/FirewallManager.java @@ -67,10 +67,10 @@ public interface FirewallManager extends FirewallService { boolean revokeFirewallRule(long ruleId, boolean apply, Account caller, long userId); FirewallRule createFirewallRule(long ipAddrId, Account caller, String xId, Integer portStart, Integer portEnd, String protocol, List sourceCidrList, Integer icmpCode, Integer icmpType, Long relatedRuleId, - FirewallRule.FirewallRuleType type) + FirewallRule.FirewallRuleType type, long networkId) throws NetworkRuleConflictException; - FirewallRule createRuleForAllCidrs(long ipAddrId, Account caller, Integer startPort, Integer endPort, String protocol, Integer icmpCode, Integer icmpType, Long relatedRuleId) throws NetworkRuleConflictException; + FirewallRule createRuleForAllCidrs(long ipAddrId, Account caller, Integer startPort, Integer endPort, String protocol, Integer icmpCode, Integer icmpType, Long relatedRuleId, long networkId) throws NetworkRuleConflictException; boolean revokeAllFirewallRulesForNetwork(long networkId, long userId, Account caller) throws ResourceUnavailableException; diff --git a/server/src/com/cloud/network/rules/RulesManagerImpl.java b/server/src/com/cloud/network/rules/RulesManagerImpl.java index eeed00118fb..4f48f4f7dd7 100755 --- a/server/src/com/cloud/network/rules/RulesManagerImpl.java +++ b/server/src/com/cloud/network/rules/RulesManagerImpl.java @@ -154,7 +154,8 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { @Override @DB @ActionEvent(eventType = EventTypes.EVENT_NET_RULE_ADD, eventDescription = "creating forwarding rule", create = true) - public PortForwardingRule createPortForwardingRule(PortForwardingRule rule, Long vmId, boolean openFirewall) throws NetworkRuleConflictException { + public PortForwardingRule createPortForwardingRule(PortForwardingRule rule, Long vmId, boolean openFirewall) + throws NetworkRuleConflictException { UserContext ctx = UserContext.current(); Account caller = ctx.getCaller(); @@ -169,9 +170,24 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { throw new InvalidParameterValueException("Unable to create port forwarding rule; ip id=" + ipAddrId + " has static nat enabled"); } - _firewallMgr.validateFirewallRule(caller, ipAddress, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), Purpose.PortForwarding, FirewallRuleType.User); + Long networkId = rule.getNetworkId(); + //associate ip address to network (if needed) + if (ipAddress.getAssociatedWithNetworkId() == null) { + s_logger.debug("The ip is not associated with the network id="+ networkId + " so assigning"); + try { + _networkMgr.associateIPToGuestNetwork(ipAddrId, networkId); + } catch (Exception ex) { + s_logger.warn("Failed to associate ip id=" + ipAddrId + " to network id=" + networkId + " as " + + "a part of port forwarding rule creation"); + return null; + } + } + + _networkMgr.checkIpForService(ipAddress, Service.PortForwarding); + + _firewallMgr.validateFirewallRule(caller, ipAddress, rule.getSourcePortStart(), rule.getSourcePortEnd(), + rule.getProtocol(), Purpose.PortForwarding, FirewallRuleType.User); - Long networkId = ipAddress.getAssociatedWithNetworkId(); Long accountId = ipAddress.getAllocatedToAccountId(); Long domainId = ipAddress.getAllocatedInDomainId(); @@ -188,12 +204,12 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { // validate user VM exists UserVm vm = _vmDao.findById(vmId); if (vm == null) { - throw new InvalidParameterValueException("Unable to create port forwarding rule on address " + ipAddress + ", invalid virtual machine id specified (" + vmId + ")."); + throw new InvalidParameterValueException("Unable to create port forwarding rule on address " + ipAddress + + ", invalid virtual machine id specified (" + vmId + ")."); } else { checkRuleAndUserVm(rule, vm, caller); } - _networkMgr.checkIpForService(ipAddress, Service.PortForwarding); // Verify that vm has nic in the network Ip dstIp = rule.getDestinationIpAddress(); @@ -207,13 +223,15 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { Transaction txn = Transaction.currentTxn(); txn.start(); - PortForwardingRuleVO newRule = new PortForwardingRuleVO(rule.getXid(), rule.getSourceIpAddressId(), rule.getSourcePortStart(), rule.getSourcePortEnd(), dstIp, rule.getDestinationPortStart(), + PortForwardingRuleVO newRule = new PortForwardingRuleVO(rule.getXid(), rule.getSourceIpAddressId(), + rule.getSourcePortStart(), rule.getSourcePortEnd(), dstIp, rule.getDestinationPortStart(), rule.getDestinationPortEnd(), rule.getProtocol().toLowerCase(), networkId, accountId, domainId, vmId); newRule = _portForwardingDao.persist(newRule); // create firewallRule for 0.0.0.0/0 cidr if (openFirewall) { - _firewallMgr.createRuleForAllCidrs(ipAddrId, caller, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), null, null, newRule.getId()); + _firewallMgr.createRuleForAllCidrs(ipAddrId, caller, rule.getSourcePortStart(), rule.getSourcePortEnd(), + rule.getProtocol(), null, null, newRule.getId(), networkId); } try { @@ -222,19 +240,17 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { throw new CloudRuntimeException("Unable to update the state to add for " + newRule); } UserContext.current().setEventDetails("Rule Id: " + newRule.getId()); - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NET_RULE_ADD, newRule.getAccountId(), ipAddress.getDataCenterId(), newRule.getId(), null); + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NET_RULE_ADD, newRule.getAccountId(), + ipAddress.getDataCenterId(), newRule.getId(), null); _usageEventDao.persist(usageEvent); txn.commit(); return newRule; } catch (Exception e) { - if (newRule != null) { - txn.start(); // no need to apply the rule as it wasn't programmed on the backend yet _firewallMgr.revokeRelatedFirewallRule(newRule.getId(), false); _portForwardingDao.remove(newRule.getId()); - txn.commit(); } @@ -288,7 +304,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { // create firewallRule for 0.0.0.0/0 cidr if (openFirewall) { - _firewallMgr.createRuleForAllCidrs(ipAddrId, caller, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), null, null, newRule.getId()); + _firewallMgr.createRuleForAllCidrs(ipAddrId, caller, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), null, null, newRule.getId(), networkId); } try { @@ -322,31 +338,45 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { } @Override - public boolean enableStaticNat(long ipId, long vmId, boolean isSystemVm) throws NetworkRuleConflictException, ResourceUnavailableException { + public boolean enableStaticNat(long ipId, long vmId, long networkId, boolean isSystemVm) + throws NetworkRuleConflictException, ResourceUnavailableException { UserContext ctx = UserContext.current(); Account caller = ctx.getCaller(); + // Verify input parameters + UserVmVO vm = _vmDao.findById(vmId); + if (vm == null) { + throw new InvalidParameterValueException("Can't enable static nat for the address id=" + ipId + + ", invalid virtual machine id specified (" + vmId + ")."); + } + IPAddressVO ipAddress = _ipAddressDao.findById(ipId); if (ipAddress == null) { throw new InvalidParameterValueException("Unable to find ip address by id " + ipId); } // Verify input parameters + boolean setNetworkId = false; if (!isSystemVm) { - UserVmVO vm = _vmDao.findById(vmId); - if (vm == null) { - throw new InvalidParameterValueException("Can't enable static nat for the address id=" + ipId + ", invalid virtual machine id specified (" + vmId + ")."); + //associate ip address to network (if needed) + if (ipAddress.getAssociatedWithNetworkId() == null) { + s_logger.debug("The ip is not associated with the network id="+ networkId + " so assigning"); + try { + _networkMgr.associateIPToGuestNetwork(ipId, networkId); + } catch (Exception ex) { + s_logger.warn("Failed to associate ip id=" + ipId + " to network id=" + networkId + " as " + + "a part of enable static nat"); + return false; } + setNetworkId = true; + } + + _networkMgr.checkIpForService(ipAddress, Service.StaticNat); + // Check permissions checkIpAndUserVm(ipAddress, vm, caller); } - // Verify that the ip is associated with the network and static nat service is supported for the network - Long networkId = ipAddress.getAssociatedWithNetworkId(); - if (networkId == null) { - throw new InvalidParameterValueException("Unable to enable static nat for the ipAddress id=" + ipId + " as ip is not associated with any network"); - } - // Check that vm has a nic in the network Nic guestNic = _networkMgr.getNicInNetwork(vmId, networkId); if (guestNic == null) { @@ -355,14 +385,12 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { Network network = _networkMgr.getNetwork(networkId); if (!_networkMgr.areServicesSupportedInNetwork(network.getId(), Service.StaticNat)) { - throw new InvalidParameterValueException("Unable to create static nat rule; StaticNat service is not supported in network id=" + networkId); + throw new InvalidParameterValueException("Unable to create static nat rule; StaticNat service is not " + + "supported in network id=" + networkId); } // Verify ip address parameter isIpReadyForStaticNat(vmId, ipAddress, caller, ctx.getCallerUserId()); - - _networkMgr.checkIpForService(ipAddress, Service.StaticNat); - ipAddress.setOneToOneNat(true); ipAddress.setAssociatedWithVmId(vmId); @@ -374,6 +402,9 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { } else { ipAddress.setOneToOneNat(false); ipAddress.setAssociatedWithVmId(null); + if (setNetworkId) { + ipAddress.setAssociatedWithNetworkId(null); + } _ipAddressDao.update(ipAddress.getId(), ipAddress); s_logger.warn("Failed to enable static nat rule for ip address " + ipId + " on the backend"); return false; @@ -384,7 +415,8 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { } } - protected void isIpReadyForStaticNat(long vmId, IPAddressVO ipAddress, Account caller, long callerUserId) throws NetworkRuleConflictException, ResourceUnavailableException { + protected void isIpReadyForStaticNat(long vmId, IPAddressVO ipAddress, Account caller, long callerUserId) + throws NetworkRuleConflictException, ResourceUnavailableException { if (ipAddress.isSourceNat()) { throw new InvalidParameterValueException("Can't enable static, ip address " + ipAddress + " is a sourceNat ip address"); } @@ -957,7 +989,8 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { @Override @DB - public FirewallRuleVO[] reservePorts(IpAddress ip, String protocol, FirewallRule.Purpose purpose, boolean openFirewall, Account caller, int... ports) throws NetworkRuleConflictException { + public FirewallRuleVO[] reservePorts(IpAddress ip, String protocol, FirewallRule.Purpose purpose, + boolean openFirewall, Account caller, int... ports) throws NetworkRuleConflictException { FirewallRuleVO[] rules = new FirewallRuleVO[ports.length]; Transaction txn = Transaction.currentTxn(); @@ -968,7 +1001,8 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { rules[i] = _firewallDao.persist(rules[i]); if (openFirewall) { - _firewallMgr.createRuleForAllCidrs(ip.getId(), caller, ports[i], ports[i], protocol, null, null, rules[i].getId()); + _firewallMgr.createRuleForAllCidrs(ip.getId(), caller, ports[i], ports[i], protocol, null, null, + rules[i].getId(), ip.getAssociatedWithNetworkId()); } } txn.commit(); @@ -1035,8 +1069,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { } // if network has elastic IP functionality supported, we first have to disable static nat on old ip in order to -// re-enable it on the new one - // enable static nat takes care of that + // re-enable it on the new one enable static nat takes care of that Network guestNetwork = _networkMgr.getNetwork(ipAddress.getAssociatedWithNetworkId()); NetworkOffering offering = _configMgr.getNetworkOffering(guestNetwork.getNetworkOfferingId()); if (offering.getElasticIp()) { @@ -1077,14 +1110,17 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { } if (success) { + Transaction txn = Transaction.currentTxn(); + txn.start(); boolean isIpSystem = ipAddress.getSystem(); - ipAddress.setOneToOneNat(false); ipAddress.setAssociatedWithVmId(null); if (isIpSystem && !releaseIpIfElastic) { ipAddress.setSystem(false); } _ipAddressDao.update(ipAddress.getId(), ipAddress); + _networkMgr.unassignIPFromVpcNetwork(ipAddress.getId()); + txn.commit(); if (isIpSystem && releaseIpIfElastic && !_networkMgr.handleSystemIpRelease(ipAddress)) { s_logger.warn("Failed to release system ip address " + ipAddress); @@ -1163,7 +1199,8 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { dstIp = _networkMgr.getIpInNetwork(sourceIp.getAssociatedWithVmId(), networkId); } - StaticNatImpl staticNat = new StaticNatImpl(sourceIp.getAllocatedToAccountId(), sourceIp.getAllocatedInDomainId(), networkId, sourceIpId, dstIp, forRevoke); + StaticNatImpl staticNat = new StaticNatImpl(sourceIp.getAllocatedToAccountId(), sourceIp.getAllocatedInDomainId(), + networkId, sourceIpId, dstIp, forRevoke); staticNats.add(staticNat); try { @@ -1205,12 +1242,14 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { boolean isSystemVM = (vm.getType() == Type.ConsoleProxy || vm.getType() == Type.SecondaryStorageVm); try { - success = enableStaticNat(ip.getId(), vm.getId(), isSystemVM); + success = enableStaticNat(ip.getId(), vm.getId(), guestNetwork.getId(), isSystemVM); } catch (NetworkRuleConflictException ex) { - s_logger.warn("Failed to enable static nat as a part of enabling elasticIp and staticNat for vm " + vm + " in guest network " + guestNetwork + " due to exception ", ex); + s_logger.warn("Failed to enable static nat as a part of enabling elasticIp and staticNat for vm " + + vm + " in guest network " + guestNetwork + " due to exception ", ex); success = false; } catch (ResourceUnavailableException ex) { - s_logger.warn("Failed to enable static nat as a part of enabling elasticIp and staticNat for vm " + vm + " in guest network " + guestNetwork + " due to exception ", ex); + s_logger.warn("Failed to enable static nat as a part of enabling elasticIp and staticNat for vm " + + vm + " in guest network " + guestNetwork + " due to exception ", ex); success = false; } @@ -1224,5 +1263,4 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { } } } - } diff --git a/server/src/com/cloud/network/vpc/Dao/PrivateIpDao.java b/server/src/com/cloud/network/vpc/Dao/PrivateIpDao.java new file mode 100644 index 00000000000..226b8b1269d --- /dev/null +++ b/server/src/com/cloud/network/vpc/Dao/PrivateIpDao.java @@ -0,0 +1,62 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc.Dao; + +import java.util.List; + +import com.cloud.network.vpc.PrivateIpVO; +import com.cloud.utils.db.GenericDao; + +/** + * @author Alena Prokharchyk + */ +public interface PrivateIpDao extends GenericDao{ + + /** + * @param dcId + * @param networkId + * @return + */ + PrivateIpVO allocateIpAddress(long dcId, long networkId); + + /** + * @param ipAddress + * @param networkId + */ + void releaseIpAddress(String ipAddress, long networkId); + + /** + * @param networkId + * @param ip4Address + * @return + */ + PrivateIpVO findByIpAndSourceNetworkId(long networkId, String ip4Address); + + /** + * @param networkId + * @return + */ + List listByNetworkId(long networkId); + + /** + * @param ntwkId + * @return + */ + int countAllocatedByNetworkId(long ntwkId); + + /** + * @param networkId + */ + void deleteByNetworkId(long networkId); + +} diff --git a/server/src/com/cloud/network/vpc/Dao/PrivateIpDaoImpl.java b/server/src/com/cloud/network/vpc/Dao/PrivateIpDaoImpl.java new file mode 100644 index 00000000000..a9d945663e4 --- /dev/null +++ b/server/src/com/cloud/network/vpc/Dao/PrivateIpDaoImpl.java @@ -0,0 +1,129 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc.Dao; + +import java.util.Date; +import java.util.List; + +import javax.ejb.Local; + +import org.apache.log4j.Logger; + +import com.cloud.network.vpc.PrivateIpVO; +import com.cloud.utils.db.DB; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.GenericSearchBuilder; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.SearchCriteria.Func; +import com.cloud.utils.db.SearchCriteria.Op; +import com.cloud.utils.db.Transaction; + +/** + * @author Alena Prokharchyk + */ + +@Local(value = PrivateIpDao.class) +@DB(txn = false) +public class PrivateIpDaoImpl extends GenericDaoBase implements PrivateIpDao { + private static final Logger s_logger = Logger.getLogger(PrivateIpDaoImpl.class); + + private final SearchBuilder AllFieldsSearch; + private final GenericSearchBuilder CountAllocatedByNetworkId; + + + protected PrivateIpDaoImpl() { + super(); + + AllFieldsSearch = createSearchBuilder(); + AllFieldsSearch.and("ip", AllFieldsSearch.entity().getIpAddress(), SearchCriteria.Op.EQ); + AllFieldsSearch.and("networkId", AllFieldsSearch.entity().getNetworkId(), SearchCriteria.Op.EQ); + AllFieldsSearch.and("ipAddress", AllFieldsSearch.entity().getIpAddress(), SearchCriteria.Op.EQ); + AllFieldsSearch.and("taken", AllFieldsSearch.entity().getTakenAt(), SearchCriteria.Op.EQ); + AllFieldsSearch.done(); + + CountAllocatedByNetworkId = createSearchBuilder(Integer.class); + CountAllocatedByNetworkId.select(null, Func.COUNT, CountAllocatedByNetworkId.entity().getId()); + CountAllocatedByNetworkId.and("networkId", CountAllocatedByNetworkId.entity().getNetworkId(), Op.EQ); + CountAllocatedByNetworkId.and("taken", CountAllocatedByNetworkId.entity().getTakenAt(), Op.NNULL); + CountAllocatedByNetworkId.done(); + } + + @Override + public PrivateIpVO allocateIpAddress(long dcId, long networkId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("networkId", networkId); + sc.setParameters("taken", (Date)null); + + Transaction txn = Transaction.currentTxn(); + txn.start(); + PrivateIpVO vo = lockOneRandomRow(sc, true); + if (vo == null) { + txn.rollback(); + return null; + } + vo.setTakenAt(new Date()); + update(vo.getId(), vo); + txn.commit(); + return vo; + } + + @Override + public void releaseIpAddress(String ipAddress, long networkId) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Releasing private ip address: " + ipAddress + " network id " + networkId); + } + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("ip", ipAddress); + sc.setParameters("networkId", networkId); + + PrivateIpVO vo = createForUpdate(); + + vo.setTakenAt(null); + update(vo, sc); + } + + /* (non-Javadoc) + * @see com.cloud.network.vpc.Dao.PrivateIpDao#findByIpAndSourceNetworkId(long, java.lang.String) + */ + @Override + public PrivateIpVO findByIpAndSourceNetworkId(long networkId, String ip4Address) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("ip", ip4Address); + sc.setParameters("networkId", networkId); + return findOneBy(sc); + } + + @Override + public List listByNetworkId(long networkId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("networkId", networkId); + return listBy(sc); + } + + @Override + public int countAllocatedByNetworkId(long ntwkId) { + SearchCriteria sc = CountAllocatedByNetworkId.create(); + sc.setParameters("networkId", ntwkId); + List results = customSearch(sc, null); + return results.get(0); + } + + + @Override + public void deleteByNetworkId(long networkId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("networkId", networkId); + remove(sc); + } +} diff --git a/server/src/com/cloud/network/vpc/Dao/VpcDao.java b/server/src/com/cloud/network/vpc/Dao/VpcDao.java new file mode 100644 index 00000000000..75fd56e88b7 --- /dev/null +++ b/server/src/com/cloud/network/vpc/Dao/VpcDao.java @@ -0,0 +1,36 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc.Dao; + +import java.util.List; + +import com.cloud.network.vpc.Vpc; +import com.cloud.network.vpc.VpcVO; +import com.cloud.utils.db.GenericDao; + +/** + * @author Alena Prokharchyk + */ +public interface VpcDao extends GenericDao{ + + /** + * @param offId + * @return + */ + int getVpcCountByOfferingId(long offId); + + Vpc getActiveVpcById(long vpcId); + + List listByAccountId(long accountId); + +} diff --git a/server/src/com/cloud/network/vpc/Dao/VpcDaoImpl.java b/server/src/com/cloud/network/vpc/Dao/VpcDaoImpl.java new file mode 100644 index 00000000000..6d6b03c220b --- /dev/null +++ b/server/src/com/cloud/network/vpc/Dao/VpcDaoImpl.java @@ -0,0 +1,80 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc.Dao; + +import java.util.List; + +import javax.ejb.Local; + +import com.cloud.domain.Domain.State; +import com.cloud.network.vpc.Vpc; +import com.cloud.network.vpc.VpcVO; +import com.cloud.utils.db.DB; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.GenericSearchBuilder; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.SearchCriteria.Func; +import com.cloud.utils.db.SearchCriteria.Op; + +/** + * @author Alena Prokharchyk + */ + +@Local(value = VpcDao.class) +@DB(txn = false) +public class VpcDaoImpl extends GenericDaoBase implements VpcDao{ + final GenericSearchBuilder CountByOfferingId; + final SearchBuilder AllFieldsSearch; + + protected VpcDaoImpl() { + super(); + + CountByOfferingId = createSearchBuilder(Integer.class); + CountByOfferingId.select(null, Func.COUNT, CountByOfferingId.entity().getId()); + CountByOfferingId.and("offeringId", CountByOfferingId.entity().getVpcOfferingId(), Op.EQ); + CountByOfferingId.and("removed", CountByOfferingId.entity().getRemoved(), Op.NULL); + CountByOfferingId.done(); + + AllFieldsSearch = createSearchBuilder(); + AllFieldsSearch.and("id", AllFieldsSearch.entity().getId(), Op.EQ); + AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), Op.EQ); + AllFieldsSearch.and("accountId", AllFieldsSearch.entity().getAccountId(), Op.EQ); + AllFieldsSearch.done(); + } + + + @Override + public int getVpcCountByOfferingId(long offId) { + SearchCriteria sc = CountByOfferingId.create(); + sc.setParameters("offeringId", offId); + List results = customSearch(sc, null); + return results.get(0); + } + + @Override + public Vpc getActiveVpcById(long vpcId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("id", vpcId); + sc.setParameters("state", State.Active); + return findOneBy(sc); + } + + @Override + public List listByAccountId(long accountId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("accountId", accountId); + return listBy(sc, null); + } +} + diff --git a/server/src/com/cloud/network/vpc/Dao/VpcGatewayDao.java b/server/src/com/cloud/network/vpc/Dao/VpcGatewayDao.java new file mode 100644 index 00000000000..8e9a72b214a --- /dev/null +++ b/server/src/com/cloud/network/vpc/Dao/VpcGatewayDao.java @@ -0,0 +1,23 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc.Dao; + +import com.cloud.network.vpc.VpcGatewayVO; +import com.cloud.utils.db.GenericDao; + +/** + * @author Alena Prokharchyk + */ +public interface VpcGatewayDao extends GenericDao{ + +} diff --git a/server/src/com/cloud/network/vpc/Dao/VpcOfferingDao.java b/server/src/com/cloud/network/vpc/Dao/VpcOfferingDao.java new file mode 100644 index 00000000000..b5c8b47933d --- /dev/null +++ b/server/src/com/cloud/network/vpc/Dao/VpcOfferingDao.java @@ -0,0 +1,30 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc.Dao; + +import com.cloud.network.vpc.VpcOfferingVO; +import com.cloud.utils.db.GenericDao; + +/** + * @author Alena Prokharchyk + */ +public interface VpcOfferingDao extends GenericDao{ + /** + * Returns the VPC offering that matches the unique name. + * + * @param uniqueName + * name + * @return VpcOfferingVO + */ + VpcOfferingVO findByUniqueName(String uniqueName); +} diff --git a/server/src/com/cloud/network/vpc/Dao/VpcOfferingDaoImpl.java b/server/src/com/cloud/network/vpc/Dao/VpcOfferingDaoImpl.java new file mode 100644 index 00000000000..b5e6c6ede8a --- /dev/null +++ b/server/src/com/cloud/network/vpc/Dao/VpcOfferingDaoImpl.java @@ -0,0 +1,68 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc.Dao; + +import javax.ejb.Local; + +import com.cloud.network.vpc.VpcOfferingVO; +import com.cloud.utils.db.DB; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.SearchCriteria.Op; +import com.cloud.utils.db.Transaction; + +/** + * @author Alena Prokharchyk + */ +@Local(value = VpcOfferingDao.class) +@DB(txn = false) +public class VpcOfferingDaoImpl extends GenericDaoBase implements VpcOfferingDao{ + final SearchBuilder AllFieldsSearch; + + + protected VpcOfferingDaoImpl() { + super(); + + AllFieldsSearch = createSearchBuilder(); + AllFieldsSearch.and("id", AllFieldsSearch.entity().getId(), Op.EQ); + AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), Op.EQ); + AllFieldsSearch.and("name", AllFieldsSearch.entity().getName(), Op.EQ); + AllFieldsSearch.and("uName", AllFieldsSearch.entity().getUniqueName(), Op.EQ); + AllFieldsSearch.and("displayText", AllFieldsSearch.entity().getDisplayText(), Op.EQ); + AllFieldsSearch.and("svcOffId", AllFieldsSearch.entity().getServiceOfferingId(), Op.EQ); + AllFieldsSearch.done(); + + } + + @Override + @DB + public boolean remove(Long vpcOffId) { + Transaction txn = Transaction.currentTxn(); + txn.start(); + VpcOfferingVO offering = findById(vpcOffId); + offering.setUniqueName(null); + update(vpcOffId, offering); + boolean result = super.remove(vpcOffId); + txn.commit(); + return result; + } + + + @Override + public VpcOfferingVO findByUniqueName(String uniqueName) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("uName", uniqueName); + return findOneBy(sc); + } +} diff --git a/server/src/com/cloud/network/vpc/Dao/VpcOfferingServiceMapDao.java b/server/src/com/cloud/network/vpc/Dao/VpcOfferingServiceMapDao.java new file mode 100644 index 00000000000..74246aef67e --- /dev/null +++ b/server/src/com/cloud/network/vpc/Dao/VpcOfferingServiceMapDao.java @@ -0,0 +1,34 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc.Dao; + +import java.util.List; + +import com.cloud.network.Network.Service; +import com.cloud.network.vpc.VpcOfferingServiceMapVO; +import com.cloud.utils.db.GenericDao; + +/** + * @author Alena Prokharchyk + */ +public interface VpcOfferingServiceMapDao extends GenericDao{ + + List listByVpcOffId(long vpcOffId); + + /** + * @param networkOfferingId + * @param services + * @return + */ + boolean areServicesSupportedByNetworkOffering(long networkOfferingId, Service[] services); +} diff --git a/server/src/com/cloud/network/vpc/Dao/VpcOfferingServiceMapDaoImpl.java b/server/src/com/cloud/network/vpc/Dao/VpcOfferingServiceMapDaoImpl.java new file mode 100644 index 00000000000..cbbf1d5e43e --- /dev/null +++ b/server/src/com/cloud/network/vpc/Dao/VpcOfferingServiceMapDaoImpl.java @@ -0,0 +1,90 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc.Dao; + +import java.util.List; + +import javax.ejb.Local; + +import com.cloud.network.Network.Service; +import com.cloud.network.vpc.VpcOfferingServiceMapVO; +import com.cloud.offerings.NetworkOfferingServiceMapVO; +import com.cloud.utils.db.DB; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; + +/** + * @author Alena Prokharchyk + */ +@Local(value = VpcOfferingServiceMapDao.class) +@DB(txn = false) +public class VpcOfferingServiceMapDaoImpl extends GenericDaoBase implements VpcOfferingServiceMapDao{ + final SearchBuilder AllFieldsSearch; + final SearchBuilder MultipleServicesSearch; + + + protected VpcOfferingServiceMapDaoImpl() { + super(); + AllFieldsSearch = createSearchBuilder(); + AllFieldsSearch.and("vpcOffId", AllFieldsSearch.entity().getVpcOfferingId(), SearchCriteria.Op.EQ); + AllFieldsSearch.and("service", AllFieldsSearch.entity().getService(), SearchCriteria.Op.EQ); + AllFieldsSearch.and("provider", AllFieldsSearch.entity().getProvider(), SearchCriteria.Op.EQ); + AllFieldsSearch.done(); + + + MultipleServicesSearch = createSearchBuilder(); + MultipleServicesSearch.and("vpcOffId", MultipleServicesSearch.entity().getVpcOfferingId(), SearchCriteria.Op.EQ); + MultipleServicesSearch.and("service", MultipleServicesSearch.entity().getService(), SearchCriteria.Op.IN); + MultipleServicesSearch.and("provider", MultipleServicesSearch.entity().getProvider(), SearchCriteria.Op.EQ); + MultipleServicesSearch.done(); + } + + @Override + public List listByVpcOffId(long vpcOffId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("vpcOffId", vpcOffId); + return listBy(sc); + } + + + @Override + public boolean areServicesSupportedByNetworkOffering(long networkOfferingId, Service... services) { + SearchCriteria sc = MultipleServicesSearch.create(); + sc.setParameters("vpcOffId", networkOfferingId); + + if (services != null) { + String[] servicesStr = new String[services.length]; + + int i = 0; + for (Service service : services) { + servicesStr[i] = service.getName(); + i++; + } + + sc.setParameters("service", (Object[])servicesStr); + } + + List offeringServices = listBy(sc); + + if (services != null) { + if (offeringServices.size() == services.length) { + return true; + } + } else if (!offeringServices.isEmpty()) { + return true; + } + + return false; + } +} diff --git a/server/src/com/cloud/network/vpc/PrivateIpVO.java b/server/src/com/cloud/network/vpc/PrivateIpVO.java new file mode 100644 index 00000000000..42df20ce923 --- /dev/null +++ b/server/src/com/cloud/network/vpc/PrivateIpVO.java @@ -0,0 +1,76 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc; + +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +/** + * @author Alena Prokharchyk + */ + +@Entity +@Table(name="private_ip_address") +public class PrivateIpVO { + + @Id + @GeneratedValue(strategy=GenerationType.IDENTITY) + @Column(name="id") + long id; + + @Column(name="ip_address", updatable=false, nullable=false) + String ipAddress; + + @Column(name="taken") + @Temporal(value=TemporalType.TIMESTAMP) + private Date takenAt; + + @Column(name="network_id", updatable=false, nullable=false) + private long networkId; + + public PrivateIpVO() { + } + + public PrivateIpVO(String ipAddress, long networkId) { + this.ipAddress = ipAddress; + this.networkId = networkId; + } + + public void setTakenAt(Date takenDate) { + this.takenAt = takenDate; + } + + public String getIpAddress() { + return ipAddress; + } + + public long getNetworkId() { + return networkId; + } + + public Date getTakenAt() { + return takenAt; + } + + public long getId() { + return id; + } +} diff --git a/server/src/com/cloud/network/vpc/VpcGatewayVO.java b/server/src/com/cloud/network/vpc/VpcGatewayVO.java new file mode 100644 index 00000000000..277c440da53 --- /dev/null +++ b/server/src/com/cloud/network/vpc/VpcGatewayVO.java @@ -0,0 +1,22 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc; + +/** + * @author Alena Prokharchyk + */ +public class VpcGatewayVO { + + public VpcGatewayVO() { + } +} diff --git a/server/src/com/cloud/network/vpc/VpcManager.java b/server/src/com/cloud/network/vpc/VpcManager.java new file mode 100644 index 00000000000..55a607f2779 --- /dev/null +++ b/server/src/com/cloud/network/vpc/VpcManager.java @@ -0,0 +1,99 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.Network.Provider; +import com.cloud.network.Network.Service; +import com.cloud.network.element.VpcProvider; +import com.cloud.network.vpc.VpcOffering.State; +import com.cloud.offering.NetworkOffering; +import com.cloud.user.Account; +import com.cloud.vm.DomainRouterVO; + + +/** + * @author Alena Prokharchyk + */ +public interface VpcManager extends VpcService{ + + /** + * @param name + * @param displayText + * @param svcProviderMap + * @param isDefault + * @param state TODO + * @return + */ + VpcOffering createVpcOffering(String name, String displayText, Map> svcProviderMap, + boolean isDefault, State state); + + /** + * @param vpcOffId + * @param services + * @return + */ + boolean areServicesSupportedByVpcOffering(long vpcOffId, Service[] services); + + /** + * @param zoneId + * @param vpcOffId + * @param vpcOwner + * @param vpcName + * @param displayText + * @param cidr + * @param networkDomain TODO + * @return + */ + Vpc createVpc(long zoneId, long vpcOffId, Account vpcOwner, String vpcName, String displayText, String cidr, String networkDomain); + + List getSupportedServices(); + + /** + * @param guestNtwkOff + * @param cidr + * @param networkDomain + * @param networkOwner + * @param vpc TODO + * @return + * @throws ConcurrentOperationException + */ + void validateGuestNtkwForVpc(NetworkOffering guestNtwkOff, String cidr, String networkDomain, Account networkOwner, + Vpc vpc) throws ConcurrentOperationException; + + /** + * @return + */ + VpcProvider getVpcElement(); + + List getVpcsForAccount(long accountId); + + /** + * @param vpc + * @return + * @throws ConcurrentOperationException + * @throws ResourceUnavailableException + */ + boolean destroyVpc(Vpc vpc) throws ConcurrentOperationException, ResourceUnavailableException; + + /** + * @param vpcId + * @return + */ + List getVpcRouters(long vpcId); +} diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java new file mode 100644 index 00000000000..55e95be2480 --- /dev/null +++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java @@ -0,0 +1,919 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; + +import org.apache.log4j.Logger; + +import com.cloud.configuration.ConfigurationManager; +import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.dc.DataCenter; +import com.cloud.deploy.DeployDestination; +import com.cloud.event.ActionEvent; +import com.cloud.event.EventTypes; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.PermissionDeniedException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.exception.UnsupportedServiceException; +import com.cloud.network.IPAddressVO; +import com.cloud.network.Network; +import com.cloud.network.Network.GuestType; +import com.cloud.network.Network.Provider; +import com.cloud.network.Network.Service; +import com.cloud.network.NetworkManager; +import com.cloud.network.dao.IPAddressDao; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.element.VpcProvider; +import com.cloud.network.vpc.VpcOffering.State; +import com.cloud.network.vpc.Dao.VpcDao; +import com.cloud.network.vpc.Dao.VpcOfferingDao; +import com.cloud.network.vpc.Dao.VpcOfferingServiceMapDao; +import com.cloud.offering.NetworkOffering; +import com.cloud.org.Grouping; +import com.cloud.projects.Project.ListProjectResourcesCriteria; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; +import com.cloud.user.User; +import com.cloud.user.UserContext; +import com.cloud.utils.Ternary; +import com.cloud.utils.component.Inject; +import com.cloud.utils.component.Manager; +import com.cloud.utils.db.DB; +import com.cloud.utils.db.Filter; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.Transaction; +import com.cloud.utils.net.NetUtils; +import com.cloud.vm.DomainRouterVO; +import com.cloud.vm.ReservationContext; +import com.cloud.vm.ReservationContextImpl; +import com.cloud.vm.dao.DomainRouterDao; + +/** + * @author Alena Prokharchyk + */ + +@Local(value = { VpcManager.class, VpcService.class }) +public class VpcManagerImpl implements VpcManager, Manager{ + private static final Logger s_logger = Logger.getLogger(VpcManagerImpl.class); + @Inject + VpcOfferingDao _vpcOffDao; + @Inject + VpcOfferingServiceMapDao _vpcOffSvcMapDao; + @Inject + VpcDao _vpcDao; + @Inject + ConfigurationDao _configDao; + @Inject + ConfigurationManager _configMgr; + @Inject + AccountManager _accountMgr; + @Inject + NetworkDao _ntwkDao; + @Inject + NetworkManager _ntwkMgr; + @Inject + IPAddressDao _ipAddressDao; + @Inject + DomainRouterDao _routerDao; + + private VpcProvider vpcElement = null; + + String _name; + + @Override + @DB + public boolean configure(String name, Map params) throws ConfigurationException { + _name = name; + + //configure default vpc offering + Transaction txn = Transaction.currentTxn(); + txn.start(); + + if (_vpcOffDao.findByUniqueName(VpcOffering.defaultVPCOfferingName) == null) { + s_logger.debug("Creating default VPC offering " + VpcOffering.defaultVPCOfferingName); + + Map> svcProviderMap = new HashMap>(); + Set provider = new HashSet(); + provider.add(Provider.VPCVirtualRouter); + for (Service svc : getSupportedServices()) { + svcProviderMap.put(svc, provider); + } + createVpcOffering(VpcOffering.defaultVPCOfferingName, VpcOffering.defaultVPCOfferingName, svcProviderMap, + true, State.Enabled); + } + + txn.commit(); + + return true; + } + + @Override + public boolean start() { + return true; + } + + @Override + public boolean stop() { + return true; + } + + @Override + public String getName() { + return _name; + } + + @Override + public List getVpcNetworks(long vpcId) { + return _ntwkDao.listByVpc(vpcId); + } + + @Override + public VpcOffering getVpcOffering(long vpcOffId) { + return _vpcOffDao.findById(vpcOffId); + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_VPC_OFFERING_CREATE, eventDescription = "creating vpc offering") + public VpcOffering createVpcOffering(String name, String displayText, List supportedServices) { + Map> svcProviderMap = new HashMap>(); + Set defaultProviders = new HashSet(); + defaultProviders.add(Provider.VPCVirtualRouter); + + boolean sourceNatSvc = false; + boolean firewallSvs = false; + // populate the services first + for (String serviceName : supportedServices) { + // validate if the service is supported + Service service = Network.Service.getService(serviceName); + if (service == null || service == Service.Gateway) { + throw new InvalidParameterValueException("Invalid service " + serviceName); + } + + //don't allow security group service for vpc + if (service == Service.SecurityGroup) { + throw new UnsupportedServiceException("Service " + Service.SecurityGroup.getName() + " is not supported by VPC"); + } + svcProviderMap.put(service, defaultProviders); + } + + if (!sourceNatSvc) { + s_logger.debug("Automatically adding source nat service to the list of VPC services"); + svcProviderMap.put(Service.SourceNat, defaultProviders); + } + + if (!firewallSvs) { + s_logger.debug("Automatically adding firewall service to the list of VPC services"); + svcProviderMap.put(Service.Firewall, defaultProviders); + } + + svcProviderMap.put(Service.Gateway, defaultProviders); + + return createVpcOffering(name, displayText, svcProviderMap, false, null); + } + + + @Override + @DB + public VpcOffering createVpcOffering(String name, String displayText, Map> svcProviderMap, boolean isDefault, State state) { + Transaction txn = Transaction.currentTxn(); + txn.start(); + // create vpc offering object + VpcOfferingVO offering = new VpcOfferingVO(name, displayText, isDefault, null); + + if (state != null) { + offering.setState(state); + } + s_logger.debug("Adding vpc offering " + offering); + offering = _vpcOffDao.persist(offering); + // populate services and providers + if (svcProviderMap != null) { + for (Network.Service service : svcProviderMap.keySet()) { + Set providers = svcProviderMap.get(service); + if (providers != null && !providers.isEmpty()) { + for (Network.Provider provider : providers) { + VpcOfferingServiceMapVO offService = new VpcOfferingServiceMapVO(offering.getId(), service, provider); + _vpcOffSvcMapDao.persist(offService); + s_logger.trace("Added service for the vpc offering: " + offService + " with provider " + provider.getName()); + } + } else { + throw new InvalidParameterValueException("Provider is missing for the VPC offering service " + service.getName()); + } + } + } + + + + txn.commit(); + + UserContext.current().setEventDetails(" Id: " + offering.getId() + " Name: " + name); + return offering; + } + + @Override + public Vpc getVpc(long vpcId) { + return _vpcDao.findById(vpcId); + } + + @Override + public Vpc getActiveVpc(long vpcId) { + return _vpcDao.findById(vpcId); + } + + @Override + public Map> getVpcOffSvcProvidersMap(long vpcOffId) { + Map> serviceProviderMap = new HashMap>(); + List map = _vpcOffSvcMapDao.listByVpcOffId(vpcOffId); + + for (VpcOfferingServiceMapVO instance : map) { + String service = instance.getService(); + Set providers; + providers = serviceProviderMap.get(service); + if (providers == null) { + providers = new HashSet(); + } + providers.add(Provider.getProvider(instance.getProvider())); + serviceProviderMap.put(Service.getService(service), providers); + } + + return serviceProviderMap; + } + + + @Override + public List listVpcOfferings(Long id, String name, String displayText, List supportedServicesStr, + Boolean isDefault, String keyword, String state, Long startIndex, Long pageSizeVal) { + Filter searchFilter = new Filter(VpcOfferingVO.class, "created", false, startIndex, pageSizeVal); + SearchCriteria sc = _vpcOffDao.createSearchCriteria(); + + if (keyword != null) { + SearchCriteria ssc = _vpcOffDao.createSearchCriteria(); + ssc.addOr("displayText", SearchCriteria.Op.LIKE, "%" + keyword + "%"); + ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); + + sc.addAnd("name", SearchCriteria.Op.SC, ssc); + } + + if (name != null) { + sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + name + "%"); + } + + if (displayText != null) { + sc.addAnd("displayText", SearchCriteria.Op.LIKE, "%" + displayText + "%"); + } + + if (isDefault != null) { + sc.addAnd("isDefault", SearchCriteria.Op.EQ, isDefault); + } + + if (state != null) { + sc.addAnd("state", SearchCriteria.Op.EQ, state); + } + + if (id != null) { + sc.addAnd("id", SearchCriteria.Op.EQ, id); + } + + + List offerings = _vpcOffDao.search(sc, searchFilter); + + // filter by supported services + boolean listBySupportedServices = (supportedServicesStr != null && !supportedServicesStr.isEmpty() && !offerings.isEmpty()); + + if (listBySupportedServices) { + List supportedOfferings = new ArrayList(); + Service[] supportedServices = null; + + if (listBySupportedServices) { + supportedServices = new Service[supportedServicesStr.size()]; + int i = 0; + for (String supportedServiceStr : supportedServicesStr) { + Service service = Service.getService(supportedServiceStr); + if (service == null) { + throw new InvalidParameterValueException("Invalid service specified " + supportedServiceStr); + } else { + supportedServices[i] = service; + } + i++; + } + } + + for (VpcOfferingVO offering : offerings) { + if (areServicesSupportedByVpcOffering(offering.getId(), supportedServices)) { + supportedOfferings.add(offering); + } + } + + return supportedOfferings; + } else { + return offerings; + } + } + + @Override + public boolean areServicesSupportedByVpcOffering(long vpcOffId, Service... services) { + return (_vpcOffSvcMapDao.areServicesSupportedByNetworkOffering(vpcOffId, services)); + } + + + @Override + @ActionEvent(eventType = EventTypes.EVENT_VPC_OFFERING_DELETE, eventDescription = "deleting vpc offering") + public boolean deleteVpcOffering(long offId) { + UserContext.current().setEventDetails(" Id: " + offId); + + // Verify vpc offering id + VpcOfferingVO offering = _vpcOffDao.findById(offId); + if (offering == null) { + throw new InvalidParameterValueException("unable to find vpc offering " + offId); + } + + // Don't allow to delete default vpc offerings + if (offering.isDefault() == true) { + throw new InvalidParameterValueException("Default network offering can't be deleted"); + } + + // don't allow to delete vpc offering if it's in use by existing vpcs (the offering can be disabled though) + int vpcCount = _vpcDao.getVpcCountByOfferingId(offId); + if (vpcCount > 0) { + throw new InvalidParameterValueException("Can't delete vpc offering " + offId + " as its used by " + vpcCount + " vpcs. " + + "To make the network offering unavaiable, disable it"); + } + + if (_vpcOffDao.remove(offId)) { + return true; + } else { + return false; + } + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_VPC_OFFERING_UPDATE, eventDescription = "updating vpc offering") + public VpcOffering updateVpcOffering(long vpcOffId, String vpcOfferingName, String displayText, String state) { + UserContext.current().setEventDetails(" Id: " + vpcOffId); + + // Verify input parameters + VpcOfferingVO offeringToUpdate = _vpcOffDao.findById(vpcOffId); + if (offeringToUpdate == null) { + throw new InvalidParameterValueException("Unable to find vpc offering " + vpcOffId); + } + + VpcOfferingVO offering = _vpcOffDao.createForUpdate(vpcOffId); + + if (vpcOfferingName != null) { + offering.setName(vpcOfferingName); + } + + if (displayText != null) { + offering.setDisplayText(displayText); + } + + if (state != null) { + boolean validState = false; + for (VpcOffering.State st : VpcOffering.State.values()) { + if (st.name().equalsIgnoreCase(state)) { + validState = true; + offering.setState(st); + } + } + if (!validState) { + throw new InvalidParameterValueException("Incorrect state value: " + state); + } + } + + if (_vpcOffDao.update(vpcOffId, offering)) { + s_logger.debug("Updated VPC offeirng id=" + vpcOffId); + return _vpcOffDao.findById(vpcOffId); + } else { + return null; + } + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_VPC_CREATE, eventDescription = "creating vpc") + public Vpc createVpc(long zoneId, long vpcOffId, long vpcOwnerId, String vpcName, String displayText, String cidr, + String networkDomain) { + Account caller = UserContext.current().getCaller(); + Account owner = _accountMgr.getAccount(vpcOwnerId); + + //Verify that caller can perform actions in behalf of vpc owner + _accountMgr.checkAccess(caller, null, false, owner); + + // Validate vpc offering + VpcOfferingVO vpcOff = _vpcOffDao.findById(vpcOffId); + if (vpcOff == null) { + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find vpc offering by specified id"); + ex.addProxyObject("vpc_offerings", vpcOffId, "vpcOfferingId"); + throw ex; + } + + //Validate zone + DataCenter zone = _configMgr.getZone(zoneId); + if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getType())) { + // See DataCenterVO.java + PermissionDeniedException ex = new PermissionDeniedException("Cannot perform this operation since specified Zone is currently disabled"); + ex.addProxyObject("data_center", zone.getId(), "zoneId"); + throw ex; + } + + if (networkDomain == null) { + // 1) Get networkDomain from the corresponding account + networkDomain = _ntwkMgr.getAccountNetworkDomain(owner.getId(), zoneId); + + + // 2) If null, generate networkDomain using domain suffix from the global config variables + if (networkDomain == null) { + networkDomain = "cs" + Long.toHexString(owner.getId()) + _ntwkMgr.getDefaultNetworkDomain(); + } + } + + return createVpc(zoneId, vpcOffId, owner, vpcName, displayText, cidr, networkDomain); + } + + @Override + public Vpc createVpc(long zoneId, long vpcOffId, Account vpcOwner, String vpcName, String displayText, String cidr, + String networkDomain) { + + //Validate CIDR + if (!NetUtils.isValidCIDR(cidr)) { + throw new InvalidParameterValueException("Invalid CIDR specified " + cidr); + } + + // validate network domain + if (!NetUtils.verifyDomainName(networkDomain)) { + throw new InvalidParameterValueException( + "Invalid network domain. Total length shouldn't exceed 190 chars. Each domain " + + "label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', " + + "the digits '0' through '9', " + + "and the hyphen ('-'); can't start or end with \"-\""); + } + + + VpcVO vpc = new VpcVO (zoneId, vpcName, displayText, vpcOwner.getId(), vpcOwner.getDomainId(), vpcOffId, cidr, + networkDomain); + vpc = _vpcDao.persist(vpc); + + if (vpc != null) { + s_logger.debug("Created VPC " + vpc); + } else { + s_logger.debug("Failed to create VPC"); + } + return vpc; + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_VPC_DELETE, eventDescription = "deleting VPC") + public boolean deleteVpc(long vpcId) throws ConcurrentOperationException, ResourceUnavailableException { + UserContext.current().setEventDetails(" Id: " + vpcId); + Account caller = UserContext.current().getCaller(); + + // Verify vpc id + Vpc vpc = getVpc(vpcId); + if (vpc == null) { + throw new InvalidParameterValueException("unable to find VPC id=" + vpcId); + } + + //verify permissions + _accountMgr.checkAccess(caller, null, false, vpc); + + return destroyVpc(vpc); + } + + @Override + public boolean destroyVpc(Vpc vpc) throws ConcurrentOperationException, ResourceUnavailableException { + UserContext ctx = UserContext.current(); + + //don't allow to delete vpc if it's in use by existing networks + int networksCount = _ntwkDao.getNetworkCountByVpcId(vpc.getId()); + if (networksCount > 0) { + throw new InvalidParameterValueException("Can't delete VPC " + vpc + " as its used by " + networksCount + " networks"); + } + + //mark VPC as disabled + s_logger.debug("Updating VPC " + vpc + " with state " + Vpc.State.Disabled + " as a part of vpc delete"); + VpcVO vpcVO = _vpcDao.findById(vpc.getId()); + vpcVO.setState(Vpc.State.Disabled); + _vpcDao.update(vpc.getId(), vpcVO); + + //shutdown VPC + if (!shutdownVpc(vpc.getId())) { + s_logger.warn("Failed to shutdown vpc " + vpc + " as a part of vpc destroy process"); + return false; + } + + //cleanup vpc resources + if (!cleanupVpcResources(vpc.getId(), ctx.getCaller(), ctx.getCallerUserId())) { + s_logger.warn("Failed to cleanup resources for vpc " + vpc); + return false; + } + + if (_vpcDao.remove(vpc.getId())) { + return true; + } else { + return false; + } + } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_VPC_UPDATE, eventDescription = "updating vpc") + public Vpc updateVpc(long vpcId, String vpcName, String displayText) { + UserContext.current().setEventDetails(" Id: " + vpcId); + Account caller = UserContext.current().getCaller(); + + // Verify input parameters + VpcVO vpcToUpdate = _vpcDao.findById(vpcId); + if (vpcToUpdate == null) { + throw new InvalidParameterValueException("Unable to find vpc offering " + vpcId); + } + + _accountMgr.checkAccess(caller, null, false, vpcToUpdate); + + VpcVO vpc = _vpcDao.createForUpdate(vpcId); + + if (vpcName != null) { + vpc.setName(vpcName); + } + + if (displayText != null) { + vpc.setDisplayText(displayText); + } + + if (_vpcDao.update(vpcId, vpc)) { + s_logger.debug("Updated VPC id=" + vpcId); + return _vpcDao.findById(vpcId); + } else { + return null; + } + } + + + @Override + public List listVpcs(Long id, String vpcName, String displayText, List supportedServicesStr, + String cidr, Long vpcOffId, String state, String accountName, Long domainId, String keyword, + Long startIndex, Long pageSizeVal, Long zoneId, Boolean isRecursive, Boolean listAll, Boolean restartRequired) { + Account caller = UserContext.current().getCaller(); + List permittedAccounts = new ArrayList(); + + Ternary domainIdRecursiveListProject = new Ternary(domainId, isRecursive, null); + _accountMgr.buildACLSearchParameters(caller, id, accountName, null, permittedAccounts, domainIdRecursiveListProject, + listAll, false); + domainId = domainIdRecursiveListProject.first(); + isRecursive = domainIdRecursiveListProject.second(); + ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); + Filter searchFilter = new Filter(VpcVO.class, "created", false, startIndex, pageSizeVal); + + SearchBuilder sb = _vpcDao.createSearchBuilder(); + _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); + + sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE); + sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); + sb.and("displayText", sb.entity().getDisplayText(), SearchCriteria.Op.LIKE); + sb.and("vpcOfferingId", sb.entity().getVpcOfferingId(), SearchCriteria.Op.EQ); + sb.and("zoneId", sb.entity().getZoneId(), SearchCriteria.Op.EQ); + sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ); + sb.and("restartRequired", sb.entity().isRestartRequired(), SearchCriteria.Op.EQ); + + + // now set the SC criteria... + SearchCriteria sc = sb.create(); + _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); + + if (keyword != null) { + SearchCriteria ssc = _vpcDao.createSearchCriteria(); + ssc.addOr("displayText", SearchCriteria.Op.LIKE, "%" + keyword + "%"); + ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); + sc.addAnd("name", SearchCriteria.Op.SC, ssc); + } + + if (vpcName != null) { + sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + vpcName + "%"); + } + + if (displayText != null) { + sc.addAnd("displayText", SearchCriteria.Op.LIKE, "%" + displayText + "%"); + } + + if (id != null) { + sc.addAnd("id", SearchCriteria.Op.EQ, id); + } + + if (vpcOffId != null) { + sc.addAnd("vpcOfferingId", SearchCriteria.Op.EQ, vpcOffId); + } + + if (zoneId != null) { + sc.addAnd("zoneId", SearchCriteria.Op.EQ, zoneId); + } + + if (state != null) { + sc.addAnd("state", SearchCriteria.Op.EQ, state); + } + + if (restartRequired != null) { + sc.addAnd("restartRequired", SearchCriteria.Op.EQ, restartRequired); + } + + List vpcs = _vpcDao.search(sc, searchFilter); + + // filter by supported services + boolean listBySupportedServices = (supportedServicesStr != null && !supportedServicesStr.isEmpty() && !vpcs.isEmpty()); + + if (listBySupportedServices) { + List supportedVpcs = new ArrayList(); + Service[] supportedServices = null; + + if (listBySupportedServices) { + supportedServices = new Service[supportedServicesStr.size()]; + int i = 0; + for (String supportedServiceStr : supportedServicesStr) { + Service service = Service.getService(supportedServiceStr); + if (service == null) { + throw new InvalidParameterValueException("Invalid service specified " + supportedServiceStr); + } else { + supportedServices[i] = service; + } + i++; + } + } + + for (VpcVO vpc : vpcs) { + if (areServicesSupportedByVpcOffering(vpc.getVpcOfferingId(), supportedServices)) { + supportedVpcs.add(vpc); + } + } + + return supportedVpcs; + } else { + return vpcs; + } + } + + @Override + public List getSupportedServices() { + List services = new ArrayList(); + services.add(Network.Service.Dhcp); + services.add(Network.Service.Dns); + services.add(Network.Service.UserData); + services.add(Network.Service.Firewall); + services.add(Network.Service.PortForwarding); + services.add(Network.Service.Lb); + services.add(Network.Service.SourceNat); + services.add(Network.Service.StaticNat); + services.add(Network.Service.Gateway); + services.add(Network.Service.Vpn); + return services; + } + + @Override + public boolean startVpc(long vpcId) throws ConcurrentOperationException, ResourceUnavailableException, + InsufficientCapacityException { + UserContext ctx = UserContext.current(); + Account caller = ctx.getCaller(); + User callerUser = _accountMgr.getActiveUser(ctx.getCallerUserId()); + + //check if vpc exists + Vpc vpc = getActiveVpc(vpcId); + if (vpc == null) { + throw new InvalidParameterValueException("Unable to find Enabled vpc by id " + vpcId); + } + + //permission check + _accountMgr.checkAccess(caller, null, false, vpc); + + DataCenter dc = _configMgr.getZone(vpc.getZoneId()); + + DeployDestination dest = new DeployDestination(dc, null, null, null); + ReservationContext context = new ReservationContextImpl(null, null, callerUser, + _accountMgr.getAccount(vpc.getAccountId())); + + boolean result = true; + try { + if (!startVpc(vpc, dest, context)) { + s_logger.warn("Failed to start vpc " + vpc); + result = false; + } + } catch (Exception ex) { + s_logger.warn("Failed to start vpc " + vpc + " due to ", ex); + result = false; + } finally { + //do cleanup + if (!result) { + s_logger.debug("Destroying vpc " + vpc + " that failed to start"); + if (destroyVpc(vpc)) { + s_logger.warn("Successfully destroyed vpc " + vpc + " that failed to start"); + } else { + s_logger.warn("Failed to destroy vpc " + vpc + " that failed to start"); + } + } + } + return result; + } + + protected boolean startVpc(Vpc vpc, DeployDestination dest, ReservationContext context) + throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { + //deploy provider + if (getVpcElement().implementVpc(vpc, dest, context)) { + s_logger.debug("Vpc " + vpc + " has started succesfully"); + return true; + } else { + s_logger.warn("Vpc " + vpc + " failed to start"); + return false; + } + } + + @Override + public boolean shutdownVpc(long vpcId) throws ConcurrentOperationException, ResourceUnavailableException { + UserContext ctx = UserContext.current(); + Account caller = ctx.getCaller(); + + //check if vpc exists + Vpc vpc = getVpc(vpcId); + if (vpc == null) { + throw new InvalidParameterValueException("Unable to find vpc by id " + vpcId); + } + + //permission check + _accountMgr.checkAccess(caller, null, false, vpc); + + //shutdown provider + boolean success = getVpcElement().shutdownVpc(vpc); + + //FIXME - once more features are added to vpc (gateway/firewall rules, etc - cleanup them here) + if (success) { + s_logger.debug("Vpc " + vpc + " has been shutdown succesfully"); + } else { + s_logger.warn("Vpc " + vpc + " failed to shutdown"); + } + return success; + } + + @Override + @DB + public void validateGuestNtkwForVpc(NetworkOffering guestNtwkOff, String cidr, String networkDomain, + Account networkOwner, Vpc vpc) throws ConcurrentOperationException { + + Vpc locked = _vpcDao.acquireInLockTable(vpc.getId()); + if (locked == null) { + throw new ConcurrentOperationException("Unable to acquire lock on " + vpc); + } + + try { + //1) CIDR is required + if (cidr == null) { + throw new InvalidParameterValueException("Gateway/netmask are required when create network for VPC"); + } + + //2) Network cidr should be within vpcCidr + if (!NetUtils.isNetworkAWithinNetworkB(cidr, vpc.getCidr())) { + throw new InvalidParameterValueException("Network cidr " + cidr + " is not within vpc " + vpc + " cidr"); + } + + //3) Network cidr shouldn't cross the cidr of other vpc network cidrs + List ntwks = _ntwkDao.listByVpc(vpc.getId()); + for (Network ntwk : ntwks) { + assert (cidr != null) : "Why the network cidr is null when it belongs to vpc?"; + + if (NetUtils.isNetworkAWithinNetworkB(ntwk.getCidr(), vpc.getCidr()) + || NetUtils.isNetworkAWithinNetworkB(vpc.getCidr(), ntwk.getCidr())) { + throw new InvalidParameterValueException("Network cidr " + cidr + " crosses other network cidr " + ntwk + + " belonging to the same vpc " + vpc); + } + } + + //4) vpc and network should belong to the same owner + if (vpc.getAccountId() != networkOwner.getId()) { + throw new InvalidParameterValueException("Vpc " + vpc + " owner is different from the network owner " + + networkOwner); + } + + //5) Only Isolated networks with Source nat service enabled can be added to vpc + if (!(guestNtwkOff.getGuestType() == GuestType.Isolated + && _ntwkMgr.areServicesSupportedByNetworkOffering(guestNtwkOff.getId(), Service.SourceNat))) { + + throw new InvalidParameterValueException("Only networks of type " + GuestType.Isolated + " with service " + + Service.SourceNat + + " can be added as a part of VPC"); + } + + //6) Only VPC VR can be a provider for the network offering + List ntwkOffProviders = _ntwkMgr.getNtwkOffDistinctProviders(guestNtwkOff.getId()); + for (Provider provider : ntwkOffProviders) { + if (provider != Provider.VPCVirtualRouter) { + throw new InvalidParameterValueException("Only VPCVirtualRouter provider is supported in VPC network;" + + " while network offering " + guestNtwkOff + " has " + provider.getName() + " enabled."); + } + } + + //7) No redundant router support + if (guestNtwkOff.getRedundantRouter()) { + throw new InvalidParameterValueException("No redunant router support when network belnogs to VPC"); + } + + //8) Conserve mode should be off + if (guestNtwkOff.isConserveMode()) { + throw new InvalidParameterValueException("Only networks with conserve mode Off can belong to VPC"); + } + + } finally { + s_logger.debug("Releasing lock for " + locked); + _vpcDao.releaseFromLockTable(locked.getId()); + } + } + + @Override + public VpcProvider getVpcElement() { + if (vpcElement == null) { + vpcElement = ((VpcProvider)_ntwkMgr.getElementImplementingProvider(Provider.VPCVirtualRouter.getName())); + } + + return vpcElement; + } + + @Override + public List getVpcsForAccount(long accountId) { + return _vpcDao.listByAccountId(accountId); + } + + public boolean cleanupVpcResources(long vpcId, Account caller, long callerUserId) { + s_logger.debug("Cleaning up resources for vpc id=" + vpcId); + boolean success = true; + // release all ip addresses + List ipsToRelease = _ipAddressDao.listByAssociatedVpc(vpcId, null); + s_logger.debug("Releasing ips for vpc id=" + vpcId + " as a part of vpc cleanup"); + for (IPAddressVO ipToRelease : ipsToRelease) { + success = success && _ntwkMgr.disassociatePublicIpAddress(ipToRelease.getId(), callerUserId, caller); + if (!success) { + s_logger.warn("Failed to cleanup ip " + ipToRelease + " as a part of vpc id=" + vpcId + " cleanup"); + } + } + + return success; + } + + + @Override + @ActionEvent(eventType = EventTypes.EVENT_VPC_RESTART, eventDescription = "restarting vpc") + public boolean restartVpc(Long vpcId) throws ConcurrentOperationException, ResourceUnavailableException, + InsufficientCapacityException { + Account caller = UserContext.current().getCaller(); + + // Verify input parameters + VpcVO vpc = _vpcDao.findById(vpcId); + if (vpc == null) { + throw new InvalidParameterValueException("Unable to find vpc offering " + vpcId); + } + + _accountMgr.checkAccess(caller, null, false, vpc); + + s_logger.debug("Restarting VPC " + vpc); + boolean restartRequired = false; + try { + s_logger.debug("Shuttign down VPC " + vpc + " as a part of VPC restart process"); + if (!shutdownVpc(vpcId)) { + s_logger.warn("Failed to shutdown vpc as a part of VPC " + vpc + " restart process"); + restartRequired = true; + return false; + } + + s_logger.debug("Starting VPC " + vpc + " as a part of VPC restart process"); + if (!startVpc(vpcId)) { + s_logger.warn("Failed to start vpc as a part of VPC " + vpc + " restart process"); + restartRequired = true; + return false; + } + s_logger.debug("VPC " + vpc + " was restarted successfully"); + return true; + } finally { + s_logger.debug("Updating VPC " + vpc + " with restartRequired=" + restartRequired); + vpc.setRestartRequired(restartRequired); + _vpcDao.update(vpc.getId(), vpc); + } + } + + @Override + public List getVpcRouters(long vpcId) { + return _routerDao.listRoutersByVpcId(vpcId); + } +} diff --git a/server/src/com/cloud/network/vpc/VpcOfferingServiceMapVO.java b/server/src/com/cloud/network/vpc/VpcOfferingServiceMapVO.java new file mode 100644 index 00000000000..ffe8533cdf9 --- /dev/null +++ b/server/src/com/cloud/network/vpc/VpcOfferingServiceMapVO.java @@ -0,0 +1,87 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc; + +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.cloud.network.Network.Provider; +import com.cloud.network.Network.Service; +import com.cloud.utils.db.GenericDao; + +/** + * @author Alena Prokharchyk + */ + +@Entity +@Table(name="vpc_offering_service_map") +public class VpcOfferingServiceMapVO { + @Id + @GeneratedValue(strategy=GenerationType.IDENTITY) + @Column(name="id") + long id; + + @Column(name="vpc_offering_id") + long vpcOfferingId; + + @Column(name="service") + String service; + + @Column(name="provider") + String provider; + + @Column(name=GenericDao.CREATED_COLUMN) + Date created; + + public long getId() { + return id; + } + + public long getVpcOfferingId() { + return vpcOfferingId; + } + + public String getService() { + return service; + } + + public String getProvider() { + return provider; + } + + public Date getCreated() { + return created; + } + + public VpcOfferingServiceMapVO() { + } + + public VpcOfferingServiceMapVO(long vpcOfferingId, Service service, Provider provider) { + this.vpcOfferingId = vpcOfferingId; + this.service = service.getName(); + if (provider != null) { + this.provider = provider.getName(); + } + } + + public String toString() { + StringBuilder buf = new StringBuilder("[VPC Offering Service["); + return buf.append(vpcOfferingId).append("-").append(service).append("-").append(provider).append("]").toString(); + } +} diff --git a/server/src/com/cloud/network/vpc/VpcOfferingVO.java b/server/src/com/cloud/network/vpc/VpcOfferingVO.java new file mode 100644 index 00000000000..2109e1c0cd7 --- /dev/null +++ b/server/src/com/cloud/network/vpc/VpcOfferingVO.java @@ -0,0 +1,150 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc; + +import java.util.Date; +import java.util.UUID; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.cloud.utils.db.GenericDao; + +/** + * @author Alena Prokharchyk + */ + +@Entity +@Table(name="vpc_offerings") +public class VpcOfferingVO implements VpcOffering{ + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + long id; + + @Column(name="uuid") + private String uuid; + + @Column(name = "name") + String name; + + @Column(name = "unique_name") + String uniqueName; + + @Column(name = "display_text") + String displayText; + + @Column(name = "state") + @Enumerated(value = EnumType.STRING) + State state = State.Disabled; + + @Column(name = "default") + boolean isDefault = false; + + @Column(name = GenericDao.REMOVED_COLUMN) + Date removed; + + @Column(name = GenericDao.CREATED_COLUMN) + Date created; + + @Column(name = "service_offering_id") + Long serviceOfferingId; + + public VpcOfferingVO() { + this.uuid = UUID.randomUUID().toString(); + } + + public VpcOfferingVO(String name, String displayText, Long serviceOfferingId) { + this.name = name; + this.displayText = displayText; + this.uniqueName = name; + this.serviceOfferingId = serviceOfferingId; + this.uuid = UUID.randomUUID().toString(); + this.state = State.Disabled; + } + + public VpcOfferingVO(String name, String displayText, boolean isDefault, Long serviceOfferingId) { + this(name, displayText, serviceOfferingId); + this.isDefault = isDefault; + } + + @Override + public long getId() { + return id; + } + + @Override + public String getUuid() { + return uuid; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getUniqueName() { + return uniqueName; + } + + @Override + public String getDisplayText() { + return displayText; + } + + @Override + public State getState() { + return state; + } + + @Override + public boolean isDefault() { + return isDefault; + } + + public void setUniqueName(String uniqueName) { + this.uniqueName = uniqueName; + } + + @Override + public String toString() { + StringBuilder buf = new StringBuilder("[VPC Offering ["); + return buf.append(id).append("-").append(name).append("]").toString(); + } + + public void setName(String name) { + this.name = name; + } + + + public void setDisplayText(String displayText) { + this.displayText = displayText; + } + + public void setState(State state) { + this.state = state; + } + + @Override + public Long getServiceOfferingId() { + return serviceOfferingId; + } +} diff --git a/server/src/com/cloud/network/vpc/VpcVO.java b/server/src/com/cloud/network/vpc/VpcVO.java new file mode 100644 index 00000000000..212a124f9b7 --- /dev/null +++ b/server/src/com/cloud/network/vpc/VpcVO.java @@ -0,0 +1,187 @@ +// Copyright 2012 Citrix Systems, Inc. Licensed under the +// Apache License, Version 2.0 (the "License"); you may not use this +// file except in compliance with the License. Citrix Systems, Inc. +// reserves all rights not expressly granted by the License. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Automatically generated by addcopyright.py at 04/03/2012 +package com.cloud.network.vpc; + +import java.util.Date; +import java.util.UUID; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.cloud.api.Identity; +import com.cloud.utils.db.GenericDao; + +/** + * @author Alena Prokharchyk + */ + +@Entity +@Table(name="vpc") +public class VpcVO implements Vpc, Identity { + @Id + @Column(name="id") + long id; + + @Column(name="uuid") + private String uuid; + + @Column(name="name") + private String name; + + @Column(name = "display_text") + String displayText; + + @Column(name="zone_id") + long zoneId; + + @Column(name="cidr") + private String cidr = null; + + @Column(name="domain_id") + Long domainId = null; + + @Column(name="account_id") + Long accountId = null; + + @Column(name="state") + @Enumerated(value=EnumType.STRING) + State state; + + @Column(name="vpc_offering_id") + long vpcOfferingId; + + @Column(name=GenericDao.REMOVED_COLUMN) + Date removed; + + @Column(name=GenericDao.CREATED_COLUMN) + Date created; + + @Column(name="network_domain") + String networkDomain; + + @Column(name="restart_required") + boolean restartRequired = false; + + public VpcVO() { + this.uuid = UUID.randomUUID().toString(); + } + + public VpcVO(long zoneId, String name, String displayText, long accountId, long domainId, long vpcOffId, String cidr, + String networkDomain) { + this.zoneId = zoneId; + this.name = name; + this.displayText = displayText; + this.accountId = accountId; + this.domainId = domainId; + this.cidr = cidr; + this.uuid = UUID.randomUUID().toString(); + this.state = State.Enabled; + this.networkDomain = networkDomain; + this.vpcOfferingId = vpcOffId; + } + + @Override + public boolean readyToUse() { + return state == State.Enabled; + } + + @Override + public long getId() { + return id; + } + + @Override + public String getUuid() { + return uuid; + } + + @Override + public String getName() { + return name; + } + + @Override + public long getZoneId() { + return zoneId; + } + + @Override + public String getCidr() { + return cidr; + } + + @Override + public long getDomainId() { + return domainId; + } + + @Override + public long getAccountId() { + return accountId; + } + + @Override + public State getState() { + return state; + } + + public void setState(State state) { + this.state = state; + } + + @Override + public long getVpcOfferingId() { + return vpcOfferingId; + } + + public Date getRemoved() { + return removed; + } + + @Override + public String getDisplayText() { + return displayText; + } + + public void setName(String name) { + this.name = name; + } + + public void setDisplayText(String displayText) { + this.displayText = displayText; + } + + @Override + public String toString() { + StringBuilder buf = new StringBuilder("[VPC ["); + return buf.append(id).append("-").append(name).append("]").toString(); + } + + @Override + public String getNetworkDomain() { + return networkDomain; + } + + public void setRestartRequired(boolean restartRequired) { + this.restartRequired = restartRequired; + } + + @Override + public boolean isRestartRequired() { + return restartRequired; + } +} diff --git a/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java b/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java index 035629ceb85..b1ee175b0e7 100755 --- a/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java +++ b/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java @@ -102,7 +102,8 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag SearchBuilder VpnSearch; @Override - public RemoteAccessVpn createRemoteAccessVpn(long publicIpId, String ipRange, boolean openFirewall) throws NetworkRuleConflictException { + public RemoteAccessVpn createRemoteAccessVpn(long publicIpId, String ipRange, boolean openFirewall, long networkId) + throws NetworkRuleConflictException { UserContext ctx = UserContext.current(); Account caller = ctx.getCaller(); @@ -114,11 +115,23 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag _accountMgr.checkAccess(caller, null, true, ipAddr); - if (!ipAddr.readyToUse() || ipAddr.getAssociatedWithNetworkId() == null) { + if (!ipAddr.readyToUse()) { throw new InvalidParameterValueException("The Ip address is not ready to be used yet: " + ipAddr.getAddress()); } IPAddressVO ipAddress = _ipAddressDao.findById(publicIpId); + + //associate ip address to network (if needed) + if (ipAddress.getAssociatedWithNetworkId() == null) { + s_logger.debug("The ip is not associated with the network id="+ networkId + " so assigning"); + try { + _networkMgr.associateIPToGuestNetwork(publicIpId, networkId); + } catch (Exception ex) { + s_logger.warn("Failed to associate ip id=" + publicIpId + " to network id=" + networkId + " as " + + "a part of remote access vpn creation"); + return null; + } + } _networkMgr.checkIpForService(ipAddress, Service.Vpn); RemoteAccessVpnVO vpnVO = _remoteAccessVpnDao.findByPublicIpAddress(publicIpId); @@ -132,7 +145,7 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag } // TODO: assumes one virtual network / domr per account per zone - vpnVO = _remoteAccessVpnDao.findByAccountAndNetwork(ipAddr.getAccountId(), ipAddr.getAssociatedWithNetworkId()); + vpnVO = _remoteAccessVpnDao.findByAccountAndNetwork(ipAddr.getAccountId(), networkId); if (vpnVO != null) { //if vpn is in Added state, return it to the api if (vpnVO.getState() == RemoteAccessVpn.State.Added) { @@ -142,7 +155,7 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag } //Verify that vpn service is enabled for the network - Network network = _networkMgr.getNetwork(ipAddr.getAssociatedWithNetworkId()); + Network network = _networkMgr.getNetwork(networkId); if (!_networkMgr.areServicesSupportedInNetwork(network.getId(), Service.Vpn)) { throw new InvalidParameterValueException("Vpn service is not supported in network id=" + ipAddr.getAssociatedWithNetworkId()); } diff --git a/server/src/com/cloud/offerings/NetworkOfferingVO.java b/server/src/com/cloud/offerings/NetworkOfferingVO.java index cf0e6702437..d1adeac96a8 100755 --- a/server/src/com/cloud/offerings/NetworkOfferingVO.java +++ b/server/src/com/cloud/offerings/NetworkOfferingVO.java @@ -307,6 +307,12 @@ public class NetworkOfferingVO implements NetworkOffering, Identity { this(name, "System Offering for " + name, trafficType, true, false, 0, 0, true, Availability.Required, null, null, true, specifyIpRanges); this.state = State.Enabled; } + + public NetworkOfferingVO(String name, Network.GuestType guestType) { + this(name, "System Offering for " + name, TrafficType.Guest, true, true, 0, 0, true, Availability.Optional, + null, Network.GuestType.Isolated, true, false); + this.state = State.Enabled; + } @Override public String toString() { diff --git a/server/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDao.java b/server/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDao.java index 2ab4507d765..430c94de91b 100644 --- a/server/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDao.java +++ b/server/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDao.java @@ -26,11 +26,18 @@ import com.cloud.utils.db.GenericDao; */ public interface NetworkOfferingServiceMapDao extends GenericDao { boolean areServicesSupportedByNetworkOffering(long networkOfferingId, Service... services); + List listByNetworkOfferingId(long networkOfferingId); + void deleteByOfferingId(long networkOfferingId); + List listProvidersForServiceForNetworkOffering(long networkOfferingId, Service service); + boolean isProviderForNetworkOffering(long networkOfferingId, Provider provider); + List listServicesForNetworkOffering(long networkOfferingId); + + List getDistinctProviders(long offId); } diff --git a/server/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDaoImpl.java b/server/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDaoImpl.java index 28eed904e43..c43220dd38b 100644 --- a/server/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDaoImpl.java +++ b/server/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDaoImpl.java @@ -17,12 +17,9 @@ import java.util.List; import javax.ejb.Local; -import com.cloud.exception.UnsupportedServiceException; -import com.cloud.network.NetworkServiceMapVO; -import com.cloud.network.Network.Service; import com.cloud.network.Network.Provider; +import com.cloud.network.Network.Service; import com.cloud.offerings.NetworkOfferingServiceMapVO; -import com.cloud.offerings.NetworkOfferingVO; import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.GenericSearchBuilder; @@ -37,6 +34,8 @@ public class NetworkOfferingServiceMapDaoImpl extends GenericDaoBase MultipleServicesSearch; final GenericSearchBuilder ProvidersSearch; final GenericSearchBuilder ServicesSearch; + final GenericSearchBuilder DistinctProvidersSearch; + protected NetworkOfferingServiceMapDaoImpl() { super(); @@ -62,6 +61,12 @@ public class NetworkOfferingServiceMapDaoImpl extends GenericDaoBase getDistinctProviders(long offId) { + SearchCriteria sc = DistinctProvidersSearch.create(); + sc.setParameters("offId", offId); + List results = customSearch(sc, null); + return results; + } } diff --git a/server/src/com/cloud/server/ConfigurationServerImpl.java b/server/src/com/cloud/server/ConfigurationServerImpl.java index 81ca96e931c..29173389bf4 100755 --- a/server/src/com/cloud/server/ConfigurationServerImpl.java +++ b/server/src/com/cloud/server/ConfigurationServerImpl.java @@ -61,6 +61,7 @@ import com.cloud.domain.dao.DomainDao; import com.cloud.exception.InternalErrorException; import com.cloud.exception.InvalidParameterValueException; import com.cloud.network.Network; +import com.cloud.network.Network.GuestType; import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; import com.cloud.network.Network.State; @@ -94,7 +95,6 @@ import com.cloud.utils.PropertiesUtil; import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.crypt.DBEncryptionUtil; import com.cloud.utils.db.DB; -import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; @@ -874,16 +874,22 @@ public class ConfigurationServerImpl implements ConfigurationServer { @DB protected void createDefaultNetworkOfferings() { - NetworkOfferingVO publicNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemPublicNetwork, TrafficType.Public, true); + NetworkOfferingVO publicNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemPublicNetwork, + TrafficType.Public, true); publicNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(publicNetworkOffering); - NetworkOfferingVO managementNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemManagementNetwork, TrafficType.Management, false); + NetworkOfferingVO managementNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemManagementNetwork, + TrafficType.Management, false); managementNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(managementNetworkOffering); - NetworkOfferingVO controlNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemControlNetwork, TrafficType.Control, false); + NetworkOfferingVO controlNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemControlNetwork, + TrafficType.Control, false); controlNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(controlNetworkOffering); - NetworkOfferingVO storageNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemStorageNetwork, TrafficType.Storage, true); + NetworkOfferingVO storageNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemStorageNetwork, + TrafficType.Storage, true); storageNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(storageNetworkOffering); + NetworkOfferingVO privateGatewayNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemPrivateGatewayNetworkOffering, GuestType.Isolated); + privateGatewayNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(privateGatewayNetworkOffering); - // populate providers + //populate providers Map defaultSharedNetworkOfferingProviders = new HashMap(); defaultSharedNetworkOfferingProviders.put(Service.Dhcp, Provider.VirtualRouter); defaultSharedNetworkOfferingProviders.put(Service.Dns, Provider.VirtualRouter); @@ -968,7 +974,8 @@ public class ConfigurationServerImpl implements ConfigurationServer { defaultIsolatedSourceNatEnabledNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultIsolatedSourceNatEnabledNetworkOffering); for (Service service : defaultIsolatedSourceNatEnabledNetworkOfferingProviders.keySet()) { - NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO(defaultIsolatedSourceNatEnabledNetworkOffering.getId(), service, defaultIsolatedSourceNatEnabledNetworkOfferingProviders.get(service)); + NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO + (defaultIsolatedSourceNatEnabledNetworkOffering.getId(), service, defaultIsolatedSourceNatEnabledNetworkOfferingProviders.get(service)); _ntwkOfferingServiceMapDao.persist(offService); s_logger.trace("Added service for the network offering: " + offService); } @@ -1007,6 +1014,36 @@ public class ConfigurationServerImpl implements ConfigurationServer { s_logger.trace("Added service for the network offering: " + offService); } + // Offering #6 + NetworkOfferingVO defaultNetworkOfferingForVpcNetworks = new NetworkOfferingVO( + NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworks, + "Offering for Isolated Vpc networks with Source Nat service enabled", + TrafficType.Guest, + false, false, null, null, true, Availability.Required, + null, Network.GuestType.Isolated, false, false); + + defaultNetworkOfferingForVpcNetworks.setState(NetworkOffering.State.Enabled); + defaultNetworkOfferingForVpcNetworks = _networkOfferingDao.persistDefaultNetworkOffering(defaultNetworkOfferingForVpcNetworks); + + Map defaultVpcNetworkOfferingProviders = new HashMap(); + defaultVpcNetworkOfferingProviders.put(Service.Dhcp, Provider.VPCVirtualRouter); + defaultVpcNetworkOfferingProviders.put(Service.Dns, Provider.VPCVirtualRouter); + defaultVpcNetworkOfferingProviders.put(Service.UserData, Provider.VPCVirtualRouter); + defaultVpcNetworkOfferingProviders.put(Service.Firewall, Provider.VPCVirtualRouter); + defaultVpcNetworkOfferingProviders.put(Service.Gateway, Provider.VPCVirtualRouter); + defaultVpcNetworkOfferingProviders.put(Service.Lb, Provider.VPCVirtualRouter); + defaultVpcNetworkOfferingProviders.put(Service.SourceNat, Provider.VPCVirtualRouter); + defaultVpcNetworkOfferingProviders.put(Service.StaticNat, Provider.VPCVirtualRouter); + defaultVpcNetworkOfferingProviders.put(Service.PortForwarding, Provider.VPCVirtualRouter); + defaultVpcNetworkOfferingProviders.put(Service.Vpn, Provider.VPCVirtualRouter); + + for (Service service : defaultVpcNetworkOfferingProviders.keySet()) { + NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO + (defaultNetworkOfferingForVpcNetworks.getId(), service, defaultVpcNetworkOfferingProviders.get(service)); + _ntwkOfferingServiceMapDao.persist(offService); + s_logger.trace("Added service for the network offering: " + offService); + } + txn.commit(); } @@ -1061,8 +1098,9 @@ public class ConfigurationServerImpl implements ConfigurationServer { } if (broadcastDomainType != null) { - NetworkVO network = new NetworkVO(id, trafficType, mode, broadcastDomainType, networkOfferingId, domainId, accountId, related, null, null, networkDomain, Network.GuestType.Shared, zoneId, null, - null, specifyIpRanges); + NetworkVO network = new NetworkVO(id, trafficType, mode, broadcastDomainType, networkOfferingId, + domainId, accountId, related, null, null, networkDomain, Network.GuestType.Shared, zoneId, null, + null, specifyIpRanges, null); network.setGuruName(guruNames.get(network.getTrafficType())); network.setDns1(zone.getDns1()); network.setDns2(zone.getDns2()); diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index b865f9c184e..84135ac1e12 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -1565,6 +1565,7 @@ public class ManagementServerImpl implements ManagementServer { Long hostId = cmd.getHostId(); String keyword = cmd.getKeyword(); Long networkId = cmd.getNetworkId(); + Long vpcId = cmd.getVpcId(); Account caller = UserContext.current().getCaller(); List permittedAccounts = new ArrayList(); @@ -1585,6 +1586,7 @@ public class ManagementServerImpl implements ManagementServer { sb.and("dataCenterId", sb.entity().getDataCenterIdToDeployIn(), SearchCriteria.Op.EQ); 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 (networkId != null) { SearchBuilder nicSearch = _nicDao.createSearchBuilder(); @@ -1611,25 +1613,35 @@ public class ManagementServerImpl implements ManagementServer { if (name != null) { sc.setParameters("name", "%" + name + "%"); } + if (id != null) { sc.setParameters("id", id); } + if (state != null) { sc.setParameters("state", state); } + if (zone != null) { sc.setParameters("dataCenterId", zone); } + if (pod != null) { sc.setParameters("podId", pod); } + if (hostId != null) { sc.setParameters("hostId", hostId); } + if (networkId != null) { sc.setJoinParameters("nicSearch", "networkId", networkId); } + if (vpcId != null) { + sc.setParameters("vpcId", vpcId); + } + return _routerDao.search(sc, searchFilter); } @@ -1646,6 +1658,7 @@ public class ManagementServerImpl implements ManagementServer { Long ipId = cmd.getId(); Boolean sourceNat = cmd.getIsSourceNat(); Boolean staticNat = cmd.getIsStaticNat(); + Long vpcId = cmd.getVpcId(); Account caller = UserContext.current().getCaller(); List permittedAccounts = new ArrayList(); @@ -1673,6 +1686,7 @@ public class ManagementServerImpl implements ManagementServer { sb.and("associatedNetworkIdEq", sb.entity().getAssociatedWithNetworkId(), SearchCriteria.Op.EQ); sb.and("isSourceNat", sb.entity().isSourceNat(), SearchCriteria.Op.EQ); sb.and("isStaticNat", sb.entity().isOneToOneNat(), SearchCriteria.Op.EQ); + sb.and("vpcId", sb.entity().getVpcId(), SearchCriteria.Op.EQ); if (forLoadBalancing != null && (Boolean) forLoadBalancing) { SearchBuilder lbSearch = _loadbalancerDao.createSearchBuilder(); @@ -1715,6 +1729,10 @@ public class ManagementServerImpl implements ManagementServer { sc.setParameters("dataCenterId", zone); } + if (vpcId != null) { + sc.setParameters("vpcId", vpcId); + } + if (ipId != null) { sc.setParameters("id", ipId); } diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java index 29a978244ee..8a54f235b71 100755 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java @@ -42,6 +42,8 @@ import com.cloud.agent.api.StartupStorageCommand; import com.cloud.agent.api.StopAnswer; import com.cloud.agent.api.check.CheckSshAnswer; import com.cloud.agent.api.check.CheckSshCommand; +import com.cloud.agent.api.to.NicTO; +import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.manager.Commands; import com.cloud.capacity.dao.CapacityDao; import com.cloud.cluster.ClusterManager; @@ -69,6 +71,7 @@ import com.cloud.info.RunningHostInfoAgregator; import com.cloud.info.RunningHostInfoAgregator.ZoneHostInfo; import com.cloud.keystore.KeystoreManager; import com.cloud.network.IPAddressVO; +import com.cloud.network.Network; import com.cloud.network.NetworkManager; import com.cloud.network.NetworkVO; import com.cloud.network.Networks.TrafficType; @@ -1087,7 +1090,6 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V buf.append(" eth").append(deviceId).append("mask=").append(nic.getNetmask()); } - buf.append(" eth").append(deviceId).append("mask=").append(nic.getNetmask()); if (nic.isDefaultNic()) { buf.append(" gateway=").append(nic.getGateway()); } @@ -1444,4 +1446,20 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V } return null; } + + @Override + public boolean plugNic(Network network, NicTO nic, VirtualMachineTO vm, + ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException, + InsufficientCapacityException { + //not supported + throw new UnsupportedOperationException("Plug nic is not supported for vm of type " + vm.getType()); + } + + + @Override + public boolean unplugNic(Network network, NicTO nic, VirtualMachineTO vm, + ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException { + //not supported + throw new UnsupportedOperationException("Unplug nic is not supported for vm of type " + vm.getType()); + } } diff --git a/server/src/com/cloud/test/PodZoneConfig.java b/server/src/com/cloud/test/PodZoneConfig.java index 2669e66d774..0daa9167493 100644 --- a/server/src/com/cloud/test/PodZoneConfig.java +++ b/server/src/com/cloud/test/PodZoneConfig.java @@ -381,7 +381,8 @@ public class PodZoneConfig { String defaultXenStorageNetworkLabel = getDefaultXenNetworkLabel(TrafficType.Storage); String defaultXenGuestNetworkLabel = getDefaultXenNetworkLabel(TrafficType.Guest); - String insertTraficType = "INSERT INTO `cloud`.`physical_network_traffic_types` (physical_network_id, traffic_type, xen_network_label) VALUES ( ?, ?, ?)"; + String insertTraficType = "INSERT INTO `cloud`.`physical_network_traffic_types` " + + "(physical_network_id, traffic_type, xen_network_label) VALUES ( ?, ?, ?)"; try { PreparedStatement stmt = txn.prepareAutoCloseStatement(insertTraficType); diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java index 35fbfe01077..441399fcabf 100755 --- a/server/src/com/cloud/user/AccountManagerImpl.java +++ b/server/src/com/cloud/user/AccountManagerImpl.java @@ -77,6 +77,8 @@ import com.cloud.network.dao.RemoteAccessVpnDao; import com.cloud.network.dao.VpnUserDao; import com.cloud.network.security.SecurityGroupManager; import com.cloud.network.security.dao.SecurityGroupDao; +import com.cloud.network.vpc.Vpc; +import com.cloud.network.vpc.VpcManager; import com.cloud.network.vpn.RemoteAccessVpnService; import com.cloud.projects.Project; import com.cloud.projects.Project.ListProjectResourcesCriteria; @@ -199,6 +201,8 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag private ProjectAccountDao _projectAccountDao; @Inject private IPAddressDao _ipAddressDao; + @Inject + private VpcManager _vpcMgr; private Adapters _userAuthenticators; @@ -574,19 +578,35 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag } } + //Delete all VPCs + boolean vpcsDeleted = true; + s_logger.debug("Deleting vpcs for account " + account.getId()); + List vpcs = _vpcMgr.getVpcsForAccount(account.getId()); + for (Vpc vpc : vpcs) { + + if (!_vpcMgr.destroyVpc(vpc)) { + s_logger.warn("Unable to destroy VPC " + vpc + " as a part of account id=" + accountId + " cleanup."); + accountCleanupNeeded = true; + vpcsDeleted = false; + } else { + s_logger.debug("VPC " + vpc.getId() + " successfully deleted as a part of account id=" + accountId + " cleanup."); + } + } + + if (vpcsDeleted) { // release ip addresses belonging to the account List ipsToRelease = _ipAddressDao.listByAccount(accountId); for (IpAddress ip : ipsToRelease) { s_logger.debug("Releasing ip " + ip + " as a part of account id=" + accountId + " cleanup"); - if (!_networkMgr.releasePublicIpAddress(ip.getId(), callerUserId, caller)) { + if (!_networkMgr.disassociatePublicIpAddress(ip.getId(), callerUserId, caller)) { s_logger.warn("Failed to release ip address " + ip + " as a part of account id=" + accountId + " clenaup"); accountCleanupNeeded = true; } } + } // delete account specific Virtual vlans (belong to system Public Network) - only when networks are cleaned - // up - // successfully + // up successfully if (networksDeleted) { if (!_configMgr.deleteAccountSpecificVirtualRanges(accountId)) { accountCleanupNeeded = true; diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 63b85a573bc..77339760889 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -152,7 +152,6 @@ import com.cloud.storage.GuestOSVO; import com.cloud.storage.Snapshot; import com.cloud.storage.SnapshotVO; import com.cloud.storage.Storage; -import com.cloud.storage.VolumeHostVO; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Storage.TemplateType; @@ -166,6 +165,7 @@ import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateZoneVO; import com.cloud.storage.Volume; import com.cloud.storage.Volume.Type; +import com.cloud.storage.VolumeHostVO; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.storage.dao.GuestOSDao; @@ -425,7 +425,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager } Network defaultNetwork = _networkDao.findById(defaultNic.getNetworkId()); - NicProfile defaultNicProfile = new NicProfile(defaultNic, defaultNetwork, null, null, null, _networkMgr.isSecurityGroupSupportedInNetwork(defaultNetwork), _networkMgr.getNetworkTag(template.getHypervisorType(), defaultNetwork)); + NicProfile defaultNicProfile = new NicProfile(defaultNic, defaultNetwork, null, null, null, + _networkMgr.isSecurityGroupSupportedInNetwork(defaultNetwork), + _networkMgr.getNetworkTag(template.getHypervisorType(), defaultNetwork)); VirtualMachineProfile vmProfile = new VirtualMachineProfileImpl(vmInstance); vmProfile.setParameter(VirtualMachineProfile.Param.VmPassword, password); @@ -2167,9 +2169,11 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager List virtualNetworks = _networkMgr.listNetworksForAccount(owner.getId(), zone.getId(), Network.GuestType.Isolated); if (virtualNetworks.isEmpty()) { - s_logger.debug("Creating network for account " + owner + " from the network offering id=" + requiredOfferings.get(0).getId() + " as a part of deployVM process"); - Network newNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), owner.getAccountName() + "-network", owner.getAccountName() + "-network", null, null, - null, null, owner, false, null, physicalNetwork, zone.getId(), ACLType.Account, null); + s_logger.debug("Creating network for account " + owner + " from the network offering id=" + + requiredOfferings.get(0).getId() + " as a part of deployVM process"); + Network newNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), + owner.getAccountName() + "-network", owner.getAccountName() + "-network", null, null, + null, null, owner, null, physicalNetwork, zone.getId(), ACLType.Account, null, null); defaultNetwork = _networkDao.findById(newNetwork.getId()); } else if (virtualNetworks.size() > 1) { throw new InvalidParameterValueException("More than 1 default Isolated networks are found for account " + owner + "; please specify networkIds"); @@ -3433,7 +3437,8 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager NetworkVO defaultNetwork = null; List requiredOfferings = _networkOfferingDao.listByAvailability(Availability.Required, false); if (requiredOfferings.size() < 1) { - throw new InvalidParameterValueException("Unable to find network offering with availability=" + Availability.Required + " to automatically create the network as a part of vm creation"); + throw new InvalidParameterValueException("Unable to find network offering with availability=" + + Availability.Required + " to automatically create the network as a part of vm creation"); } PhysicalNetwork physicalNetwork = _networkMgr.translateZoneIdToPhysicalNetwork(zone.getId()); @@ -3442,17 +3447,21 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager List virtualNetworks = _networkMgr.listNetworksForAccount(newAccount.getId(), zone.getId(), Network.GuestType.Isolated); if (virtualNetworks.isEmpty()) { - s_logger.debug("Creating network for account " + newAccount + " from the network offering id=" + requiredOfferings.get(0).getId() + " as a part of deployVM process"); - Network newNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), newAccount.getAccountName() + "-network", newAccount.getAccountName() + "-network", null, null, - null, null, newAccount, false, null, physicalNetwork, zone.getId(), ACLType.Account, null); + s_logger.debug("Creating network for account " + newAccount + " from the network offering id=" + + requiredOfferings.get(0).getId() + " as a part of deployVM process"); + Network newNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), + newAccount.getAccountName() + "-network", newAccount.getAccountName() + "-network", null, null, + null, null, newAccount, null, physicalNetwork, zone.getId(), ACLType.Account, null, null); defaultNetwork = _networkDao.findById(newNetwork.getId()); } else if (virtualNetworks.size() > 1) { - throw new InvalidParameterValueException("More than 1 default Isolated networks are found for account " + newAccount + "; please specify networkIds"); + throw new InvalidParameterValueException("More than 1 default Isolated networks are found " + + "for account " + newAccount + "; please specify networkIds"); } else { defaultNetwork = virtualNetworks.get(0); } } else { - throw new InvalidParameterValueException("Required network offering id=" + requiredOfferings.get(0).getId() + " is not in " + NetworkOffering.State.Enabled); + throw new InvalidParameterValueException("Required network offering id=" + + requiredOfferings.get(0).getId() + " is not in " + NetworkOffering.State.Enabled); } applicableNetworks.add(defaultNetwork); @@ -3557,5 +3566,20 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager return vm; } + @Override + public boolean plugNic(Network network, NicTO nic, VirtualMachineTO vm, + ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException, + InsufficientCapacityException { + //not supported + throw new UnsupportedOperationException("Plug nic is not supported for vm of type " + vm.getType()); + } + + + @Override + public boolean unplugNic(Network network, NicTO nic, VirtualMachineTO vm, + ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException { + //not supported + throw new UnsupportedOperationException("Unplug nic is not supported for vm of type " + vm.getType()); + } } diff --git a/server/src/com/cloud/vm/VirtualMachineGuru.java b/server/src/com/cloud/vm/VirtualMachineGuru.java index f736310ebb8..f8355f580cf 100644 --- a/server/src/com/cloud/vm/VirtualMachineGuru.java +++ b/server/src/com/cloud/vm/VirtualMachineGuru.java @@ -13,9 +13,15 @@ package com.cloud.vm; import com.cloud.agent.api.StopAnswer; +import com.cloud.agent.api.to.NicTO; +import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.manager.Commands; import com.cloud.deploy.DeployDestination; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InsufficientNetworkCapacityException; import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.Network; /** * A VirtualMachineGuru knows how to process a certain type of virtual machine. @@ -68,4 +74,34 @@ public interface VirtualMachineGuru { * @return id if the handler works for this vm and can parse id. null if not. */ Long convertToId(String vmName); + + /** + * Prepare for a nic to be plugged into the network. + * @param network + * @param nic + * @param vm + * @param context + * @param dest TODO + * @return + * @throws ConcurrentOperationException + * @throws ResourceUnavailableException + * @throws InsufficientNetworkCapacityException + */ + boolean plugNic(Network network, NicTO nic, VirtualMachineTO vm, + ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, + ResourceUnavailableException, InsufficientCapacityException; + + /** + * A nic is unplugged from this network. + * @param network + * @param nic + * @param vm + * @param context + * @param dest TODO + * @return + * @throws ConcurrentOperationException + * @throws ResourceUnavailableException + */ + boolean unplugNic(Network network, NicTO nic, VirtualMachineTO vm, + ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException; } diff --git a/server/src/com/cloud/vm/VirtualMachineManager.java b/server/src/com/cloud/vm/VirtualMachineManager.java index 3387a8e22e7..56dc483be34 100644 --- a/server/src/com/cloud/vm/VirtualMachineManager.java +++ b/server/src/com/cloud/vm/VirtualMachineManager.java @@ -12,9 +12,11 @@ // Automatically generated by addcopyright.py at 04/03/2012 package com.cloud.vm; +import java.net.URI; import java.util.List; import java.util.Map; +import com.cloud.agent.api.to.NicTO; import com.cloud.deploy.DeployDestination; import com.cloud.deploy.DeploymentPlan; import com.cloud.exception.AgentUnavailableException; @@ -26,6 +28,7 @@ import com.cloud.exception.OperationTimedoutException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.exception.VirtualMachineMigrationException; import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.network.Network; import com.cloud.network.NetworkVO; import com.cloud.offering.ServiceOffering; import com.cloud.service.ServiceOfferingVO; @@ -132,4 +135,33 @@ public interface VirtualMachineManager extends Manager { */ boolean upgradeVmDb(long vmId, long serviceOfferingId); + /** + * @param vm + * @param network + * @param requested TODO + * @return + * @throws ConcurrentOperationException + * @throws ResourceUnavailableException + * @throws InsufficientCapacityException + */ + NicProfile addVmToNetwork(VirtualMachine vm, Network network, NicProfile requested) throws ConcurrentOperationException, + ResourceUnavailableException, InsufficientCapacityException; + + /** + * @param vm + * @param network + * @param broadcastUri TODO + * @return + * @throws ResourceUnavailableException + * @throws ConcurrentOperationException + */ + boolean removeVmFromNetwork(VirtualMachine vm, Network network, URI broadcastUri) throws ConcurrentOperationException, ResourceUnavailableException; + + /** + * @param nic + * @param hypervisorType + * @return + */ + NicTO toNicTO(NicProfile nic, HypervisorType hypervisorType); + } diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index b73d0fd8e48..06699aee022 100755 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -12,6 +12,7 @@ // Automatically generated by addcopyright.py at 04/03/2012 package com.cloud.vm; +import java.net.URI; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -57,6 +58,7 @@ import com.cloud.agent.api.StartupRoutingCommand; import com.cloud.agent.api.StartupRoutingCommand.VmState; import com.cloud.agent.api.StopAnswer; import com.cloud.agent.api.StopCommand; +import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.manager.Commands; import com.cloud.agent.manager.allocator.HostAllocator; @@ -103,6 +105,7 @@ import com.cloud.hypervisor.HypervisorGuruManager; import com.cloud.network.Network; import com.cloud.network.NetworkManager; import com.cloud.network.NetworkVO; +import com.cloud.network.dao.NetworkDao; import com.cloud.offering.ServiceOffering; import com.cloud.org.Cluster; import com.cloud.resource.ResourceManager; @@ -217,6 +220,8 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene protected StoragePoolDao _storagePoolDao; @Inject protected HypervisorGuruManager _hvGuruMgr; + @Inject + protected NetworkDao _networkDao; @Inject(adapter = DeploymentPlanner.class) protected Adapters _planners; @@ -748,11 +753,10 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene reuseVolume = true; } - VirtualMachineTO vmTO = null; Commands cmds = null; vmGuru.finalizeVirtualMachineProfile(vmProfile, dest, ctx); - vmTO = hvGuru.implement(vmProfile); + VirtualMachineTO vmTO = hvGuru.implement(vmProfile); cmds = new Commands(OnError.Stop); cmds.addCommand(new StartCommand(vmTO)); @@ -2128,7 +2132,8 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene List nics = _nicsDao.listByVmId(profile.getId()); for (NicVO nic : nics) { Network network = _networkMgr.getNetwork(nic.getNetworkId()); - NicProfile nicProfile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), null, _networkMgr.isSecurityGroupSupportedInNetwork(network), _networkMgr.getNetworkTag(profile.getHypervisorType(), network)); + NicProfile nicProfile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), null, + _networkMgr.isSecurityGroupSupportedInNetwork(network), _networkMgr.getNetworkTag(profile.getHypervisorType(), network)); profile.addNic(nicProfile); } @@ -2426,4 +2431,119 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene vmForUpdate.setServiceOfferingId(newSvcOff.getId()); return _vmDao.update(vmId, vmForUpdate); } + + @Override + public NicProfile addVmToNetwork(VirtualMachine vm, Network network, NicProfile requested) throws ConcurrentOperationException, + ResourceUnavailableException, InsufficientCapacityException { + + s_logger.debug("Adding vm " + vm + " to network " + network); + VMInstanceVO vmVO = _vmDao.findById(vm.getId()); + NetworkVO networkVO = _networkDao.findById(network.getId()); + ReservationContext context = new ReservationContextImpl(null, null, _accountMgr.getActiveUser(User.UID_SYSTEM), + _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM)); + + VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vmVO, null, + null, null, null); + + DataCenter dc = _configMgr.getZone(network.getDataCenterId()); + Host host = _hostDao.findById(vm.getHostId()); + DeployDestination dest = new DeployDestination(dc, null, null, host); + + NicProfile nic = null; + String broadcastUri = null; + if (requested != null && requested.getBroadCastUri() != null) { + broadcastUri = requested.getBroadCastUri().toString(); + NicVO nicVO = _nicsDao.findByInstanceIdNetworkIdAndBroadcastUri(network.getId(), vm.getId(), broadcastUri); + if (nicVO != null) { + nic = _networkMgr.getNicProfile(vm, network.getId()); + } + } + + if (nic == null) { + s_logger.debug("Allocating nic for the " + vm + " in network " + network); + //1) allocate nic and prepare nic if needed + int deviceId = _nicsDao.countNics(vm.getId()); + + nic = _networkMgr.allocateNic(requested, network, false, + deviceId, vmProfile).first(); + + if (nic == null) { + throw new CloudRuntimeException("Failed to allocate nic for vm " + vm + " in network " + network); + } + + s_logger.debug("Nic is allocated successfully for vm " + vm + " in network " + network); + + nic = _networkMgr.prepareNic(vmProfile, dest, context, nic.getId(), networkVO); + + s_logger.debug("Nic is prepared successfully for vm " + vm + " in network " + network); + + } + + //2) Convert vmProfile to vmTO + HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vmProfile.getVirtualMachine().getHypervisorType()); + VirtualMachineTO vmTO = hvGuru.implement(vmProfile); + + //3) Convert nicProfile to NicTO + NicTO nicTO = toNicTO(nic, vmProfile.getVirtualMachine().getHypervisorType()); + + //4) plug the nic to the vm + VirtualMachineGuru vmGuru = getVmGuru(vmVO); + + s_logger.debug("Plugging nic for vm " + vm + " in network " + network); + if (vmGuru.plugNic(network, nicTO, vmTO, context, dest)) { + s_logger.debug("Nic is plugged successfully for vm " + vm + " in network " + network + ". Vm is a part of network now"); + return nic; + } else { + s_logger.warn("Failed to plug nic to the vm " + vm + " in network " + network); + return null; + } + } + + @Override + public NicTO toNicTO(NicProfile nic, HypervisorType hypervisorType) { + HypervisorGuru hvGuru = _hvGuruMgr.getGuru(hypervisorType); + + NicTO nicTO = hvGuru.toNicTO(nic); + return nicTO; + } + + @Override + public boolean removeVmFromNetwork(VirtualMachine vm, Network network, URI broadcastUri) throws ConcurrentOperationException, ResourceUnavailableException { + VMInstanceVO vmVO = _vmDao.findById(vm.getId()); + NetworkVO networkVO = _networkDao.findById(network.getId()); + ReservationContext context = new ReservationContextImpl(null, null, _accountMgr.getActiveUser(User.UID_SYSTEM), + _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM)); + + VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vmVO, null, + null, null, null); + + DataCenter dc = _configMgr.getZone(network.getDataCenterId()); + Host host = _hostDao.findById(vm.getHostId()); + DeployDestination dest = new DeployDestination(dc, null, null, host); + + //1) Release the nic + NicProfile nic = _networkMgr.releaseNic(vmProfile, networkVO, broadcastUri); + + //2) Convert vmProfile to vmTO + VirtualMachineGuru vmGuru = getVmGuru(vmVO); + HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vmProfile.getVirtualMachine().getHypervisorType()); + VirtualMachineTO vmTO = hvGuru.implement(vmProfile); + + NicTO nicTO = toNicTO(nic, vmProfile.getVirtualMachine().getHypervisorType()); + + s_logger.debug("Un-plugging nic for vm " + vm + " from network " + network); + boolean result = vmGuru.unplugNic(network, nicTO, vmTO, context, dest); + //4) Unplug the nic + if (result) { + s_logger.debug("Nic is unplugged successfully for vm " + vm + " in network " + network ); + } else { + s_logger.warn("Failed to unplug nic for the vm " + vm + " from network " + network); + return false; + } + + //6) Remove the nic + _networkMgr.removeNic(vmProfile, network); + return result; + } + } diff --git a/server/src/com/cloud/vm/dao/DomainRouterDao.java b/server/src/com/cloud/vm/dao/DomainRouterDao.java index af5cd32fc99..11f93bbb6ca 100755 --- a/server/src/com/cloud/vm/dao/DomainRouterDao.java +++ b/server/src/com/cloud/vm/dao/DomainRouterDao.java @@ -64,16 +64,7 @@ public interface DomainRouterDao extends GenericDao { * @param hostId id of the host. null if to get all. * @return list of DomainRouterVO */ - public List listVirtualByHostId(Long hostId); - - /** - * list virtual machine routers by host id. exclude destroyed, stopped, expunging VM, - * pass in null to get all - * virtual machine routers. - * @param hostId id of the host. null if to get all. - * @return list of DomainRouterVO - */ - public List listVirtualUpByHostId(Long hostId); + public List listIsolatedByHostId(Long hostId); /** * Find the list of domain routers for a domain @@ -101,4 +92,43 @@ public interface DomainRouterDao extends GenericDao { List listByNetworkAndRole(long networkId, Role role); List listByElementId(long elementId); + + /** + * Persists the domain router instance + creates the reference to the guest network (if not null) + * @param guestNetworks TODO + * @return + */ + DomainRouterVO persist(DomainRouterVO router, List guestNetworks); + + /** + * @param routerId + * @return + */ + List getRouterNetworks(long routerId); + + /** + * @param vpcId + * @return + */ + List listRoutersByVpcId(long vpcId); + + /** + * @param routerId + * @param guestNetwork + */ + void addRouterToGuestNetwork(DomainRouterVO router, Network guestNetwork); + + /** + * @param routerId + * @param guestNetworkId + */ + void removeRouterFromNetwork(long routerId, long guestNetworkId); + + /** + * @param routerId + * @param guestNetworkId + * @return + */ + boolean isRouterPartOfGuestNetwork(long routerId, long guestNetworkId); + } diff --git a/server/src/com/cloud/vm/dao/DomainRouterDaoImpl.java b/server/src/com/cloud/vm/dao/DomainRouterDaoImpl.java index 1f28c3ad547..f0257ac12d7 100755 --- a/server/src/com/cloud/vm/dao/DomainRouterDaoImpl.java +++ b/server/src/com/cloud/vm/dao/DomainRouterDaoImpl.java @@ -16,15 +16,16 @@ import java.util.List; import javax.ejb.Local; -import org.apache.log4j.Logger; - import com.cloud.host.HostVO; import com.cloud.host.dao.HostDaoImpl; import com.cloud.network.Network; -import com.cloud.network.NetworkVO; -import com.cloud.network.dao.NetworkDaoImpl; +import com.cloud.network.RouterNetworkDaoImpl; +import com.cloud.network.RouterNetworkVO; import com.cloud.network.router.VirtualRouter.Role; +import com.cloud.user.UserStatisticsVO; +import com.cloud.user.dao.UserStatisticsDaoImpl; import com.cloud.utils.component.ComponentLocator; +import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.JoinBuilder.JoinType; import com.cloud.utils.db.SearchBuilder; @@ -37,15 +38,16 @@ import com.cloud.vm.VirtualMachine.State; @Local(value = { DomainRouterDao.class }) public class DomainRouterDaoImpl extends GenericDaoBase implements DomainRouterDao { - private static final Logger s_logger = Logger.getLogger(DomainRouterDaoImpl.class); protected final SearchBuilder AllFieldsSearch; protected final SearchBuilder IdNetworkIdStatesSearch; protected final SearchBuilder HostUpSearch; protected final SearchBuilder StateNetworkTypeSearch; protected final SearchBuilder OutsidePodSearch; - NetworkDaoImpl _networksDao = ComponentLocator.inject(NetworkDaoImpl.class); HostDaoImpl _hostsDao = ComponentLocator.inject(HostDaoImpl.class); + RouterNetworkDaoImpl _routerNetworkDao = ComponentLocator.inject(RouterNetworkDaoImpl.class); + UserStatisticsDaoImpl _userStatsDao = ComponentLocator.inject(UserStatisticsDaoImpl.class); + protected final SearchBuilder VpcSearch; protected DomainRouterDaoImpl() { AllFieldsSearch = createSearchBuilder(); @@ -56,37 +58,55 @@ public class DomainRouterDaoImpl extends GenericDaoBase im AllFieldsSearch.and("host", AllFieldsSearch.entity().getHostId(), Op.EQ); AllFieldsSearch.and("lastHost", AllFieldsSearch.entity().getLastHostId(), Op.EQ); AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), Op.EQ); - AllFieldsSearch.and("network", AllFieldsSearch.entity().getNetworkId(), Op.EQ); + SearchBuilder joinRouterNetwork = _routerNetworkDao.createSearchBuilder(); + joinRouterNetwork.and("networkId", joinRouterNetwork.entity().getNetworkId(), Op.EQ); + AllFieldsSearch.join("networkRouter", joinRouterNetwork, joinRouterNetwork.entity().getRouterId(), AllFieldsSearch.entity().getId(), JoinType.INNER); AllFieldsSearch.and("podId", AllFieldsSearch.entity().getPodIdToDeployIn(), Op.EQ); AllFieldsSearch.and("elementId", AllFieldsSearch.entity().getElementId(), Op.EQ); + AllFieldsSearch.and("vpcId", AllFieldsSearch.entity().getVpcId(), Op.EQ); AllFieldsSearch.done(); + + VpcSearch = createSearchBuilder(); + VpcSearch.and("role", VpcSearch.entity().getRole(), Op.EQ); + VpcSearch.and("vpcId", VpcSearch.entity().getVpcId(), Op.EQ); + VpcSearch.done(); IdNetworkIdStatesSearch = createSearchBuilder(); IdNetworkIdStatesSearch.and("id", IdNetworkIdStatesSearch.entity().getId(), Op.EQ); - IdNetworkIdStatesSearch.and("network", IdNetworkIdStatesSearch.entity().getNetworkId(), Op.EQ); + SearchBuilder joinRouterNetwork1 = _routerNetworkDao.createSearchBuilder(); + joinRouterNetwork1.and("networkId", joinRouterNetwork1.entity().getNetworkId(), Op.EQ); + IdNetworkIdStatesSearch.join("networkRouter", joinRouterNetwork1, joinRouterNetwork1.entity().getRouterId(), IdNetworkIdStatesSearch.entity().getId(), JoinType.INNER); IdNetworkIdStatesSearch.and("states", IdNetworkIdStatesSearch.entity().getState(), Op.IN); IdNetworkIdStatesSearch.done(); HostUpSearch = createSearchBuilder(); HostUpSearch.and("host", HostUpSearch.entity().getHostId(), Op.EQ); HostUpSearch.and("states", HostUpSearch.entity().getState(), Op.NIN); - SearchBuilder joinNetwork = _networksDao.createSearchBuilder(); - joinNetwork.and("type", joinNetwork.entity().getGuestType(), Op.EQ); - HostUpSearch.join("network", joinNetwork, joinNetwork.entity().getId(), HostUpSearch.entity().getNetworkId(), JoinType.INNER); + SearchBuilder joinRouterNetwork3 = _routerNetworkDao.createSearchBuilder(); + joinRouterNetwork3.and("networkId", joinRouterNetwork3.entity().getNetworkId(), Op.EQ); + joinRouterNetwork3.and("type", joinRouterNetwork3.entity().getGuestType(), Op.EQ); + HostUpSearch.join("networkRouter", joinRouterNetwork3, joinRouterNetwork3.entity().getRouterId(), HostUpSearch.entity().getId(), JoinType.INNER); HostUpSearch.done(); - + StateNetworkTypeSearch = createSearchBuilder(); StateNetworkTypeSearch.and("state", StateNetworkTypeSearch.entity().getState(), Op.EQ); - SearchBuilder joinStateNetwork = _networksDao.createSearchBuilder(); - joinStateNetwork.and("type", joinStateNetwork.entity().getGuestType(), Op.EQ); - StateNetworkTypeSearch.join("network", joinStateNetwork, joinStateNetwork.entity().getId(), StateNetworkTypeSearch.entity().getNetworkId(), JoinType.INNER); + SearchBuilder joinRouterNetwork4 = _routerNetworkDao.createSearchBuilder(); + joinRouterNetwork4.and("networkId", joinRouterNetwork4.entity().getNetworkId(), Op.EQ); + joinRouterNetwork4.and("type", joinRouterNetwork4.entity().getGuestType(), Op.EQ); + StateNetworkTypeSearch.join("networkRouter", joinRouterNetwork4, joinRouterNetwork4.entity().getRouterId(), StateNetworkTypeSearch.entity().getId(), JoinType.INNER); + SearchBuilder joinHost = _hostsDao.createSearchBuilder(); joinHost.and("mgmtServerId", joinHost.entity().getManagementServerId(), Op.EQ); - StateNetworkTypeSearch.join("host", joinHost, joinHost.entity().getId(), StateNetworkTypeSearch.entity().getHostId(), JoinType.INNER); + StateNetworkTypeSearch.join("host", joinHost, joinHost.entity().getId(), + StateNetworkTypeSearch.entity().getHostId(), JoinType.INNER); StateNetworkTypeSearch.done(); - + + OutsidePodSearch = createSearchBuilder(); - OutsidePodSearch.and("network", OutsidePodSearch.entity().getNetworkId(), Op.EQ); + SearchBuilder joinRouterNetwork2 = _routerNetworkDao.createSearchBuilder(); + joinRouterNetwork2.and("networkId", joinRouterNetwork2.entity().getNetworkId(), Op.EQ); + OutsidePodSearch.join("networkRouter", joinRouterNetwork2, joinRouterNetwork2.entity().getRouterId(), + OutsidePodSearch.entity().getId(), JoinType.INNER); OutsidePodSearch.and("podId", OutsidePodSearch.entity().getPodIdToDeployIn(), Op.NEQ); OutsidePodSearch.and("state", OutsidePodSearch.entity().getState(), Op.EQ); OutsidePodSearch.and("role", OutsidePodSearch.entity().getRole(), Op.EQ); @@ -150,23 +170,12 @@ public class DomainRouterDaoImpl extends GenericDaoBase im } @Override - public List listVirtualByHostId(Long hostId) { + public List listIsolatedByHostId(Long hostId) { SearchCriteria sc = HostUpSearch.create(); if (hostId != null) { sc.setParameters("host", hostId); } - sc.setJoinParameters("network", "type", Network.GuestType.Isolated); - return listBy(sc); - } - - @Override - public List listVirtualUpByHostId(Long hostId) { - SearchCriteria sc = HostUpSearch.create(); - if (hostId != null) { - sc.setParameters("host", hostId); - } - sc.setParameters("states", State.Destroyed, State.Stopped, State.Expunging); - sc.setJoinParameters("network", "type", Network.GuestType.Isolated); + sc.setJoinParameters("networkRouter", "type", Network.GuestType.Isolated); return listBy(sc); } @@ -180,7 +189,7 @@ public class DomainRouterDaoImpl extends GenericDaoBase im @Override public List findByNetwork(long networkId) { SearchCriteria sc = AllFieldsSearch.create(); - sc.setParameters("network", networkId); + sc.setJoinParameters("networkRouter", "networkId", networkId); return listBy(sc); } @@ -195,7 +204,7 @@ public class DomainRouterDaoImpl extends GenericDaoBase im @Override public List listActive(long networkId) { SearchCriteria sc = IdNetworkIdStatesSearch.create(); - sc.setParameters("network", networkId); + sc.setJoinParameters("networkRouter", "networkId", networkId); sc.setParameters("states", State.Running, State.Migrating, State.Stopping, State.Starting); return listBy(sc); } @@ -204,7 +213,7 @@ public class DomainRouterDaoImpl extends GenericDaoBase im public List listByStateAndNetworkType(State state, Network.GuestType type, long mgmtSrvrId) { SearchCriteria sc = StateNetworkTypeSearch.create(); sc.setParameters("state", state); - sc.setJoinParameters("network", "type", type); + sc.setJoinParameters("networkRouter", "type", type); sc.setJoinParameters("host", "mgmtServerId", mgmtSrvrId); return listBy(sc); } @@ -212,7 +221,7 @@ public class DomainRouterDaoImpl extends GenericDaoBase im @Override public List findByNetworkOutsideThePod(long networkId, long podId, State state, Role role) { SearchCriteria sc = OutsidePodSearch.create(); - sc.setParameters("network", networkId); + sc.setJoinParameters("networkRouter", "networkId", networkId); sc.setParameters("podId", podId); sc.setParameters("state", state); sc.setParameters("role", role); @@ -222,7 +231,7 @@ public class DomainRouterDaoImpl extends GenericDaoBase im @Override public List listByNetworkAndPodAndRole(long networkId, long podId, Role role) { SearchCriteria sc = AllFieldsSearch.create(); - sc.setParameters("network", networkId); + sc.setJoinParameters("networkRouter", "networkId", networkId); sc.setParameters("podId", podId); sc.setParameters("role", role); return listBy(sc); @@ -231,7 +240,7 @@ public class DomainRouterDaoImpl extends GenericDaoBase im @Override public List listByNetworkAndRole(long networkId, Role role) { SearchCriteria sc = AllFieldsSearch.create(); - sc.setParameters("network", networkId); + sc.setJoinParameters("networkRouter", "networkId", networkId); sc.setParameters("role", role); return listBy(sc); } @@ -242,4 +251,69 @@ public class DomainRouterDaoImpl extends GenericDaoBase im sc.setParameters("elementId", elementId); return listBy(sc); } + + @Override + @DB + public DomainRouterVO persist(DomainRouterVO router, List guestNetworks) { + Transaction txn = Transaction.currentTxn(); + txn.start(); + + // 1) create network + DomainRouterVO newRouter = super.persist(router); + + if (guestNetworks != null && !guestNetworks.isEmpty()) { + // 2) add router to the network + for (Network guestNetwork : guestNetworks) { + addRouterToGuestNetwork(router, guestNetwork); + } + } + + txn.commit(); + return newRouter; + } + + @Override + @DB + public void addRouterToGuestNetwork(DomainRouterVO router, Network guestNetwork) { + Transaction txn = Transaction.currentTxn(); + txn.start(); + //1) add router to network + RouterNetworkVO routerNtwkMap = new RouterNetworkVO(router.getId(), guestNetwork.getId(), guestNetwork.getGuestType()); + _routerNetworkDao.persist(routerNtwkMap); + //2) create user stats entry for the network + UserStatisticsVO stats = _userStatsDao.findBy(router.getAccountId(), router.getDataCenterIdToDeployIn(), + guestNetwork.getId(), null, router.getId(), router.getType().toString()); + if (stats == null) { + stats = new UserStatisticsVO(router.getAccountId(), router.getDataCenterIdToDeployIn(), null, router.getId(), + router.getType().toString(), guestNetwork.getId()); + _userStatsDao.persist(stats); + } + txn.commit(); + } + + @Override + public void removeRouterFromNetwork(long routerId, long guestNetworkId) { + RouterNetworkVO routerNtwkMap = _routerNetworkDao.findByRouterAndNetwork(routerId, guestNetworkId); + _routerNetworkDao.remove(routerNtwkMap.getId()); + } + + @Override + public List getRouterNetworks(long routerId) { + return _routerNetworkDao.getRouterNetworks(routerId); + } + + @Override + public List listRoutersByVpcId(long vpcId) { + SearchCriteria sc = VpcSearch.create(); + sc.setParameters("vpcId", vpcId); + sc.setParameters("role", Role.VIRTUAL_ROUTER); + return listBy(sc); + } + + @Override + public boolean isRouterPartOfGuestNetwork(long routerId, long guestNetworkId) { + RouterNetworkVO routerNtwkMap = _routerNetworkDao.findByRouterAndNetwork(routerId, guestNetworkId); + return routerNtwkMap != null; + } + } diff --git a/server/src/com/cloud/vm/dao/NicDao.java b/server/src/com/cloud/vm/dao/NicDao.java index 2748ba22231..3dca809e3e9 100644 --- a/server/src/com/cloud/vm/dao/NicDao.java +++ b/server/src/com/cloud/vm/dao/NicDao.java @@ -37,4 +37,17 @@ public interface NicDao extends GenericDao { NicVO findByIp4AddressAndNetworkId(String ip4Address, long networkId); NicVO findDefaultNicForVM(long instanceId); + + /** + * @param networkId + * @param instanceId + * @return + */ + NicVO findNonReleasedByInstanceIdAndNetworkId(long networkId, long instanceId); + + String getIpAddress(long networkId, long instanceId); + + int countNics(long instanceId); + + NicVO findByInstanceIdNetworkIdAndBroadcastUri(long networkId, long instanceId, String broadcastUri); } diff --git a/server/src/com/cloud/vm/dao/NicDaoImpl.java b/server/src/com/cloud/vm/dao/NicDaoImpl.java index 1e3d6e06363..77f54ce81cd 100644 --- a/server/src/com/cloud/vm/dao/NicDaoImpl.java +++ b/server/src/com/cloud/vm/dao/NicDaoImpl.java @@ -22,6 +22,8 @@ import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Func; import com.cloud.utils.db.SearchCriteria.Op; +import com.cloud.vm.Nic; +import com.cloud.vm.Nic.State; import com.cloud.vm.NicVO; import com.cloud.vm.VirtualMachine; @@ -29,6 +31,9 @@ import com.cloud.vm.VirtualMachine; public class NicDaoImpl extends GenericDaoBase implements NicDao { private final SearchBuilder AllFieldsSearch; private final GenericSearchBuilder IpSearch; + private final SearchBuilder NonReleasedSearch; + final GenericSearchBuilder CountBy; + protected NicDaoImpl() { super(); @@ -39,6 +44,7 @@ public class NicDaoImpl extends GenericDaoBase implements NicDao { AllFieldsSearch.and("vmType", AllFieldsSearch.entity().getVmType(), Op.EQ); AllFieldsSearch.and("address", AllFieldsSearch.entity().getIp4Address(), Op.EQ); AllFieldsSearch.and("isDefault", AllFieldsSearch.entity().isDefaultNic(), Op.EQ); + AllFieldsSearch.and("broadcastUri", AllFieldsSearch.entity().getBroadcastUri(), Op.EQ); AllFieldsSearch.done(); IpSearch = createSearchBuilder(String.class); @@ -46,6 +52,18 @@ public class NicDaoImpl extends GenericDaoBase implements NicDao { IpSearch.and("network", IpSearch.entity().getNetworkId(), Op.EQ); IpSearch.and("address", IpSearch.entity().getIp4Address(), Op.NNULL); IpSearch.done(); + + NonReleasedSearch = createSearchBuilder(); + NonReleasedSearch.and("instance", NonReleasedSearch.entity().getInstanceId(), Op.EQ); + NonReleasedSearch.and("network", NonReleasedSearch.entity().getNetworkId(), Op.EQ); + NonReleasedSearch.and("state", NonReleasedSearch.entity().getState(), Op.NOTIN); + NonReleasedSearch.done(); + + CountBy = createSearchBuilder(Integer.class); + CountBy.select(null, Func.COUNT, CountBy.entity().getId()); + CountBy.and("vmId", CountBy.entity().getInstanceId(), Op.EQ); + CountBy.and("removed", CountBy.entity().getRemoved(), Op.NULL); + CountBy.done(); } @Override @@ -123,4 +141,40 @@ public class NicDaoImpl extends GenericDaoBase implements NicDao { sc.setParameters("isDefault", 1); return findOneBy(sc); } + + @Override + public NicVO findNonReleasedByInstanceIdAndNetworkId(long networkId, long instanceId) { + SearchCriteria sc = NonReleasedSearch.create(); + sc.setParameters("network", networkId); + sc.setParameters("instance", instanceId); + sc.setParameters("state", State.Releasing, Nic.State.Deallocating); + return findOneBy(sc); + } + + @Override + public String getIpAddress(long networkId, long instanceId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("network", networkId); + sc.setParameters("instance", instanceId); + return findOneBy(sc).getIp4Address(); + } + + @Override + public int countNics(long instanceId) { + SearchCriteria sc = CountBy.create(); + sc.setParameters("vmId", instanceId); + List results = customSearch(sc, null); + return results.get(0); + } + + + @Override + public NicVO findByInstanceIdNetworkIdAndBroadcastUri(long networkId, long instanceId, String broadcastUri) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("network", networkId); + sc.setParameters("instance", instanceId); + sc.setParameters("broadcastUri", broadcastUri); + return findOneBy(sc); + } + } diff --git a/server/test/com/cloud/network/MockNetworkManagerImpl.java b/server/test/com/cloud/network/MockNetworkManagerImpl.java index b2b4ce04ccc..83a5f9717dd 100755 --- a/server/test/com/cloud/network/MockNetworkManagerImpl.java +++ b/server/test/com/cloud/network/MockNetworkManagerImpl.java @@ -12,6 +12,7 @@ // Automatically generated by addcopyright.py at 04/03/2012 package com.cloud.network; +import java.net.URI; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -44,11 +45,13 @@ import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; import com.cloud.network.Networks.TrafficType; import com.cloud.network.addr.PublicIp; +import com.cloud.network.element.NetworkElement; import com.cloud.network.element.RemoteAccessVPNServiceProvider; import com.cloud.network.element.UserDataServiceProvider; import com.cloud.network.guru.NetworkGuru; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.StaticNat; +import com.cloud.network.vpc.Vpc; import com.cloud.offering.NetworkOffering; import com.cloud.offerings.NetworkOfferingVO; import com.cloud.user.Account; @@ -72,19 +75,19 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager, NetworkS } @Override - public IpAddress associateIP(long ipId) throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException, ResourceUnavailableException { + public IpAddress associateIPToGuestNetwork(long ipId, long networkId) throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException, ResourceUnavailableException { // TODO Auto-generated method stub return null; } @Override - public boolean disassociateIpAddress(long ipAddressId) { + public boolean releaseIpAddress(long ipAddressId) { // TODO Auto-generated method stub return false; } @Override - public Network createNetwork(CreateNetworkCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException { + public Network createGuestNetwork(CreateNetworkCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException { // TODO Auto-generated method stub return null; } @@ -178,21 +181,14 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager, NetworkS } - @Override - public PublicIp assignSourceNatIpAddress(Account owner, Network network, long callerId) throws ConcurrentOperationException, InsufficientAddressCapacityException { - // TODO Auto-generated method stub - return null; - } - - @Override - public boolean releasePublicIpAddress(long id, long userId, Account caller) { + public boolean disassociatePublicIpAddress(long id, long userId, Account caller) { // TODO Auto-generated method stub return false; } @Override - public List listPublicIpAddressesInVirtualNetwork(long accountId, long dcId, Boolean sourceNat, Long associatedNetworkId) { + public List listPublicIpsAssignedToGuestNtwk(long accountId, long associatedNetworkId, Boolean sourceNat) { // TODO Auto-generated method stub return null; } @@ -206,7 +202,7 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager, NetworkS @Override public List setupNetwork(Account owner, NetworkOfferingVO offering, Network predefined, DeploymentPlan plan, String name, String displayText, boolean errorIfAlreadySetup, Long domainId, - ACLType aclType, Boolean subdomainAccess) throws ConcurrentOperationException { + ACLType aclType, Boolean subdomainAccess, Long vpcId) throws ConcurrentOperationException { // TODO Auto-generated method stub return null; } @@ -310,8 +306,8 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager, NetworkS } @Override - public Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, String networkDomain, Account owner, boolean isSecurityGroupEnabled, - Long domainId, PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType, Boolean subdomainAccess) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException { + public Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, String networkDomain, Account owner, Long domainId, + PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException { // TODO Auto-generated method stub return null; } @@ -645,12 +641,6 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager, NetworkS return false; } - @Override - public PhysicalNetworkServiceProvider addDefaultVirtualRouterToPhysicalNetwork(long physicalNetworkId) { - // TODO Auto-generated method stub - return null; - } - @Override public Map getNetworkOfferingServiceCapabilities(NetworkOffering offering, Service service) { // TODO Auto-generated method stub @@ -707,13 +697,7 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager, NetworkS // TODO Auto-generated method stub return false; } - - @Override - public PhysicalNetworkServiceProvider addDefaultSecurityGroupProviderToPhysicalNetwork(long physicalNetworkId) { - // TODO Auto-generated method stub - return null; - } - + @Override public List getPhysicalNetworkInfo(long dcId, HypervisorType hypervisorType) { // TODO Auto-generated method stub @@ -874,10 +858,184 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager, NetworkS } /* (non-Javadoc) - * @see com.cloud.network.NetworkService#allocateIP(long, com.cloud.user.Account) + * @see com.cloud.network.NetworkService#isVmPartOfNetwork(long, long) */ @Override - public IpAddress allocateIP(long networkId, Account ipOwner) throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException { + public boolean isVmPartOfNetwork(long vmId, long ntwkId) { + // TODO Auto-generated method stub + return false; + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkService#associateIP(long, java.lang.Long, java.lang.Long) + */ + @Override + public IpAddress associateIP(long ipId, Long networkId, Long vpcId) throws InsufficientAddressCapacityException, ResourceAllocationException, ResourceUnavailableException, ConcurrentOperationException { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkService#createPrivateNetwork(java.lang.String, java.lang.String, long, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, long) + */ + @Override + public Network createPrivateNetwork(String networkName, String displayText, long physicalNetworkId, String vlan, String startIp, String endIP, String gateway, String netmask, long networkOwnerId) + throws ResourceAllocationException, ConcurrentOperationException, InsufficientCapacityException { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkManager#getAccountNetworkDomain(long, long) + */ + @Override + public String getAccountNetworkDomain(long accountId, long zoneId) { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkManager#getDefaultNetworkDomain() + */ + @Override + public String getDefaultNetworkDomain() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkManager#getNtwkOffDistinctProviders(long) + */ + @Override + public List getNtwkOffDistinctProviders(long networkId) { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkManager#allocateNic(com.cloud.vm.NicProfile, com.cloud.network.Network, java.lang.Boolean, int, com.cloud.vm.VirtualMachineProfile) + */ + @Override + public Pair allocateNic(NicProfile requested, Network network, Boolean isDefaultNic, int deviceId, VirtualMachineProfile vm) + throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException, ConcurrentOperationException { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkManager#prepareNic(com.cloud.vm.VirtualMachineProfile, com.cloud.deploy.DeployDestination, com.cloud.vm.ReservationContext, long, com.cloud.network.NetworkVO) + */ + @Override + public NicProfile prepareNic(VirtualMachineProfile vmProfile, DeployDestination dest, ReservationContext context, long nicId, NetworkVO network) + throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException, ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkManager#releaseNic(com.cloud.vm.VirtualMachineProfile, com.cloud.network.NetworkVO) + */ + @Override + public NicProfile releaseNic(VirtualMachineProfile vmProfile, NetworkVO network) throws ConcurrentOperationException, ResourceUnavailableException { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkManager#removeNic(com.cloud.vm.VirtualMachineProfile, com.cloud.network.Network) + */ + @Override + public void removeNic(VirtualMachineProfile vm, Network network) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkManager#listPublicIpsAssignedToAccount(long, long, java.lang.Boolean) + */ + @Override + public List listPublicIpsAssignedToAccount(long accountId, long dcId, Boolean sourceNat) { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkManager#unassignIPFromVpcNetwork(long) + */ + @Override + public void unassignIPFromVpcNetwork(long ipId) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkManager#getNicProfile(com.cloud.vm.VirtualMachine, long) + */ + @Override + public NicProfile getNicProfile(VirtualMachine vm, long networkId) { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkManager#setupDns(com.cloud.network.Network, com.cloud.network.Network.Provider) + */ + @Override + public boolean setupDns(Network network, Provider provider) { + // TODO Auto-generated method stub + return false; + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkManager#releaseNic(com.cloud.vm.VirtualMachineProfile, com.cloud.network.NetworkVO, java.net.URI) + */ + @Override + public NicProfile releaseNic(VirtualMachineProfile vmProfile, NetworkVO network, URI broadcastUri) throws ConcurrentOperationException, ResourceUnavailableException { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkService#allocateIP(com.cloud.user.Account, boolean, long) + */ + @Override + public IpAddress allocateIP(Account ipOwner, boolean isSystem, long zoneId) throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkService#listNetworksByVpc(long) + */ + @Override + public List listNetworksByVpc(long vpcId) { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkManager#getElementImplementingProvider(java.lang.String) + */ + @Override + public NetworkElement getElementImplementingProvider(String providerName) { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkManager#assignSourceNatIpAddressToGuestNetwork(com.cloud.user.Account, com.cloud.network.Network) + */ + @Override + public PublicIp assignSourceNatIpAddressToGuestNetwork(Account owner, Network guestNetwork) throws InsufficientAddressCapacityException, ConcurrentOperationException { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.cloud.network.NetworkManager#assignSourceNatIpAddressToVpc(com.cloud.user.Account, com.cloud.network.vpc.Vpc) + */ + @Override + public PublicIp assignSourceNatIpAddressToVpc(Account owner, Vpc vpc) throws InsufficientAddressCapacityException, ConcurrentOperationException { // TODO Auto-generated method stub return null; } diff --git a/server/test/com/cloud/vm/MockVirtualMachineManagerImpl.java b/server/test/com/cloud/vm/MockVirtualMachineManagerImpl.java index 5a65a6d13f9..e32b2d74271 100755 --- a/server/test/com/cloud/vm/MockVirtualMachineManagerImpl.java +++ b/server/test/com/cloud/vm/MockVirtualMachineManagerImpl.java @@ -12,12 +12,14 @@ // Automatically generated by addcopyright.py at 04/03/2012 package com.cloud.vm; +import java.net.URI; import java.util.List; import java.util.Map; import javax.ejb.Local; import javax.naming.ConfigurationException; +import com.cloud.agent.api.to.NicTO; import com.cloud.deploy.DeployDestination; import com.cloud.deploy.DeploymentPlan; import com.cloud.exception.AgentUnavailableException; @@ -29,6 +31,7 @@ import com.cloud.exception.OperationTimedoutException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.exception.VirtualMachineMigrationException; import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.network.Network; import com.cloud.network.NetworkVO; import com.cloud.offering.ServiceOffering; import com.cloud.service.ServiceOfferingVO; @@ -235,4 +238,31 @@ public class MockVirtualMachineManagerImpl implements VirtualMachineManager { return false; } + /* (non-Javadoc) + * @see com.cloud.vm.VirtualMachineManager#addVmToNetwork(com.cloud.vm.VirtualMachine, com.cloud.network.Network, com.cloud.vm.NicProfile) + */ + @Override + public NicProfile addVmToNetwork(VirtualMachine vm, Network network, NicProfile requested) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see com.cloud.vm.VirtualMachineManager#removeVmFromNetwork(com.cloud.vm.VirtualMachine, com.cloud.network.Network, java.net.URI) + */ + @Override + public boolean removeVmFromNetwork(VirtualMachine vm, Network network, URI broadcastUri) throws ConcurrentOperationException, ResourceUnavailableException { + // TODO Auto-generated method stub + return false; + } + + /* (non-Javadoc) + * @see com.cloud.vm.VirtualMachineManager#toNicTO(com.cloud.vm.NicProfile, com.cloud.hypervisor.Hypervisor.HypervisorType) + */ + @Override + public NicTO toNicTO(NicProfile nic, HypervisorType hypervisorType) { + // TODO Auto-generated method stub + return null; + } + } diff --git a/setup/apidoc/gen_toc.py b/setup/apidoc/gen_toc.py index 3775f9fbaf8..8fd4602803d 100644 --- a/setup/apidoc/gen_toc.py +++ b/setup/apidoc/gen_toc.py @@ -115,7 +115,8 @@ known_categories = { 'Project': 'Project', 'Lun': 'Storage', 'Pool': 'Pool', - 'Tags': 'Resource tags', + 'Tags': 'Resource Tags', + 'VPC': 'VPC', } diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index 3e0701be767..5a5890f858c 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -208,12 +208,14 @@ CREATE TABLE `cloud`.`networks` ( `created` datetime NOT NULL COMMENT 'date created', `removed` datetime COMMENT 'date removed if not null', `specify_ip_ranges` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'true if the network provides an ability to define ip ranges', + `vpc_id` bigint unsigned COMMENT 'vpc this network belongs to', PRIMARY KEY (`id`), CONSTRAINT `fk_networks__network_offering_id` FOREIGN KEY (`network_offering_id`) REFERENCES `network_offerings`(`id`), CONSTRAINT `fk_networks__data_center_id` FOREIGN KEY (`data_center_id`) REFERENCES `data_center`(`id`) ON DELETE CASCADE, CONSTRAINT `fk_networks__related` FOREIGN KEY(`related`) REFERENCES `networks`(`id`) ON DELETE CASCADE, CONSTRAINT `fk_networks__account_id` FOREIGN KEY(`account_id`) REFERENCES `account`(`id`), CONSTRAINT `fk_networks__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain`(`id`), + CONSTRAINT `fk_networks__vpc_id` FOREIGN KEY(`vpc_id`) REFERENCES `vpc`(`id`), CONSTRAINT `uc_networks__uuid` UNIQUE (`uuid`), INDEX `i_networks__removed`(`removed`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -918,6 +920,7 @@ CREATE TABLE `cloud`.`user_ip_address` ( `network_id` bigint unsigned COMMENT 'network this public ip address is associated with', `physical_network_id` bigint unsigned NOT NULL COMMENT 'physical network id that this configuration is based on', `is_system` int(1) unsigned NOT NULL default '0', + `vpc_id` bigint unsigned COMMENT 'vpc the ip address is associated with', PRIMARY KEY (`id`), UNIQUE (`public_ip_address`, `source_network_id`), CONSTRAINT `fk_user_ip_address__source_network_id` FOREIGN KEY (`source_network_id`) REFERENCES `networks`(`id`), @@ -928,6 +931,7 @@ CREATE TABLE `cloud`.`user_ip_address` ( CONSTRAINT `fk_user_ip_address__data_center_id` FOREIGN KEY (`data_center_id`) REFERENCES `data_center`(`id`) ON DELETE CASCADE, CONSTRAINT `uc_user_ip_address__uuid` UNIQUE (`uuid`), CONSTRAINT `fk_user_ip_address__physical_network_id` FOREIGN KEY (`physical_network_id`) REFERENCES `physical_network`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_user_ip_address__vpc_id` FOREIGN KEY (`vpc_id`) REFERENCES `vpc`(`id`) ON DELETE CASCADE, INDEX `i_user_ip_address__allocated`(`allocated`), INDEX `i_user_ip_address__source_nat`(`source_nat`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -1069,7 +1073,6 @@ CREATE TABLE `cloud`.`domain_router` ( `public_netmask` varchar(15) COMMENT 'netmask used for the domR', `guest_netmask` varchar(15) COMMENT 'netmask used for the guest network', `guest_ip_address` char(40) COMMENT ' ip address in the guest network', - `network_id` bigint unsigned NOT NULL COMMENT 'network configuration that this domain router belongs to', `is_redundant_router` int(1) unsigned NOT NULL COMMENT 'if in redundant router mode', `priority` int(4) unsigned COMMENT 'priority of router in the redundant router mode', `is_priority_bumpup` int(1) unsigned NOT NULL COMMENT 'if the priority has been bumped up', @@ -1078,9 +1081,11 @@ CREATE TABLE `cloud`.`domain_router` ( `role` varchar(64) NOT NULL COMMENT 'type of role played by this router', `template_version` varchar(100) COMMENT 'template version', `scripts_version` varchar(100) COMMENT 'scripts version', + `vpc_id` bigint unsigned COMMENT 'correlated virtual router vpc ID', PRIMARY KEY (`id`), CONSTRAINT `fk_domain_router__id` FOREIGN KEY `fk_domain_router__id` (`id`) REFERENCES `vm_instance`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_domain_router__element_id` FOREIGN KEY `fk_domain_router__element_id`(`element_id`) REFERENCES `virtual_router_providers`(`id`) + CONSTRAINT `fk_domain_router__element_id` FOREIGN KEY `fk_domain_router__element_id`(`element_id`) REFERENCES `virtual_router_providers`(`id`), + CONSTRAINT `fk_domain_router__vpc_id` FOREIGN KEY `fk_domain_router__vpc_id`(`vpc_id`) REFERENCES `vpc`(`id`) ) ENGINE = InnoDB DEFAULT CHARSET=utf8 COMMENT = 'information about the domR instance'; CREATE TABLE `cloud`.`upload` ( @@ -2140,5 +2145,97 @@ CREATE TABLE `cloud`.`resource_tags` ( UNIQUE `i_tags__resource_id__resource_type__key`(`resource_id`, `resource_type`, `key`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +CREATE TABLE `cloud`.`vpc` ( + `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', + `uuid` varchar(40) NOT NULL, + `name` varchar(255) COMMENT 'vpc name', + `display_text` varchar(255) COMMENT 'vpc display text', + `cidr` varchar(18) COMMENT 'vpc cidr', + `vpc_offering_id` bigint unsigned NOT NULL COMMENT 'vpc offering id that this vpc is created from', + `zone_id` bigint unsigned NOT NULL COMMENT 'the id of the zone this Vpc belongs to', + `state` varchar(32) NOT NULL COMMENT 'state of the VP (can be Enabled and Disabled)', + `domain_id` bigint unsigned NOT NULL COMMENT 'domain the vpc belongs to', + `account_id` bigint unsigned NOT NULL COMMENT 'owner of this vpc', + `network_domain` varchar(255) COMMENT 'network domain', + `removed` datetime COMMENT 'date removed if not null', + `created` datetime NOT NULL COMMENT 'date created', + `restart_required` int(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 if restart is required for the VPC', + PRIMARY KEY (`id`), + INDEX `i_vpc__removed`(`removed`), + CONSTRAINT `fk_vpc__zone_id` FOREIGN KEY `fk_vpc__zone_id` (`zone_id`) REFERENCES `data_center` (`id`) ON DELETE CASCADE, + CONSTRAINT `fk_vpc__vpc_offering_id` FOREIGN KEY (`vpc_offering_id`) REFERENCES `vpc_offerings`(`id`), + CONSTRAINT `fk_vpc__account_id` FOREIGN KEY `fk_vpc__account_id` (`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_vpc__domain_id` FOREIGN KEY `fk_vpc__domain_id` (`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + +CREATE TABLE `cloud`.`vpc_offerings` ( + `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', + `uuid` varchar(40) NOT NULL, + `unique_name` varchar(64) UNIQUE COMMENT 'unique name of the vpc offering', + `name` varchar(255) COMMENT 'vpc name', + `display_text` varchar(255) COMMENT 'display text', + `state` char(32) COMMENT 'state of the vpc offering that has Disabled value by default', + `default` int(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 if vpc offering is default', + `removed` datetime COMMENT 'date removed if not null', + `created` datetime NOT NULL COMMENT 'date created', + `service_offering_id` bigint unsigned COMMENT 'service offering id that virtual router is tied to', + PRIMARY KEY (`id`), + INDEX `i_vpc__removed`(`removed`), + CONSTRAINT `fk_vpc_offerings__service_offering_id` FOREIGN KEY `fk_vpc_offerings__service_offering_id` (`service_offering_id`) REFERENCES `service_offering`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`vpc_offering_service_map` ( + `id` bigint unsigned NOT NULL auto_increment, + `vpc_offering_id` bigint unsigned NOT NULL COMMENT 'vpc_offering_id', + `service` varchar(255) NOT NULL COMMENT 'service', + `provider` varchar(255) COMMENT 'service provider', + `created` datetime COMMENT 'date created', + PRIMARY KEY (`id`), + CONSTRAINT `fk_vpc_offering_service_map__vpc_offering_id` FOREIGN KEY(`vpc_offering_id`) REFERENCES `vpc_offerings`(`id`) ON DELETE CASCADE, + UNIQUE (`vpc_offering_id`, `service`, `provider`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + +CREATE TABLE `cloud`.`router_network_ref` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `router_id` bigint unsigned NOT NULL COMMENT 'router id', + `network_id` bigint unsigned NOT NULL COMMENT 'network id', + `guest_type` char(32) COMMENT 'type of guest network that can be shared or isolated', + PRIMARY KEY (`id`), + CONSTRAINT `fk_router_network_ref__networks_id` FOREIGN KEY (`network_id`) REFERENCES `networks`(`id`) ON DELETE CASCADE, + UNIQUE `i_router_network_ref__router_id__network_id`(`router_id`, `network_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + +CREATE TABLE `cloud`.`vpc_gateways` ( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id', + `uuid` varchar(40), + `ip4_address` char(40) COMMENT 'ip4 address of the gateway', + `type` varchar(32) COMMENT 'type of gateway; can be Public/Private/Vpn', + `network_id` bigint unsigned NOT NULL COMMENT 'network id vpc gateway belongs to', + `vpc_id` bigint unsigned NOT NULL COMMENT 'id of the vpc the gateway belongs to', + `zone_id` bigint unsigned NOT NULL COMMENT 'id of the zone the gateway belongs to', + `created` datetime NOT NULL COMMENT 'date created', + `removed` datetime COMMENT 'date removed if not null', + PRIMARY KEY (`id`), + CONSTRAINT `fk_vpc_gateways__network_id` FOREIGN KEY `fk_vpc_gateways__network_id`(`network_id`) REFERENCES `networks`(`id`), + CONSTRAINT `fk_vpc_gateways__vpc_id` FOREIGN KEY `fk_vpc_gateways__vpc_id`(`vpc_id`) REFERENCES `vpc`(`id`), + CONSTRAINT `fk_vpc_gateways__zone_id` FOREIGN KEY `fk_vpc_gateways__zone_id`(`zone_id`) REFERENCES `data_center`(`id`), + CONSTRAINT `uc_vpc_gateways__uuid` UNIQUE (`uuid`), + INDEX `i_vpc_gateways__removed`(`removed`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`private_ip_address` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'primary key', + `ip_address` char(40) NOT NULL COMMENT 'ip address', + `network_id` bigint unsigned NOT NULL COMMENT 'id of the network ip belongs to', + `reservation_id` char(40) COMMENT 'reservation id', + `taken` datetime COMMENT 'Date taken', + PRIMARY KEY (`id`), + CONSTRAINT `fk_private_ip_address__network_id` FOREIGN KEY (`network_id`) REFERENCES `networks` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + SET foreign_key_checks = 1; + diff --git a/utils/src/com/cloud/utils/exception/CSExceptionErrorCode.java b/utils/src/com/cloud/utils/exception/CSExceptionErrorCode.java index 1e9939c2131..2789e62433c 100755 --- a/utils/src/com/cloud/utils/exception/CSExceptionErrorCode.java +++ b/utils/src/com/cloud/utils/exception/CSExceptionErrorCode.java @@ -94,13 +94,15 @@ public class CSExceptionErrorCode { ExceptionErrorCodeMap.put("com.cloud.exception.ResourceUnavailableException", 4520); ExceptionErrorCodeMap.put("com.cloud.exception.StorageUnavailableException", 4525); ExceptionErrorCodeMap.put("com.cloud.exception.UnsupportedServiceException", 4530); - ExceptionErrorCodeMap.put("com.cloud.exception.VirtualMachineMigrationException", 4535); + ExceptionErrorCodeMap.put("com.cloud.exception.VirtualMachineMigrationException", 4535); + ExceptionErrorCodeMap.put("com.cloud.async.AsyncCommandQueued", 4540); // Have a special error code for ServerApiException when it is // thrown in a standalone manner when failing to detect any of the above // standard exceptions. ExceptionErrorCodeMap.put("com.cloud.api.ServerApiException", 9999); } catch (Exception e) { + e.printStackTrace(); throw new ExceptionInInitializerError(e); } }