api,server: custom dns for guest network (#6425)

Adds option to provide custom DNS servers for isolated network, shared network and VPC tier.
New API parameters added in createNetwork API along with the corresponding response parameters.

Doc PR: apache/cloudstack-documentation#276
This commit is contained in:
Abhishek Kumar 2022-09-10 13:05:40 +05:30 committed by GitHub
parent cf18549dbb
commit 78b68fd7e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
64 changed files with 2829 additions and 352 deletions

View File

@ -41,6 +41,8 @@ public class NetworkTO {
protected String ip6address;
protected String ip6gateway;
protected String ip6cidr;
protected String ip6Dns1;
protected String ip6Dns2;
public NetworkTO() {
}
@ -221,4 +223,12 @@ public class NetworkTO {
public boolean isSecurityGroupEnabled() {
return this.isSecurityGroupEnabled;
}
public void setIp6Dns1(String ip6Dns1) {
this.ip6Dns1 = ip6Dns1;
}
public void setIp6Dns2(String ip6Dns2) {
this.ip6Dns2 = ip6Dns2;
}
}

View File

@ -483,5 +483,13 @@ public interface Network extends ControlledEntity, StateObject<Network.State>, I
String getRouterIpv6();
String getDns1();
String getDns2();
String getIp6Dns1();
String getIp6Dns2();
Date getCreated();
}

View File

@ -17,13 +17,14 @@
package com.cloud.network;
import com.google.common.collect.ImmutableMap;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.cloudstack.framework.config.ConfigKey;
import com.cloud.dc.DataCenter;
import com.cloud.dc.Vlan;
import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InvalidParameterValueException;
@ -39,10 +40,11 @@ import com.cloud.network.router.VirtualRouter;
import com.cloud.offering.NetworkOffering;
import com.cloud.offering.NetworkOffering.Detail;
import com.cloud.user.Account;
import com.cloud.utils.Pair;
import com.cloud.vm.Nic;
import com.cloud.vm.NicProfile;
import com.cloud.vm.VirtualMachine;
import org.apache.cloudstack.framework.config.ConfigKey;
import com.google.common.collect.ImmutableMap;
/**
* The NetworkModel presents a read-only view into the Network data such as L2 networks,
@ -323,4 +325,12 @@ public interface NetworkModel {
String getValidNetworkCidr(Network guestNetwork);
Pair<String, String> getNetworkIp4Dns(final Network network, final DataCenter zone);
Pair<String, String> getNetworkIp6Dns(final Network network, final DataCenter zone);
void verifyIp4DnsPair(final String ip4Dns1, final String ip4Dns2);
void verifyIp6DnsPair(final String ip6Dns1, final String ip6Dns2);
}

View File

@ -31,6 +31,8 @@ public class NetworkProfile implements Network {
private final long domainId;
private String dns1;
private String dns2;
private String ip6Dns1;
private String ip6Dns2;
private URI broadcastUri;
private final State state;
private boolean isRedundant;
@ -98,10 +100,12 @@ public class NetworkProfile implements Network {
externalId = network.getExternalId();
}
@Override
public String getDns1() {
return dns1;
}
@Override
public String getDns2() {
return dns2;
}
@ -114,6 +118,24 @@ public class NetworkProfile implements Network {
this.dns2 = dns2;
}
@Override
public String getIp6Dns1() {
return ip6Dns1;
}
@Override
public String getIp6Dns2() {
return ip6Dns2;
}
public void setIp6Dns1(String ip6Dns1) {
this.ip6Dns1 = ip6Dns1;
}
public void setIp6Dns2(String ip6Dns2) {
this.ip6Dns2 = ip6Dns2;
}
@Override
public String getGuruName() {
return guruName;

View File

@ -16,12 +16,12 @@
// under the License.
package com.cloud.network.vpc;
import java.util.Date;
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.api.Identity;
import org.apache.cloudstack.api.InternalIdentity;
import java.util.Date;
public interface Vpc extends ControlledEntity, Identity, InternalIdentity {
public enum State {
@ -95,4 +95,12 @@ public interface Vpc extends ControlledEntity, Identity, InternalIdentity {
void setRollingRestart(boolean rollingRestart);
Date getCreated();
String getIp4Dns1();
String getIp4Dns2();
String getIp6Dns1();
String getIp6Dns2();
}

View File

@ -20,6 +20,7 @@ import java.util.List;
import java.util.Map;
import org.apache.cloudstack.api.command.user.vpc.CreatePrivateGatewayCmd;
import org.apache.cloudstack.api.command.user.vpc.CreateVPCCmd;
import org.apache.cloudstack.api.command.user.vpc.ListPrivateGatewaysCmd;
import org.apache.cloudstack.api.command.user.vpc.ListStaticRoutesCmd;
import org.apache.cloudstack.api.command.user.vpc.RestartVPCCmd;
@ -36,6 +37,7 @@ import com.cloud.utils.Pair;
public interface VpcService {
public Vpc createVpc(CreateVPCCmd cmd) throws ResourceAllocationException;
/**
* Persists VPC record in the database
*
@ -50,7 +52,8 @@ public interface VpcService {
* @return
* @throws ResourceAllocationException TODO
*/
public Vpc createVpc(long zoneId, long vpcOffId, long vpcOwnerId, String vpcName, String displayText, String cidr, String networkDomain, Boolean displayVpc)
public Vpc createVpc(long zoneId, long vpcOffId, long vpcOwnerId, String vpcName, String displayText, String cidr, String networkDomain,
String dns1, String dns2, String ip6Dns1, String ip6Dns2, Boolean displayVpc)
throws ResourceAllocationException;
/**

View File

@ -157,6 +157,18 @@ public class CreateNetworkCmd extends BaseCmd implements UserCmd {
description = "The network this network is associated to. only available if create a Shared network")
private Long associatedNetworkId;
@Parameter(name = ApiConstants.DNS1, type = CommandType.STRING, description = "the first IPv4 DNS for the network", since = "4.18.0")
private String ip4Dns1;
@Parameter(name = ApiConstants.DNS2, type = CommandType.STRING, description = "the second IPv4 DNS for the network", since = "4.18.0")
private String ip4Dns2;
@Parameter(name = ApiConstants.IP6_DNS1, type = CommandType.STRING, description = "the first IPv6 DNS for the network", since = "4.18.0")
private String ip6Dns1;
@Parameter(name = ApiConstants.IP6_DNS2, type = CommandType.STRING, description = "the second IPv6 DNS for the network", since = "4.18.0")
private String ip6Dns2;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@ -326,6 +338,22 @@ public class CreateNetworkCmd extends BaseCmd implements UserCmd {
return aclId;
}
public String getIp4Dns1() {
return ip4Dns1;
}
public String getIp4Dns2() {
return ip4Dns2;
}
public String getIp6Dns1() {
return ip6Dns1;
}
public String getIp6Dns2() {
return ip6Dns2;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////

View File

@ -84,6 +84,18 @@ public class UpdateNetworkCmd extends BaseAsyncCustomIdCmd implements UserCmd {
@Parameter(name= ApiConstants.FORCED, type = CommandType.BOOLEAN, description = "Setting this to true will cause a forced network update,", authorized = {RoleType.Admin})
private Boolean forced;
@Parameter(name = ApiConstants.DNS1, type = CommandType.STRING, description = "the first IPv4 DNS for the network. Empty string will update the first IPv4 DNS with the value from the zone", since = "4.18.0")
private String ip4Dns1;
@Parameter(name = ApiConstants.DNS2, type = CommandType.STRING, description = "the second IPv4 DNS for the network. Empty string will update the second IPv4 DNS with the value from the zone", since = "4.18.0")
private String ip4Dns2;
@Parameter(name = ApiConstants.IP6_DNS1, type = CommandType.STRING, description = "the first IPv6 DNS for the network. Empty string will update the first IPv6 DNS with the value from the zone", since = "4.18.0")
private String ip6Dns1;
@Parameter(name = ApiConstants.IP6_DNS2, type = CommandType.STRING, description = "the second IPv6 DNS for the network. Empty string will update the second IPv6 DNS with the value from the zone", since = "4.18.0")
private String ip6Dns2;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@ -136,6 +148,23 @@ public class UpdateNetworkCmd extends BaseAsyncCustomIdCmd implements UserCmd {
}
return forced;
}
public String getIp4Dns1() {
return ip4Dns1;
}
public String getIp4Dns2() {
return ip4Dns2;
}
public String getIp6Dns1() {
return ip6Dns1;
}
public String getIp6Dns2() {
return ip6Dns2;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////

View File

@ -95,6 +95,18 @@ public class CreateVPCCmd extends BaseAsyncCreateCmd implements UserCmd {
@Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "an optional field, whether to the display the vpc to the end user or not", since = "4.4", authorized = {RoleType.Admin})
private Boolean display;
@Parameter(name = ApiConstants.DNS1, type = CommandType.STRING, description = "the first IPv4 DNS for the VPC", since = "4.18.0")
private String ip4Dns1;
@Parameter(name = ApiConstants.DNS2, type = CommandType.STRING, description = "the second IPv4 DNS for the VPC", since = "4.18.0")
private String ip4Dns2;
@Parameter(name = ApiConstants.IP6_DNS1, type = CommandType.STRING, description = "the first IPv6 DNS for the VPC", since = "4.18.0")
private String ip6Dns1;
@Parameter(name = ApiConstants.IP6_DNS2, type = CommandType.STRING, description = "the second IPv6 DNS for the VPC", since = "4.18.0")
private String ip6Dns2;
// ///////////////////////////////////////////////////
// ///////////////// Accessors ///////////////////////
// ///////////////////////////////////////////////////
@ -131,6 +143,22 @@ public class CreateVPCCmd extends BaseAsyncCreateCmd implements UserCmd {
return networkDomain;
}
public String getIp4Dns1() {
return ip4Dns1;
}
public String getIp4Dns2() {
return ip4Dns2;
}
public String getIp6Dns1() {
return ip6Dns1;
}
public String getIp6Dns2() {
return ip6Dns2;
}
public boolean isStart() {
if (start != null) {
return start;
@ -144,7 +172,7 @@ public class CreateVPCCmd extends BaseAsyncCreateCmd implements UserCmd {
@Override
public void create() throws ResourceAllocationException {
Vpc vpc = _vpcService.createVpc(getZoneId(), getVpcOffering(), getEntityOwnerId(), getVpcName(), getDisplayText(), getCidr(), getNetworkDomain(), getDisplayVpc());
Vpc vpc = _vpcService.createVpc(this);
if (vpc != null) {
setEntityId(vpc.getId());
setEntityUuid(vpc.getUuid());

View File

@ -120,11 +120,11 @@ public class NetworkResponse extends BaseResponseWithAssociatedNetwork implement
private String broadcastUri;
@SerializedName(ApiConstants.DNS1)
@Param(description = "the first DNS for the network")
@Param(description = "the first IPv4 DNS for the network")
private String dns1;
@SerializedName(ApiConstants.DNS2)
@Param(description = "the second DNS for the network")
@Param(description = "the second IPv4 DNS for the network")
private String dns2;
@SerializedName(ApiConstants.TYPE)
@ -287,6 +287,14 @@ public class NetworkResponse extends BaseResponseWithAssociatedNetwork implement
@Param(description = "The routes for the network to ease adding route in upstream router", since = "4.17.0")
private Set<Ipv6RouteResponse> ipv6Routes;
@SerializedName(ApiConstants.IP6_DNS1)
@Param(description = "the first IPv6 DNS for the network", since = "4.18.0")
private String ipv6Dns1;
@SerializedName(ApiConstants.IP6_DNS2)
@Param(description = "the second IPv6 DNS for the network", since = "4.18.0")
private String ipv6Dns2;
public NetworkResponse() {}
public Boolean getDisplayNetwork() {
@ -586,4 +594,12 @@ public class NetworkResponse extends BaseResponseWithAssociatedNetwork implement
public void addIpv6Route(Ipv6RouteResponse ipv6Route) {
this.ipv6Routes.add(ipv6Route);
}
public void setIpv6Dns1(String ipv6Dns1) {
this.ipv6Dns1 = ipv6Dns1;
}
public void setIpv6Dns2(String ipv6Dns2) {
this.ipv6Dns2 = ipv6Dns2;
}
}

View File

@ -136,6 +136,22 @@ public class VpcResponse extends BaseResponseWithAnnotations implements Controll
@Param(description = "The routes for the network to ease adding route in upstream router", since = "4.17.0")
private Set<Ipv6RouteResponse> ipv6Routes;
@SerializedName(ApiConstants.DNS1)
@Param(description = "the first IPv4 DNS for the VPC")
private String dns1;
@SerializedName(ApiConstants.DNS2)
@Param(description = "the second IPv4 DNS for the VPC")
private String dns2;
@SerializedName(ApiConstants.IP6_DNS1)
@Param(description = "the first IPv6 DNS for the VPC", since = "4.18.0")
private String ipv6Dns1;
@SerializedName(ApiConstants.IP6_DNS2)
@Param(description = "the second IPv6 DNS for the VPC", since = "4.18.0")
private String ipv6Dns2;
public void setId(final String id) {
this.id = id;
}
@ -257,4 +273,20 @@ public class VpcResponse extends BaseResponseWithAnnotations implements Controll
public Set<Ipv6RouteResponse> getIpv6Routes() {
return ipv6Routes;
}
public void setDns1(String dns1) {
this.dns1 = dns1;
}
public void setDns2(String dns2) {
this.dns2 = dns2;
}
public void setIpv6Dns1(String ipv6Dns1) {
this.ipv6Dns1 = ipv6Dns1;
}
public void setIpv6Dns2(String ipv6Dns2) {
this.ipv6Dns2 = ipv6Dns2;
}
}

View File

@ -187,7 +187,8 @@ public interface NetworkOrchestrationService {
Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, boolean bypassVlanOverlapCheck, String networkDomain, Account owner,
Long domainId, PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String ip6Gateway, String ip6Cidr,
Boolean displayNetworkEnabled, String isolatedPvlan, Network.PVlanType isolatedPvlanType, String externalId, String routerIp, String routerIpv6) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException;
Boolean displayNetworkEnabled, String isolatedPvlan, Network.PVlanType isolatedPvlanType, String externalId, String routerIp, String routerIpv6,
String ip4Dns1, String ip4Dns2, String ip6Dns1, String ip6Dns2) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException;
UserDataServiceProvider getPasswordResetProvider(Network network);

View File

@ -109,8 +109,7 @@ public interface VpcManager {
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, Long aclId, Account caller,
Boolean displayNetworkEnabled, String externalId, String ip6Gateway, String ip6Cidr)
Boolean displayNetworkEnabled, String externalId, String ip6Gateway, String ip6Cidr, String ip4Dns1, String ip4Dns2, String ip6Dns1, String ip6Dns2)
throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException;
/**

View File

@ -38,7 +38,6 @@ import java.util.stream.Collectors;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import com.cloud.server.ManagementServer;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.annotation.AnnotationService;
import org.apache.cloudstack.annotation.dao.AnnotationDao;
@ -55,6 +54,7 @@ import org.apache.cloudstack.framework.messagebus.MessageBus;
import org.apache.cloudstack.framework.messagebus.PublishScope;
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
import org.apache.cloudstack.network.dao.NetworkPermissionDao;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
@ -197,6 +197,7 @@ import com.cloud.offerings.dao.NetworkOfferingDao;
import com.cloud.offerings.dao.NetworkOfferingDetailsDao;
import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
import com.cloud.resource.ResourceManager;
import com.cloud.server.ManagementServer;
import com.cloud.user.Account;
import com.cloud.user.ResourceLimitService;
import com.cloud.user.User;
@ -422,6 +423,38 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
HashMap<Long, Long> _lastNetworkIdsToFree = new HashMap<Long, Long>();
private void updateRouterDefaultDns(final VirtualMachineProfile vmProfile, final NicProfile nicProfile) {
if (!Type.DomainRouter.equals(vmProfile.getType()) || !nicProfile.isDefaultNic()) {
return;
}
DomainRouterVO router = routerDao.findById(vmProfile.getId());
if (router != null && router.getVpcId() != null) {
final Vpc vpc = _vpcMgr.getActiveVpc(router.getVpcId());
if (StringUtils.isNotBlank(vpc.getIp4Dns1())) {
nicProfile.setIPv4Dns1(vpc.getIp4Dns1());
nicProfile.setIPv4Dns2(vpc.getIp4Dns2());
}
if (StringUtils.isNotBlank(vpc.getIp6Dns1())) {
nicProfile.setIPv6Dns1(vpc.getIp6Dns1());
nicProfile.setIPv6Dns2(vpc.getIp6Dns2());
}
return;
}
List<Long> networkIds = routerNetworkDao.getRouterNetworks(vmProfile.getId());
if (CollectionUtils.isEmpty(networkIds) || networkIds.size() > 1) {
return;
}
final NetworkVO routerNetwork = _networksDao.findById(networkIds.get(0));
if (StringUtils.isNotBlank(routerNetwork.getDns1())) {
nicProfile.setIPv4Dns1(routerNetwork.getDns1());
nicProfile.setIPv4Dns2(routerNetwork.getDns2());
}
if (StringUtils.isNotBlank(routerNetwork.getIp6Dns1())) {
nicProfile.setIPv6Dns1(routerNetwork.getIp6Dns1());
nicProfile.setIPv6Dns2(routerNetwork.getIp6Dns2());
}
}
@Override
@DB
public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
@ -1951,7 +1984,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
profile.setSecurityGroupEnabled(_networkModel.isSecurityGroupSupportedInNetwork(network));
guru.updateNicProfile(profile, network);
updateRouterDefaultDns(vmProfile, profile);
configureExtraDhcpOptions(network, nicId);
return profile;
}
@ -2430,7 +2463,8 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
// create network for private gateway
return createGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId,
bypassVlanOverlapCheck, null, owner, null, pNtwk, pNtwk.getDataCenterId(), ACLType.Account, null,
vpcId, null, null, true, null, null, null, true, null, null);
vpcId, null, null, true, null, null, null, true, null, null,
null, null, null, null);
}
@Override
@ -2438,18 +2472,21 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
public Network createGuestNetwork(final long networkOfferingId, final String name, final String displayText, final String gateway, final String cidr, String vlanId,
boolean bypassVlanOverlapCheck, String networkDomain, final Account owner, final Long domainId, final PhysicalNetwork pNtwk,
final long zoneId, final ACLType aclType, Boolean subdomainAccess, final Long vpcId, final String ip6Gateway, final String ip6Cidr,
final Boolean isDisplayNetworkEnabled, final String isolatedPvlan, Network.PVlanType isolatedPvlanType, String externalId, String routerIp, String routerIpv6) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
final Boolean isDisplayNetworkEnabled, final String isolatedPvlan, Network.PVlanType isolatedPvlanType, String externalId,
String routerIp, String routerIpv6, String ip4Dns1, String ip4Dns2, String ip6Dns1, String ip6Dns2) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
// create Isolated/Shared/L2 network
return createGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, bypassVlanOverlapCheck,
networkDomain, owner, domainId, pNtwk, zoneId, aclType, subdomainAccess, vpcId, ip6Gateway, ip6Cidr,
isDisplayNetworkEnabled, isolatedPvlan, isolatedPvlanType, externalId, false, routerIp, routerIpv6);
isDisplayNetworkEnabled, isolatedPvlan, isolatedPvlanType, externalId, false, routerIp, routerIpv6, ip4Dns1, ip4Dns2, ip6Dns1, ip6Dns2);
}
@DB
private Network createGuestNetwork(final long networkOfferingId, final String name, final String displayText, final String gateway, final String cidr, String vlanId,
boolean bypassVlanOverlapCheck, String networkDomain, final Account owner, final Long domainId, final PhysicalNetwork pNtwk,
final long zoneId, final ACLType aclType, Boolean subdomainAccess, final Long vpcId, final String ip6Gateway, final String ip6Cidr,
final Boolean isDisplayNetworkEnabled, final String isolatedPvlan, Network.PVlanType isolatedPvlanType, String externalId, final Boolean isPrivateNetwork, String routerIp, String routerIpv6) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
final Boolean isDisplayNetworkEnabled, final String isolatedPvlan, Network.PVlanType isolatedPvlanType, String externalId,
final Boolean isPrivateNetwork, String routerIp, String routerIpv6, final String ip4Dns1, final String ip4Dns2,
final String ip6Dns1, final String ip6Dns2) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
final NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId);
final DataCenterVO zone = _dcDao.findById(zoneId);
@ -2724,6 +2761,21 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
userNetwork.setRouterIpv6(routerIpv6);
}
if (!GuestType.L2.equals(userNetwork.getGuestType())) {
if (StringUtils.isNotBlank(ip4Dns1)) {
userNetwork.setDns1(ip4Dns1);
}
if (StringUtils.isNotBlank(ip4Dns2)) {
userNetwork.setDns2(ip4Dns2);
}
if (StringUtils.isNotBlank(ip6Dns1)) {
userNetwork.setIp6Dns1(ip6Dns1);
}
if (StringUtils.isNotBlank(ip6Dns2)) {
userNetwork.setIp6Dns2(ip6Dns2);
}
}
if (vlanIdFinal != null) {
if (isolatedPvlan == null) {
URI uri = null;

View File

@ -29,8 +29,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.cloud.network.dao.PhysicalNetworkVO;
import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.log4j.Logger;
import org.junit.Assert;
import org.junit.Before;
@ -43,30 +41,44 @@ import org.mockito.Mockito;
import com.cloud.dc.Vlan;
import com.cloud.dc.VlanVO;
import com.cloud.dc.dao.VlanDao;
import com.cloud.deploy.DeployDestination;
import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.hypervisor.Hypervisor;
import com.cloud.network.IpAddress.State;
import com.cloud.network.Network;
import com.cloud.network.Network.GuestType;
import com.cloud.network.Network.Service;
import com.cloud.network.NetworkModel;
import com.cloud.network.IpAddress.State;
import com.cloud.network.Networks.TrafficType;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkServiceMapDao;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.dao.PhysicalNetworkVO;
import com.cloud.network.dao.RouterNetworkDao;
import com.cloud.network.element.DhcpServiceProvider;
import com.cloud.network.guru.GuestNetworkGuru;
import com.cloud.network.guru.NetworkGuru;
import com.cloud.network.vpc.VpcManager;
import com.cloud.network.vpc.VpcVO;
import com.cloud.offerings.NetworkOfferingVO;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.net.Ip;
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;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachine.Type;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.dao.DomainRouterDao;
import com.cloud.vm.dao.NicDao;
import com.cloud.vm.dao.NicExtraDhcpOptionDao;
import com.cloud.vm.dao.NicIpAliasDao;
import com.cloud.vm.dao.NicSecondaryIpDao;
@ -89,6 +101,11 @@ public class NetworkOrchestratorTest extends TestCase {
private static final long networkOfferingId = 1l;
final String[] ip4Dns = {"5.5.5.5", "6.6.6.6"};
final String[] ip6Dns = {"2001:4860:4860::5555", "2001:4860:4860::6666"};
final String[] ip4AltDns = {"7.7.7.7", "8.8.8.8"};
final String[] ip6AltDns = {"2001:4860:4860::7777", "2001:4860:4860::8888"};
@Override
@Before
public void setUp() {
@ -101,6 +118,11 @@ public class NetworkOrchestratorTest extends TestCase {
testOrchastrator._nicIpAliasDao = mock(NicIpAliasDao.class);
testOrchastrator._ipAddressDao = mock(IPAddressDao.class);
testOrchastrator._vlanDao = mock(VlanDao.class);
testOrchastrator._networkModel = mock(NetworkModel.class);
testOrchastrator._nicExtraDhcpOptionDao = mock(NicExtraDhcpOptionDao.class);
testOrchastrator.routerDao = mock(DomainRouterDao.class);
testOrchastrator.routerNetworkDao = mock(RouterNetworkDao.class);
testOrchastrator._vpcMgr = mock(VpcManager.class);
DhcpServiceProvider provider = mock(DhcpServiceProvider.class);
Map<Network.Capability, String> capabilities = new HashMap<Network.Capability, String>();
@ -556,4 +578,132 @@ public class NetworkOrchestratorTest extends TestCase {
Assert.assertEquals(expectedIsolation, resultUri.getScheme());
Assert.assertEquals(expectedUri, resultUri.toString());
}
private NicProfile prepareMocksAndRunPrepareNic(VirtualMachine.Type vmType, boolean isDefaultNic, boolean isVpcRouter, boolean routerResourceHasCustomDns) {
Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType.KVM;
Long nicId = 1L;
Long vmId = 1L;
Long networkId = 1L;
Integer networkRate = 200;
Network network = Mockito.mock(Network.class);
Mockito.when(network.getGuruName()).thenReturn(GuestNetworkGuru.class.getSimpleName());
Mockito.when(network.getDns1()).thenReturn(ip4Dns[0]);
Mockito.when(network.getDns2()).thenReturn(ip4Dns[1]);
Mockito.when(network.getIp6Dns1()).thenReturn(ip6Dns[0]);
Mockito.when(network.getIp6Dns2()).thenReturn(ip6Dns[1]);
Mockito.when(testOrchastrator._networkModel.getNetworkRate(networkId, vmId)).thenReturn(networkRate);
NicVO nicVO = Mockito.mock(NicVO.class);
Mockito.when(nicVO.isDefaultNic()).thenReturn(isDefaultNic);
Mockito.when(testOrchastrator._nicDao.findById(nicId)).thenReturn(nicVO);
Mockito.when(testOrchastrator._nicDao.update(nicId, nicVO)).thenReturn(true);
Mockito.when(testOrchastrator._networkModel.isSecurityGroupSupportedInNetwork(network)).thenReturn(false);
Mockito.when(testOrchastrator._networkModel.getNetworkTag(hypervisorType, network)).thenReturn(null);
Mockito.when(testOrchastrator._ntwkSrvcDao.getDistinctProviders(networkId)).thenReturn(new ArrayList<>());
testOrchastrator.networkElements = new ArrayList<>();
Mockito.when(testOrchastrator._nicExtraDhcpOptionDao.listByNicId(nicId)).thenReturn(new ArrayList<>());
Mockito.when(testOrchastrator._ntwkSrvcDao.areServicesSupportedInNetwork(networkId, Service.Dhcp)).thenReturn(false);
VirtualMachineProfile virtualMachineProfile = Mockito.mock(VirtualMachineProfile.class);
Mockito.when(virtualMachineProfile.getType()).thenReturn(vmType);
Mockito.when(virtualMachineProfile.getId()).thenReturn(vmId);
DeployDestination deployDestination = Mockito.mock(DeployDestination.class);
ReservationContext reservationContext = Mockito.mock(ReservationContext.class);
Mockito.doAnswer((org.mockito.stubbing.Answer<Void>) invocation -> {
NicProfile nicProfile = (NicProfile) invocation.getArguments()[0];
Network ntwk = (Network) invocation.getArguments()[1];
nicProfile.setIPv4Dns1(ntwk.getDns1());
nicProfile.setIPv4Dns2(ntwk.getDns2());
nicProfile.setIPv6Dns1(ntwk.getIp6Dns1());
nicProfile.setIPv6Dns2(ntwk.getIp6Dns2());
return null;
}).when(guru).updateNicProfile(Mockito.any(NicProfile.class), Mockito.any(Network.class));
DomainRouterVO routerVO = Mockito.mock(DomainRouterVO.class);
if (isVpcRouter) {
Long vpcId = 1L;
Mockito.when(routerVO.getVpcId()).thenReturn(vpcId);
VpcVO vpcVO = Mockito.mock(VpcVO.class);
if (routerResourceHasCustomDns) {
Mockito.when(vpcVO.getIp4Dns1()).thenReturn(ip4AltDns[0]);
Mockito.when(vpcVO.getIp4Dns2()).thenReturn(ip4AltDns[1]);
Mockito.when(vpcVO.getIp6Dns1()).thenReturn(ip6AltDns[0]);
Mockito.when(vpcVO.getIp6Dns2()).thenReturn(ip6AltDns[1]);
} else {
Mockito.when(vpcVO.getIp4Dns1()).thenReturn(null);
Mockito.when(vpcVO.getIp6Dns1()).thenReturn(null);
}
Mockito.when(testOrchastrator._vpcMgr.getActiveVpc(vpcId)).thenReturn(vpcVO);
} else {
Mockito.when(routerVO.getVpcId()).thenReturn(null);
Long routerNetworkId = 2L;
NetworkVO routerNetworkVO = Mockito.mock(NetworkVO.class);
if (routerResourceHasCustomDns) {
Mockito.when(routerNetworkVO.getDns1()).thenReturn(ip4AltDns[0]);
Mockito.when(routerNetworkVO.getDns2()).thenReturn(ip4AltDns[1]);
Mockito.when(routerNetworkVO.getIp6Dns1()).thenReturn(ip6AltDns[0]);
Mockito.when(routerNetworkVO.getIp6Dns2()).thenReturn(ip6AltDns[1]);
} else {
Mockito.when(routerNetworkVO.getDns1()).thenReturn(null);
Mockito.when(routerNetworkVO.getIp6Dns1()).thenReturn(null);
}
Mockito.when(testOrchastrator.routerNetworkDao.getRouterNetworks(vmId)).thenReturn(List.of(routerNetworkId));
Mockito.when(testOrchastrator._networksDao.findById(routerNetworkId)).thenReturn(routerNetworkVO);
}
Mockito.when(testOrchastrator.routerDao.findById(vmId)).thenReturn(routerVO);
NicProfile profile = null;
try {
profile = testOrchastrator.prepareNic(virtualMachineProfile, deployDestination, reservationContext, nicId, network);
} catch (InsufficientCapacityException | ResourceUnavailableException e) {
Assert.fail(String.format("Failure with exception %s", e.getMessage()));
}
return profile;
}
@Test
public void testPrepareNicUserVm() {
NicProfile profile = prepareMocksAndRunPrepareNic(Type.User, false, false, false);
Assert.assertNotNull(profile);
Assert.assertEquals(ip4Dns[0], profile.getIPv4Dns1());
Assert.assertEquals(ip4Dns[1], profile.getIPv4Dns2());
Assert.assertEquals(ip6Dns[0], profile.getIPv6Dns1());
Assert.assertEquals(ip6Dns[1], profile.getIPv6Dns2());
}
@Test
public void testPrepareNicVpcRouterVm() {
NicProfile profile = prepareMocksAndRunPrepareNic(Type.DomainRouter, true, true, true);
Assert.assertNotNull(profile);
Assert.assertEquals(ip4AltDns[0], profile.getIPv4Dns1());
Assert.assertEquals(ip4AltDns[1], profile.getIPv4Dns2());
Assert.assertEquals(ip6AltDns[0], profile.getIPv6Dns1());
Assert.assertEquals(ip6AltDns[1], profile.getIPv6Dns2());
}
@Test
public void testPrepareNicVpcRouterNoDnsVm() {
NicProfile profile = prepareMocksAndRunPrepareNic(Type.DomainRouter, true, true, false);
Assert.assertNotNull(profile);
Assert.assertEquals(ip4Dns[0], profile.getIPv4Dns1());
Assert.assertEquals(ip4Dns[1], profile.getIPv4Dns2());
Assert.assertEquals(ip6Dns[0], profile.getIPv6Dns1());
Assert.assertEquals(ip6Dns[1], profile.getIPv6Dns2());
}
@Test
public void testPrepareNicNetworkRouterVm() {
NicProfile profile = prepareMocksAndRunPrepareNic(Type.DomainRouter, true, false, true);
Assert.assertNotNull(profile);
Assert.assertEquals(ip4AltDns[0], profile.getIPv4Dns1());
Assert.assertEquals(ip4AltDns[1], profile.getIPv4Dns2());
Assert.assertEquals(ip6AltDns[0], profile.getIPv6Dns1());
Assert.assertEquals(ip6AltDns[1], profile.getIPv6Dns2());
}
@Test
public void testPrepareNicNetworkRouterNoDnsVm() {
NicProfile profile = prepareMocksAndRunPrepareNic(Type.DomainRouter, true, false, false);
Assert.assertNotNull(profile);
Assert.assertEquals(ip4Dns[0], profile.getIPv4Dns1());
Assert.assertEquals(ip4Dns[1], profile.getIPv4Dns2());
Assert.assertEquals(ip6Dns[0], profile.getIPv6Dns1());
Assert.assertEquals(ip6Dns[1], profile.getIPv6Dns2());
}
}

View File

@ -183,15 +183,15 @@ public class DataCenterVO implements DataCenter {
this.firewallProvider = firewallProvider;
}
public DataCenterVO(long id, String name, String description, String dns1, String dns2, String dns3, String dns4, String guestCidr, String domain, Long domainId,
public DataCenterVO(long id, String name, String description, String dns1, String dns2, String internalDns1, String internalDns2, String guestCidr, String domain, Long domainId,
NetworkType zoneType, String zoneToken, String domainSuffix) {
this(name, description, dns1, dns2, dns3, dns4, guestCidr, domain, domainId, zoneType, zoneToken, domainSuffix, false, false, null, null);
this(name, description, dns1, dns2, internalDns1, internalDns2, guestCidr, domain, domainId, zoneType, zoneToken, domainSuffix, false, false, null, null);
this.id = id;
this.allocationState = Grouping.AllocationState.Enabled;
this.uuid = UUID.randomUUID().toString();
}
public DataCenterVO(String name, String description, String dns1, String dns2, String dns3, String dns4, String guestCidr, String domain, Long domainId,
public DataCenterVO(String name, String description, String dns1, String dns2, String internalDns1, String internalDns2, String guestCidr, String domain, Long domainId,
NetworkType zoneType, String zoneToken, String domainSuffix, boolean securityGroupEnabled, boolean localStorageEnabled, String ip6Dns1, String ip6Dns2) {
this.name = name;
this.description = description;
@ -199,8 +199,8 @@ public class DataCenterVO implements DataCenter {
this.dns2 = dns2;
this.ip6Dns1 = ip6Dns1;
this.ip6Dns2 = ip6Dns2;
this.internalDns1 = dns3;
this.internalDns2 = dns4;
this.internalDns1 = internalDns1;
this.internalDns2 = internalDns2;
this.guestNetworkCidr = guestCidr;
this.domain = domain;
this.domainId = domainId;

View File

@ -30,6 +30,7 @@ import javax.persistence.TableGenerator;
import javax.persistence.Transient;
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.commons.lang3.StringUtils;
import com.cloud.network.Network;
import com.cloud.network.Networks.BroadcastDomainType;
@ -106,9 +107,6 @@ public class NetworkVO implements Network {
@Column(name = "redundant")
boolean redundant;
@Column(name = "dns1")
String dns1;
@Column(name = "domain_id")
long domainId;
@ -125,9 +123,18 @@ public class NetworkVO implements Network {
@Column(name = "guru_data", length = 1024)
String guruData;
@Column(name = "dns1")
String dns1;
@Column(name = "dns2")
String dns2;
@Column(name = "ip6Dns1")
String ip6Dns1;
@Column(name = "ip6Dns2")
String ip6Dns2;
@Column(name = "network_domain")
String networkDomain;
@ -255,6 +262,18 @@ public class NetworkVO implements Network {
uuid = UUID.randomUUID().toString();
ip6Gateway = that.getIp6Gateway();
ip6Cidr = that.getIp6Cidr();
if (StringUtils.isNotBlank(that.getDns1())) {
this.dns1 = that.getDns1();
}
if (StringUtils.isNotBlank(that.getDns2())) {
this.dns2 = that.getDns2();
}
if (StringUtils.isNotBlank(that.getIp6Dns1())) {
this.ip6Dns1 = that.getIp6Dns1();
}
if (StringUtils.isNotBlank(that.getIp6Dns2())) {
this.ip6Dns2 = that.getIp6Dns2();
}
this.externalId = externalId;
}
@ -471,6 +490,7 @@ public class NetworkVO implements Network {
return dataCenterId;
}
@Override
public String getDns1() {
return dns1;
}
@ -479,6 +499,7 @@ public class NetworkVO implements Network {
dns1 = dns;
}
@Override
public String getDns2() {
return dns2;
}
@ -487,6 +508,24 @@ public class NetworkVO implements Network {
dns2 = dns;
}
@Override
public String getIp6Dns1() {
return ip6Dns1;
}
public void setIp6Dns1(String ip6Dns1) {
this.ip6Dns1 = ip6Dns1;
}
@Override
public String getIp6Dns2() {
return ip6Dns2;
}
public void setIp6Dns2(String ip6Dns2) {
this.ip6Dns2 = ip6Dns2;
}
@Override
public String getName() {
return name;

View File

@ -89,6 +89,18 @@ public class VpcVO implements Vpc {
@Column(name = "region_level_vpc")
boolean regionLevelVpc = false;
@Column(name = "dns1")
String ip4Dns1;
@Column(name = "dns2")
String ip4Dns2;
@Column(name = "ip6Dns1")
String ip6Dns1;
@Column(name = "ip6Dns2")
String ip6Dns2;
@Transient
boolean rollingRestart = false;
@ -97,8 +109,9 @@ public class VpcVO implements Vpc {
}
public VpcVO(final long zoneId, final String name, final String displayText, final long accountId, final long domainId,
final long vpcOffId, final String cidr, final String networkDomain, final boolean useDistributedRouter,
final boolean regionLevelVpc, final boolean isRedundant) {
final long vpcOffId, final String cidr, final String networkDomain, final boolean useDistributedRouter,
final boolean regionLevelVpc, final boolean isRedundant, final String ip4Dns1, final String ip4Dns2,
final String ip6Dns1, final String ip6Dns2) {
this.zoneId = zoneId;
this.name = name;
this.displayText = displayText;
@ -112,6 +125,10 @@ public class VpcVO implements Vpc {
usesDistributedRouter = useDistributedRouter;
this.regionLevelVpc = regionLevelVpc;
redundant = isRedundant;
this.ip4Dns1 = ip4Dns1;
this.ip4Dns2 = ip4Dns2;
this.ip6Dns1 = ip6Dns1;
this.ip6Dns2 = ip6Dns2;
}
@Override
@ -255,4 +272,24 @@ public class VpcVO implements Vpc {
public boolean usesDistributedRouter() {
return usesDistributedRouter;
}
@Override
public String getIp4Dns1() {
return ip4Dns1;
}
@Override
public String getIp4Dns2() {
return ip4Dns2;
}
@Override
public String getIp6Dns1() {
return ip6Dns1;
}
@Override
public String getIp6Dns2() {
return ip6Dns2;
}
}

View File

@ -31,7 +31,7 @@ public interface VpcOfferingServiceMapDao extends GenericDao<VpcOfferingServiceM
* @param services
* @return
*/
boolean areServicesSupportedByNetworkOffering(long networkOfferingId, Service[] services);
boolean areServicesSupportedByVpcOffering(long vpcOfferingId, Service[] services);
List<String> listServicesForVpcOffering(long vpcOfferingId);

View File

@ -65,9 +65,9 @@ public class VpcOfferingServiceMapDaoImpl extends GenericDaoBase<VpcOfferingServ
}
@Override
public boolean areServicesSupportedByNetworkOffering(long networkOfferingId, Service... services) {
public boolean areServicesSupportedByVpcOffering(long vpcOfferingId, Service... services) {
SearchCriteria<VpcOfferingServiceMapVO> sc = MultipleServicesSearch.create();
sc.setParameters("vpcOffId", networkOfferingId);
sc.setParameters("vpcOffId", vpcOfferingId);
if (services != null) {
String[] servicesStr = new String[services.length];

View File

@ -18,7 +18,6 @@
--;
-- Schema upgrade from 4.17.1.0 to 4.18.0.0
--;
-- Enable CPU cap for default system offerings;
UPDATE `cloud`.`service_offering` so
SET so.limit_cpu_use = 1
@ -27,3 +26,14 @@ WHERE so.default_use = 1 AND so.vm_type IN ('domainrouter', 'secondarystoragevm'
-- Add cidr_list column to load_balancing_rules
ALTER TABLE `cloud`.`load_balancing_rules`
ADD cidr_list VARCHAR(4096);
-- Alter networks table to add ip6dns1 and ip6dns2
ALTER TABLE `cloud`.`networks`
ADD COLUMN `ip6dns1` varchar(255) DEFAULT NULL COMMENT 'first IPv6 DNS for the network' AFTER `dns2`,
ADD COLUMN `ip6dns2` varchar(255) DEFAULT NULL COMMENT 'second IPv6 DNS for the network' AFTER `ip6dns1`;
-- Alter vpc table to add dns1, dns2, ip6dns1 and ip6dns2
ALTER TABLE `cloud`.`vpc`
ADD COLUMN `dns1` varchar(255) DEFAULT NULL COMMENT 'first IPv4 DNS for the vpc' AFTER `network_domain`,
ADD COLUMN `dns2` varchar(255) DEFAULT NULL COMMENT 'second IPv4 DNS for the vpc' AFTER `dns1`,
ADD COLUMN `ip6dns1` varchar(255) DEFAULT NULL COMMENT 'first IPv6 DNS for the vpc' AFTER `dns2`,
ADD COLUMN `ip6dns2` varchar(255) DEFAULT NULL COMMENT 'second IPv6 DNS for the vpc' AFTER `ip6dns1`;

View File

@ -41,6 +41,7 @@ import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.network.IpAddressManager;
import com.cloud.network.Network;
import com.cloud.network.NetworkModel;
import com.cloud.network.Networks.AddressFormat;
import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.Networks.IsolationType;
@ -49,6 +50,7 @@ import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.guru.DirectPodBasedNetworkGuru;
import com.cloud.offerings.dao.NetworkOfferingDao;
import com.cloud.utils.Pair;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.db.TransactionCallbackNoReturn;
import com.cloud.utils.db.TransactionStatus;
@ -74,6 +76,8 @@ public class BaremetaNetworkGuru extends DirectPodBasedNetworkGuru {
PodVlanMapDao _podVlanDao;
@Inject
IpAddressManager _ipAddrMgr;
@Inject
NetworkModel networkModel;
@Override
public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context)
@ -125,8 +129,9 @@ public class BaremetaNetworkGuru extends DirectPodBasedNetworkGuru {
}
DataCenter dc = _dcDao.findById(network.getDataCenterId());
nic.setIPv4Dns1(dc.getDns1());
nic.setIPv4Dns2(dc.getDns2());
Pair<String, String> dns = networkModel.getNetworkIp4Dns(network, dc);
nic.setIPv4Dns1(dns.first());
nic.setIPv4Dns2(dns.second());
/*
* Pod pod = dest.getPod(); Pair<String, Long> ip =
@ -167,7 +172,8 @@ public class BaremetaNetworkGuru extends DirectPodBasedNetworkGuru {
nic.setReservationId(String.valueOf(ip.getVlanTag()));
nic.setMacAddress(ip.getMacAddress());
}
nic.setIPv4Dns1(dc.getDns1());
nic.setIPv4Dns2(dc.getDns2());
Pair<String, String> dns = networkModel.getNetworkIp4Dns(network, dc);
nic.setIPv4Dns1(dns.first());
nic.setIPv4Dns2(dns.second());
}
}

View File

@ -16,6 +16,58 @@
// under the License.
package com.cloud.kubernetes.cluster;
import static com.cloud.utils.NumbersUtil.toHumanReadableSize;
import java.math.BigInteger;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.acl.SecurityChecker;
import org.apache.cloudstack.annotation.AnnotationService;
import org.apache.cloudstack.annotation.dao.AnnotationDao;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiConstants.VMDetails;
import org.apache.cloudstack.api.ResponseObject.ResponseView;
import org.apache.cloudstack.api.command.user.kubernetes.cluster.CreateKubernetesClusterCmd;
import org.apache.cloudstack.api.command.user.kubernetes.cluster.DeleteKubernetesClusterCmd;
import org.apache.cloudstack.api.command.user.kubernetes.cluster.GetKubernetesClusterConfigCmd;
import org.apache.cloudstack.api.command.user.kubernetes.cluster.ListKubernetesClustersCmd;
import org.apache.cloudstack.api.command.user.kubernetes.cluster.ScaleKubernetesClusterCmd;
import org.apache.cloudstack.api.command.user.kubernetes.cluster.StartKubernetesClusterCmd;
import org.apache.cloudstack.api.command.user.kubernetes.cluster.StopKubernetesClusterCmd;
import org.apache.cloudstack.api.command.user.kubernetes.cluster.UpgradeKubernetesClusterCmd;
import org.apache.cloudstack.api.response.KubernetesClusterConfigResponse;
import org.apache.cloudstack.api.response.KubernetesClusterResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
import org.apache.cloudstack.config.ApiServiceConfiguration;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import com.cloud.api.ApiDBUtils;
import com.cloud.api.query.dao.NetworkOfferingJoinDao;
import com.cloud.api.query.dao.TemplateJoinDao;
@ -117,56 +169,6 @@ import com.cloud.utils.net.NetUtils;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.dao.VMInstanceDao;
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.acl.SecurityChecker;
import org.apache.cloudstack.annotation.AnnotationService;
import org.apache.cloudstack.annotation.dao.AnnotationDao;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiConstants.VMDetails;
import org.apache.cloudstack.api.ResponseObject.ResponseView;
import org.apache.cloudstack.api.command.user.kubernetes.cluster.CreateKubernetesClusterCmd;
import org.apache.cloudstack.api.command.user.kubernetes.cluster.DeleteKubernetesClusterCmd;
import org.apache.cloudstack.api.command.user.kubernetes.cluster.GetKubernetesClusterConfigCmd;
import org.apache.cloudstack.api.command.user.kubernetes.cluster.ListKubernetesClustersCmd;
import org.apache.cloudstack.api.command.user.kubernetes.cluster.ScaleKubernetesClusterCmd;
import org.apache.cloudstack.api.command.user.kubernetes.cluster.StartKubernetesClusterCmd;
import org.apache.cloudstack.api.command.user.kubernetes.cluster.StopKubernetesClusterCmd;
import org.apache.cloudstack.api.command.user.kubernetes.cluster.UpgradeKubernetesClusterCmd;
import org.apache.cloudstack.api.response.KubernetesClusterConfigResponse;
import org.apache.cloudstack.api.response.KubernetesClusterResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
import org.apache.cloudstack.config.ApiServiceConfiguration;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import java.math.BigInteger;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import static com.cloud.utils.NumbersUtil.toHumanReadableSize;
public class KubernetesClusterManagerImpl extends ManagerBase implements KubernetesClusterService {
@ -761,7 +763,9 @@ public class KubernetesClusterManagerImpl extends ManagerBase implements Kuberne
try {
network = networkMgr.createGuestNetwork(networkOffering.getId(), clusterName + "-network", owner.getAccountName() + "-network",
null, null, null, false, null, owner, null, physicalNetwork, zone.getId(), ControlledEntity.ACLType.Account, null, null, null, null, true, null, null, null, null, null);
null, null, null, false, null, owner, null, physicalNetwork, zone.getId(),
ControlledEntity.ACLType.Account, null, null, null, null, true, null,
null, null, null, null, null, null, null, null);
} catch (ConcurrentOperationException | InsufficientCapacityException | ResourceAllocationException e) {
logAndThrow(Level.ERROR, String.format("Unable to create network for the Kubernetes cluster: %s", clusterName));
}

View File

@ -2374,6 +2374,8 @@ public class ApiResponseHelper implements ResponseGenerator {
response.setDns1(profile.getDns1());
response.setDns2(profile.getDns2());
response.setIpv6Dns1(profile.getIp6Dns1());
response.setIpv6Dns2(profile.getIp6Dns2());
// populate capability
Map<Service, Map<Capability, String>> serviceCapabilitiesMap = ApiDBUtils.getNetworkCapabilities(network.getId(), network.getDataCenterId());
Map<Service, Set<Provider>> serviceProviderMap = ApiDBUtils.listNetworkOfferingServices(network.getNetworkOfferingId());
@ -3235,6 +3237,10 @@ public class ApiResponseHelper implements ResponseGenerator {
response.setHasAnnotation(annotationDao.hasAnnotations(vpc.getUuid(), AnnotationService.EntityType.VPC.name(),
_accountMgr.isRootAdmin(CallContext.current().getCallingAccount().getId())));
ipv6Service.updateIpv6RoutesForVpcResponse(vpc, response);
response.setDns1(vpc.getIp4Dns1());
response.setDns2(vpc.getIp4Dns2());
response.setIpv6Dns1(vpc.getIp6Dns1());
response.setIpv6Dns2(vpc.getIp6Dns2());
response.setObjectName("vpc");
return response;
}

View File

@ -143,6 +143,8 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
to.setIp6Address(profile.getIPv6Address());
to.setIp6Gateway(profile.getIPv6Gateway());
to.setIp6Cidr(profile.getIPv6Cidr());
to.setIp6Dns1(profile.getIPv6Dns1());
to.setIp6Dns2(profile.getIPv6Dns2());
NetworkVO network = networkDao.findById(profile.getNetworkId());
to.setNetworkUuid(network.getUuid());

View File

@ -1802,7 +1802,8 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
s_logger.debug("Creating network for account " + owner + " from the network offering id=" + requiredOfferings.get(0).getId()
+ " as a part of createVlanIpRange process");
guestNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), owner.getAccountName() + "-network", owner.getAccountName()
+ "-network", null, null, null, false, null, owner, null, physicalNetwork, zoneId, ACLType.Account, null, null, null, null, true, null, null, null, null, null);
+ "-network", null, null, null, false, null, owner, null, physicalNetwork, zoneId, ACLType.Account, null, null, null, null, true, null, null, null, null, null,
null, null, 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 "
@ -2210,8 +2211,9 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
nic.setMacAddress(ip.getMacAddress());
}
}
nic.setIPv4Dns1(dc.getDns1());
nic.setIPv4Dns2(dc.getDns2());
Pair<String, String> dns = _networkModel.getNetworkIp4Dns(network, dc);
nic.setIPv4Dns1(dns.first());
nic.setIPv4Dns2(dns.second());
}
_ipv6Mgr.setNicIp6Address(nic, dc, network);
@ -2260,8 +2262,9 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
nic.setMacAddress(_networkModel.getNextAvailableMacAddressInNetwork(network.getId()));
}
}
nic.setIPv4Dns1(dc.getDns1());
nic.setIPv4Dns2(dc.getDns2());
Pair<String, String> dns = _networkModel.getNetworkIp4Dns(network, dc);
nic.setIPv4Dns1(dns.first());
nic.setIPv4Dns2(dns.second());
}
_ipv6Mgr.setNicIp6Address(nic, dc, network);

View File

@ -42,6 +42,7 @@ import com.cloud.network.dao.NetworkDetailsDao;
import com.cloud.network.dao.UserIpv6AddressDao;
import com.cloud.user.Account;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.Pair;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.db.DB;
import com.cloud.utils.net.NetUtils;
@ -226,8 +227,9 @@ public class Ipv6AddressManagerImpl extends ManagerBase implements Ipv6AddressMa
IPv6Address.class.getName(), null);
}
}
nic.setIPv6Dns1(dc.getIp6Dns1());
nic.setIPv6Dns2(dc.getIp6Dns2());
Pair<String, String> dns = _networkModel.getNetworkIp6Dns(network, dc);
nic.setIPv6Dns1(dns.first());
nic.setIPv6Dns2(dns.second());
}
}

View File

@ -447,8 +447,9 @@ public class Ipv6ServiceImpl extends ComponentLifecycleBase implements Ipv6Servi
} else {
nic.setFormat(Networks.AddressFormat.Ip6);
}
nic.setIPv6Dns1(dc.getIp6Dns1());
nic.setIPv6Dns2(dc.getIp6Dns2());
Pair<String, String> dns = networkModel.getNetworkIp6Dns(network, dc);
nic.setIPv6Dns1(dns.first());
nic.setIPv6Dns2(dns.second());
}
}

View File

@ -297,8 +297,9 @@ public class NetworkMigrationManagerImpl implements NetworkMigrationManager {
Vpc copyOfVpc;
long copyOfVpcId;
try {
copyOfVpc = _vpcService.createVpc(vpc.getZoneId(), vpcOfferingId, vpc.getAccountId(), vpc.getName(), vpc.getDisplayText(), vpc.getCidr(),
vpc.getNetworkDomain(), vpc.isDisplay());
copyOfVpc = _vpcService.createVpc(vpc.getZoneId(), vpcOfferingId, vpc.getAccountId(), vpc.getName(),
vpc.getDisplayText(), vpc.getCidr(), vpc.getNetworkDomain(), vpc.getIp4Dns1(), vpc.getIp4Dns2(),
vpc.getIp6Dns1(), vpc.getIp6Dns2(), vpc.isDisplay());
copyOfVpcId = copyOfVpc.getId();
//on resume of migration the uuid will be swapped already. So the copy will have the value of the original vpcid.
_resourceTagDao.persist(new ResourceTagVO(MIGRATION, Long.toString(vpcId), vpc.getAccountId(), vpc.getDomainId(), copyOfVpcId, ResourceTag.ResourceObjectType.Vpc, null, vpc.getUuid()));

View File

@ -79,6 +79,7 @@ import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.dao.NetworkAccountDao;
import com.cloud.network.dao.NetworkAccountVO;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkDetailsDao;
import com.cloud.network.dao.NetworkDomainDao;
import com.cloud.network.dao.NetworkDomainVO;
import com.cloud.network.dao.NetworkServiceMapDao;
@ -119,6 +120,7 @@ import com.cloud.user.AccountVO;
import com.cloud.user.DomainManager;
import com.cloud.user.User;
import com.cloud.user.dao.AccountDao;
import com.cloud.utils.Pair;
import com.cloud.utils.StringUtils;
import com.cloud.utils.component.AdapterBase;
import com.cloud.utils.component.ManagerBase;
@ -166,6 +168,8 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel, Confi
@Inject
NetworkDao _networksDao = null;
@Inject
NetworkDetailsDao networkDetailsDao;
@Inject
NicDao _nicDao = null;
@Inject
PodVlanMapDao _podVlanMapDao;
@ -2637,4 +2641,46 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel, Confi
String networkCidr = guestNetwork.getNetworkCidr();
return networkCidr == null ? guestNetwork.getCidr() : networkCidr;
}
@Override
public Pair<String, String> getNetworkIp4Dns(final Network network, final DataCenter zone) {
if (org.apache.commons.lang3.StringUtils.isNotBlank(network.getDns1())) {
return new Pair<>(network.getDns1(), network.getDns2());
}
return new Pair<>(zone.getDns1(), zone.getDns2());
}
@Override
public Pair<String, String> getNetworkIp6Dns(final Network network, final DataCenter zone) {
if (org.apache.commons.lang3.StringUtils.isNotBlank(network.getIp6Dns1())) {
return new Pair<>(network.getIp6Dns1(), network.getIp6Dns2());
}
return new Pair<>(zone.getIp6Dns1(), zone.getIp6Dns2());
}
@Override
public void verifyIp4DnsPair(String ip4Dns1, String ip4Dns2) {
if (org.apache.commons.lang3.StringUtils.isEmpty(ip4Dns1) && org.apache.commons.lang3.StringUtils.isNotEmpty(ip4Dns2)) {
throw new InvalidParameterValueException("Second IPv4 DNS can be specified only with the first IPv4 DNS");
}
if (org.apache.commons.lang3.StringUtils.isNotEmpty(ip4Dns1) && !NetUtils.isValidIp4(ip4Dns1)) {
throw new InvalidParameterValueException("Invalid IPv4 for DNS1");
}
if (org.apache.commons.lang3.StringUtils.isNotEmpty(ip4Dns2) && !NetUtils.isValidIp4(ip4Dns2)) {
throw new InvalidParameterValueException("Invalid IPv4 for DNS2");
}
}
@Override
public void verifyIp6DnsPair(String ip6Dns1, String ip6Dns2) {
if (org.apache.commons.lang3.StringUtils.isEmpty(ip6Dns1) && org.apache.commons.lang3.StringUtils.isNotEmpty(ip6Dns2)) {
throw new InvalidParameterValueException("Second IPv6 DNS can be specified only with the first IPv6 DNS");
}
if (org.apache.commons.lang3.StringUtils.isNotEmpty(ip6Dns1) && !NetUtils.isValidIp6(ip6Dns1)) {
throw new InvalidParameterValueException("Invalid IPv6 for IPv6 DNS1");
}
if (org.apache.commons.lang3.StringUtils.isNotEmpty(ip6Dns2) && !NetUtils.isValidIp6(ip6Dns2)) {
throw new InvalidParameterValueException("Invalid IPv6 for IPv6 DNS2");
}
}
}

View File

@ -74,6 +74,7 @@ import org.apache.cloudstack.network.dao.NetworkPermissionDao;
import org.apache.cloudstack.network.element.InternalLoadBalancerElementService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.EnumUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
@ -571,6 +572,70 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
return result;
}
private void checkNetworkDns(boolean isIpv6, NetworkOffering networkOffering, Long vpcId,
String ip4Dns1, String ip4Dns2, String ip6Dns1, String ip6Dns2) {
if (ObjectUtils.anyNotNull(ip4Dns1, ip4Dns2, ip6Dns1, ip6Dns2)) {
if (GuestType.L2.equals(networkOffering.getGuestType())) {
throw new InvalidParameterValueException(String.format("DNS can not be specified %s networks", GuestType.L2));
}
if (vpcId != null) {
throw new InvalidParameterValueException("DNS can not be specified for a VPC tier");
}
if (!areServicesSupportedByNetworkOffering(networkOffering.getId(), Service.Dns)) {
throw new InvalidParameterValueException("DNS can not be specified for networks with network offering that do not support DNS service");
}
}
if (!isIpv6 && !StringUtils.isAllEmpty(ip6Dns1, ip6Dns2)) {
throw new InvalidParameterValueException("IPv6 DNS cannot be specified for IPv4 only network");
}
_networkModel.verifyIp4DnsPair(ip4Dns1, ip4Dns2);
_networkModel.verifyIp6DnsPair(ip6Dns1, ip6Dns2);
}
protected boolean checkAndUpdateNetworkDns(NetworkVO network, NetworkOffering networkOffering, String newIp4Dns1,
String newIp4Dns2, String newIp6Dns1, String newIp6Dns2) {
String ip4Dns1 = network.getDns1();
String ip4Dns2 = network.getDns2();
String ip6Dns1 = network.getIp6Dns1();
String ip6Dns2 = network.getIp6Dns2();
if (ObjectUtils.allNull(newIp4Dns1, newIp4Dns2, newIp6Dns1, newIp6Dns2)) {
if (ObjectUtils.anyNotNull(ip4Dns1, ip4Dns2, ip6Dns1, ip6Dns2) &&
!areServicesSupportedByNetworkOffering(networkOffering.getId(), Service.Dns)) {
network.setDns1(null);
network.setDns2(null);
network.setIp6Dns1(null);
network.setIp6Dns2(null);
return true;
}
return false;
}
if (StringUtils.equals(ip4Dns1, StringUtils.trimToNull(newIp4Dns1)) && StringUtils.equals(ip4Dns2, StringUtils.trimToNull(newIp4Dns2)) &&
StringUtils.equals(ip6Dns1, StringUtils.trimToNull(newIp6Dns1)) && StringUtils.equals(ip6Dns2, StringUtils.trimToNull(newIp6Dns2))) {
return false;
}
boolean isIpv6 = (GuestType.Shared.equals(network.getGuestType()) &&
StringUtils.isNotEmpty(network.getIp6Cidr())) ||
_networkOfferingDao.isIpv6Supported(networkOffering.getId());
if (newIp4Dns1 != null) {
ip4Dns1 = StringUtils.trimToNull(newIp4Dns1);
}
if (newIp4Dns2 != null) {
ip4Dns2 = StringUtils.trimToNull(newIp4Dns2);
}
if (newIp6Dns1 != null) {
ip6Dns1 = StringUtils.trimToNull(newIp6Dns1);
}
if (newIp6Dns2 != null) {
ip6Dns2 = StringUtils.trimToNull(newIp6Dns2);
}
checkNetworkDns(isIpv6, networkOffering, network.getVpcId(), ip4Dns1, ip4Dns2, ip6Dns1, ip6Dns2);
network.setDns1(ip4Dns1);
network.setDns2(ip4Dns2);
network.setIp6Dns1(ip6Dns1);
network.setIp6Dns2(ip6Dns2);
return true;
}
@Override
public List<? extends Network> getIsolatedNetworksOwnedByAccountInZone(long zoneId, Account owner) {
@ -1273,6 +1338,10 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
String externalId = cmd.getExternalId();
String isolatedPvlanType = cmd.getIsolatedPvlanType();
Long associatedNetworkId = cmd.getAssociatedNetworkId();
String ip4Dns1 = cmd.getIp4Dns1();
String ip4Dns2 = cmd.getIp4Dns2();
String ip6Dns1 = cmd.getIp6Dns1();
String ip6Dns2 = cmd.getIp6Dns2();
// Validate network offering
NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId);
@ -1486,7 +1555,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
throw new InvalidParameterValueException("Can only support create IPv6 network with advance shared network!");
}
if(StringUtils.isAllBlank(zone.getIp6Dns1(), zone.getIp6Dns2())) {
if(StringUtils.isAllBlank(ip6Dns1, ip6Dns2, zone.getIp6Dns1(), zone.getIp6Dns2())) {
throw new InvalidParameterValueException("Can only create IPv6 network if the zone has IPv6 DNS! Please configure the zone IPv6 DNS1 and/or IPv6 DNS2.");
}
@ -1609,9 +1678,11 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
cidr, startIP, endIP);
}
checkNetworkDns(ipv6, ntwkOff, vpcId, ip4Dns1, ip4Dns2, ip6Dns1, ip6Dns2);
Network network = commitNetwork(networkOfferingId, gateway, startIP, endIP, netmask, networkDomain, vlanId, bypassVlanOverlapCheck, name, displayText, caller, physicalNetworkId, zoneId,
domainId, isDomainSpecific, subdomainAccess, vpcId, startIPv6, endIPv6, ip6Gateway, ip6Cidr, displayNetwork, aclId, secondaryVlanId, privateVlanType, ntwkOff, pNtwk, aclType, owner, cidr, createVlan,
externalId, routerIp, routerIpv6, associatedNetwork);
externalId, routerIp, routerIpv6, associatedNetwork, ip4Dns1, ip4Dns2, ip6Dns1, ip6Dns2);
if (hideIpAddressUsage) {
_networkDetailsDao.persist(new NetworkDetailVO(network.getId(), Network.hideIpAddressUsage, String.valueOf(hideIpAddressUsage), false));
@ -1753,7 +1824,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
final boolean isDomainSpecific, final Boolean subdomainAccessFinal, final Long vpcId, final String startIPv6, final String endIPv6, final String ip6Gateway, final String ip6Cidr,
final Boolean displayNetwork, final Long aclId, final String isolatedPvlan, final PVlanType isolatedPvlanType, final NetworkOfferingVO ntwkOff, final PhysicalNetwork pNtwk, final ACLType aclType, final Account ownerFinal,
final String cidr, final boolean createVlan, final String externalId, String routerIp, String routerIpv6,
final Network associatedNetwork) throws InsufficientCapacityException, ResourceAllocationException {
final Network associatedNetwork, final String ip4Dns1, final String ip4Dns2, final String ip6Dns1, final String ip6Dns2) throws InsufficientCapacityException, ResourceAllocationException {
try {
Network network = Transaction.execute(new TransactionCallbackWithException<Network, Exception>() {
@Override
@ -1812,7 +1883,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
}
}
network = _vpcMgr.createVpcGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, networkDomain, owner, sharedDomainId, pNtwk, zoneId, aclType,
subdomainAccess, vpcId, aclId, caller, displayNetwork, externalId, ip6Gateway, ip6Cidr);
subdomainAccess, vpcId, aclId, caller, displayNetwork, externalId, ip6Gateway, ip6Cidr, ip4Dns1, ip4Dns2, ip6Dns1, ip6Dns2);
} else {
if (_configMgr.isOfferingForVpc(ntwkOff)) {
throw new InvalidParameterValueException("Network offering can be used for VPC networks only");
@ -1822,7 +1893,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
}
network = _networkMgr.createGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, bypassVlanOverlapCheck, networkDomain, owner, sharedDomainId, pNtwk,
zoneId, aclType, subdomainAccess, vpcId, ip6Gateway, ip6Cidr, displayNetwork, isolatedPvlan, isolatedPvlanType, externalId, routerIp, routerIpv6);
zoneId, aclType, subdomainAccess, vpcId, ip6Gateway, ip6Cidr, displayNetwork, isolatedPvlan, isolatedPvlanType, externalId, routerIp, routerIpv6, ip4Dns1, ip4Dns2, ip6Dns1, ip6Dns2);
}
if (createVlan && network != null) {
@ -2587,6 +2658,10 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
String customId = cmd.getCustomId();
boolean updateInSequence = cmd.getUpdateInSequence();
boolean forced = cmd.getForced();
String ip4Dns1 = cmd.getIp4Dns1();
String ip4Dns2 = cmd.getIp4Dns2();
String ip6Dns1 = cmd.getIp6Dns1();
String ip6Dns2 = cmd.getIp6Dns2();
boolean restartNetwork = false;
@ -2715,6 +2790,11 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
}
}
if (checkAndUpdateNetworkDns(network, networkOfferingChanged ? networkOffering : oldNtwkOff, ip4Dns1, ip4Dns2,
ip6Dns1, ip6Dns2)) {
restartNetwork = true;
}
final Map<String, String> newSvcProviders = networkOfferingChanged
? _networkMgr.finalizeServicesAndProvidersForNetwork(_entityMgr.findById(NetworkOffering.class, networkOfferingId), network.getPhysicalNetworkId())
: new HashMap<String, String>();

View File

@ -20,9 +20,9 @@ import java.util.List;
import javax.inject.Inject;
import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import com.cloud.dc.DataCenter;
@ -36,8 +36,6 @@ import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.network.dao.PhysicalNetworkDao;
import com.cloud.network.dao.PhysicalNetworkVO;
import com.cloud.network.IpAddressManager;
import com.cloud.network.Network;
import com.cloud.network.Network.GuestType;
@ -54,8 +52,12 @@ import com.cloud.network.PhysicalNetwork.IsolationMethod;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.dao.PhysicalNetworkDao;
import com.cloud.network.dao.PhysicalNetworkVO;
import com.cloud.offering.NetworkOffering;
import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
import com.cloud.user.Account;
import com.cloud.utils.Pair;
import com.cloud.utils.component.AdapterBase;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.Transaction;
@ -217,6 +219,19 @@ public class DirectNetworkGuru extends AdapterBase implements NetworkGuru {
if (userSpecified.getRouterIpv6() != null) {
config.setRouterIpv6(userSpecified.getRouterIpv6());
}
if (StringUtils.isNotBlank(userSpecified.getDns1())) {
config.setDns1(userSpecified.getDns1());
}
if (StringUtils.isNotBlank(userSpecified.getDns2())) {
config.setDns2(userSpecified.getDns2());
}
if (StringUtils.isNotBlank(userSpecified.getIp6Dns1())) {
config.setIp6Dns1(userSpecified.getIp6Dns1());
}
if (StringUtils.isNotBlank(userSpecified.getIp6Dns2())) {
config.setIp6Dns2(userSpecified.getIp6Dns2());
}
}
boolean isSecurityGroupEnabled = _networkModel.areServicesSupportedByNetworkOffering(offering.getId(), Service.SecurityGroup);
@ -240,11 +255,13 @@ public class DirectNetworkGuru extends AdapterBase implements NetworkGuru {
@Override
public void updateNicProfile(NicProfile profile, Network network) {
DataCenter dc = _dcDao.findById(network.getDataCenterId());
Pair<String, String> ip4Dns = _networkModel.getNetworkIp4Dns(network, dc);
Pair<String, String> ip6Dns = _networkModel.getNetworkIp6Dns(network, dc);
if (profile != null) {
profile.setIPv4Dns1(dc.getDns1());
profile.setIPv4Dns2(dc.getDns2());
profile.setIPv6Dns1(dc.getIp6Dns1());
profile.setIPv6Dns2(dc.getIp6Dns2());
profile.setIPv4Dns1(ip4Dns.first());
profile.setIPv4Dns2(ip4Dns.second());
profile.setIPv6Dns1(ip6Dns.first());
profile.setIPv6Dns2(ip6Dns.second());
}
}
@ -413,7 +430,12 @@ public class DirectNetworkGuru extends AdapterBase implements NetworkGuru {
@Override
public void updateNetworkProfile(NetworkProfile networkProfile) {
DataCenter dc = _dcDao.findById(networkProfile.getDataCenterId());
networkProfile.setDns1(dc.getDns1());
networkProfile.setDns2(dc.getDns2());
Network network = _networkModel.getNetwork(networkProfile.getId());
Pair<String, String> dns = _networkModel.getNetworkIp4Dns(network, dc);
networkProfile.setDns1(dns.first());
networkProfile.setDns2(dns.second());
dns = _networkModel.getNetworkIp6Dns(network, dc);
networkProfile.setIp6Dns1(dns.first());
networkProfile.setIp6Dns2(dns.second());
}
}

View File

@ -50,6 +50,7 @@ import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.IPAddressVO;
import com.cloud.offering.NetworkOffering;
import com.cloud.offerings.dao.NetworkOfferingDao;
import com.cloud.utils.Pair;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.db.TransactionCallbackNoReturn;
@ -157,8 +158,9 @@ public class DirectPodBasedNetworkGuru extends DirectNetworkGuru {
}
DataCenter dc = _dcDao.findById(network.getDataCenterId());
nic.setIPv4Dns1(dc.getDns1());
nic.setIPv4Dns2(dc.getDns2());
Pair<String, String> dns = _networkModel.getNetworkIp4Dns(network, dc);
nic.setIPv4Dns1(dns.first());
nic.setIPv4Dns2(dns.second());
}
@DB
@ -240,8 +242,9 @@ public class DirectPodBasedNetworkGuru extends DirectNetworkGuru {
}
});
nic.setIPv4Dns1(dc.getDns1());
nic.setIPv4Dns2(dc.getDns2());
Pair<String, String> dns = _networkModel.getNetworkIp4Dns(network, dc);
nic.setIPv4Dns1(dns.first());
nic.setIPv4Dns2(dns.second());
}
}

View File

@ -59,6 +59,7 @@ import com.cloud.network.rules.PortForwardingRuleVO;
import com.cloud.network.rules.dao.PortForwardingRulesDao;
import com.cloud.offering.NetworkOffering;
import com.cloud.user.Account;
import com.cloud.utils.Pair;
import com.cloud.utils.db.DB;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.net.Ip;
@ -321,8 +322,9 @@ public class ExternalGuestNetworkGuru extends GuestNetworkGuru {
if (_networkModel.networkIsConfiguredForExternalNetworking(config.getDataCenterId(), config.getId())) {
nic.setBroadcastUri(config.getBroadcastUri());
nic.setIsolationUri(config.getBroadcastUri());
nic.setIPv4Dns1(dc.getDns1());
nic.setIPv4Dns2(dc.getDns2());
Pair<String, String> dns = _networkModel.getNetworkIp4Dns(config, dc);
nic.setIPv4Dns1(dns.first());
nic.setIPv4Dns2(dns.second());
nic.setIPv4Netmask(NetUtils.cidr2Netmask(config.getCidr()));
long cidrAddress = NetUtils.ip2Long(config.getCidr().split("/")[0]);
int cidrSize = getGloballyConfiguredCidrSize();

View File

@ -28,6 +28,7 @@ import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationSe
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.framework.config.Configurable;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import com.cloud.configuration.Config;
@ -258,6 +259,19 @@ public abstract class GuestNetworkGuru extends AdapterBase implements NetworkGur
network.setPvlanType(userSpecified.getPvlanType());
}
}
if (StringUtils.isNotBlank(userSpecified.getDns1())) {
network.setDns1(userSpecified.getDns1());
}
if (StringUtils.isNotBlank(userSpecified.getDns2())) {
network.setDns2(userSpecified.getDns2());
}
if (StringUtils.isNotBlank(userSpecified.getIp6Dns1())) {
network.setIp6Dns1(userSpecified.getIp6Dns1());
}
if (StringUtils.isNotBlank(userSpecified.getIp6Dns2())) {
network.setIp6Dns2(userSpecified.getIp6Dns2());
}
} else {
final String guestNetworkCidr = dc.getGuestNetworkCidr();
if (guestNetworkCidr == null && dc.getNetworkType() == NetworkType.Advanced) {
@ -437,8 +451,9 @@ public abstract class GuestNetworkGuru extends AdapterBase implements NetworkGur
nic.setIPv4Netmask(NetUtils.cidr2Netmask(_networkModel.getValidNetworkCidr(network)));
}
nic.setIPv4Dns1(dc.getDns1());
nic.setIPv4Dns2(dc.getDns2());
Pair<String, String> dns = _networkModel.getNetworkIp4Dns(network, dc);
nic.setIPv4Dns1(dns.first());
nic.setIPv4Dns2(dns.second());
nic.setFormat(AddressFormat.Ip4);
}
}
@ -458,9 +473,13 @@ public abstract class GuestNetworkGuru extends AdapterBase implements NetworkGur
@Override
public void updateNicProfile(final NicProfile profile, final Network network) {
final DataCenter dc = _dcDao.findById(network.getDataCenterId());
Pair<String, String> dns = _networkModel.getNetworkIp4Dns(network, dc);
Pair<String, String> ip6Dns = _networkModel.getNetworkIp6Dns(network, dc);
if (profile != null) {
profile.setIPv4Dns1(dc.getDns1());
profile.setIPv4Dns2(dc.getDns2());
profile.setIPv4Dns1(dns.first());
profile.setIPv4Dns2(dns.second());
profile.setIPv6Dns1(ip6Dns.first());
profile.setIPv6Dns2(ip6Dns.second());
}
}
@ -506,8 +525,13 @@ public abstract class GuestNetworkGuru extends AdapterBase implements NetworkGur
@Override
public void updateNetworkProfile(final NetworkProfile networkProfile) {
final DataCenter dc = _dcDao.findById(networkProfile.getDataCenterId());
networkProfile.setDns1(dc.getDns1());
networkProfile.setDns2(dc.getDns2());
Network network = _networkModel.getNetwork(networkProfile.getId());
Pair<String, String> dns = _networkModel.getNetworkIp4Dns(network, dc);
networkProfile.setDns1(dns.first());
networkProfile.setDns2(dns.second());
dns = _networkModel.getNetworkIp6Dns(network, dc);
networkProfile.setIp6Dns1(dns.first());
networkProfile.setIp6Dns2(dns.second());
}
@Override

View File

@ -44,6 +44,7 @@ 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.Pair;
import com.cloud.utils.component.AdapterBase;
import com.cloud.utils.db.EntityManager;
import com.cloud.utils.exception.CloudRuntimeException;
@ -60,7 +61,7 @@ public class PrivateNetworkGuru extends AdapterBase implements NetworkGuru {
@Inject
protected PrivateIpDao _privateIpDao;
@Inject
protected NetworkModel _networkMgr;
protected NetworkModel networkModel;
@Inject
EntityManager _entityMgr;
@ -199,16 +200,22 @@ public class PrivateNetworkGuru extends AdapterBase implements NetworkGuru {
nic.setMacAddress(ip.getMacAddress());
}
nic.setIPv4Dns1(dc.getDns1());
nic.setIPv4Dns2(dc.getDns2());
Pair<String, String> dns = networkModel.getNetworkIp4Dns(network, dc);
nic.setIPv4Dns1(dns.first());
nic.setIPv4Dns2(dns.second());
}
@Override
public void updateNicProfile(NicProfile profile, Network network) {
DataCenter dc = _entityMgr.findById(DataCenter.class, network.getDataCenterId());
Pair<String, String> dns = networkModel.getNetworkIp4Dns(network, dc);
Pair<String, String> ip6Dns = networkModel.getNetworkIp6Dns(network, dc);
if (profile != null) {
profile.setIPv4Dns1(dc.getDns1());
profile.setIPv4Dns2(dc.getDns2());
profile.setIPv4Dns1(dns.first());
profile.setIPv4Dns2(dns.second());
profile.setIPv6Dns1(ip6Dns.first());
profile.setIPv6Dns2(ip6Dns.second());
}
}
@ -239,7 +246,12 @@ public class PrivateNetworkGuru extends AdapterBase implements NetworkGuru {
@Override
public void updateNetworkProfile(NetworkProfile networkProfile) {
DataCenter dc = _entityMgr.findById(DataCenter.class, networkProfile.getDataCenterId());
networkProfile.setDns1(dc.getDns1());
networkProfile.setDns2(dc.getDns2());
Network network = networkModel.getNetwork(networkProfile.getId());
Pair<String, String> dns = networkModel.getNetworkIp4Dns(network, dc);
networkProfile.setDns1(dns.first());
networkProfile.setDns2(dns.second());
dns = networkModel.getNetworkIp6Dns(network, dc);
networkProfile.setIp6Dns1(dns.first());
networkProfile.setIp6Dns2(dns.second());
}
}

View File

@ -34,6 +34,7 @@ import com.cloud.network.IpAddressManager;
import com.cloud.network.Ipv6Service;
import com.cloud.network.Network;
import com.cloud.network.Network.State;
import com.cloud.network.NetworkModel;
import com.cloud.network.NetworkProfile;
import com.cloud.network.Networks.AddressFormat;
import com.cloud.network.Networks.BroadcastDomainType;
@ -46,6 +47,7 @@ import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.dao.NetworkVO;
import com.cloud.offering.NetworkOffering;
import com.cloud.user.Account;
import com.cloud.utils.Pair;
import com.cloud.utils.component.AdapterBase;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.Transaction;
@ -73,6 +75,8 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru {
IpAddressManager _ipAddrMgr;
@Inject
Ipv6Service ipv6Service;
@Inject
NetworkModel networkModel;
private static final TrafficType[] TrafficTypes = {TrafficType.Public};
@ -140,8 +144,9 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru {
nic.setMacAddress(ip.getMacAddress());
}
nic.setIPv4Dns1(dc.getDns1());
nic.setIPv4Dns2(dc.getDns2());
Pair<String, String> dns = networkModel.getNetworkIp4Dns(network, dc);
nic.setIPv4Dns1(dns.first());
nic.setIPv4Dns2(dns.second());
ipv6Service.updateNicIpv6(nic, dc, network);
}
@ -149,9 +154,13 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru {
@Override
public void updateNicProfile(NicProfile profile, Network network) {
DataCenter dc = _dcDao.findById(network.getDataCenterId());
Pair<String, String> dns = networkModel.getNetworkIp4Dns(network, dc);
Pair<String, String> ip6Dns = networkModel.getNetworkIp6Dns(network, dc);
if (profile != null) {
profile.setIPv4Dns1(dc.getDns1());
profile.setIPv4Dns2(dc.getDns2());
profile.setIPv4Dns1(dns.first());
profile.setIPv4Dns2(dns.second());
profile.setIPv6Dns1(ip6Dns.first());
profile.setIPv6Dns2(ip6Dns.second());
}
}
@ -237,8 +246,13 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru {
@Override
public void updateNetworkProfile(NetworkProfile networkProfile) {
DataCenter dc = _dcDao.findById(networkProfile.getDataCenterId());
networkProfile.setDns1(dc.getDns1());
networkProfile.setDns2(dc.getDns2());
Network network = networkModel.getNetwork(networkProfile.getId());
Pair<String, String> dns = networkModel.getNetworkIp4Dns(network, dc);
networkProfile.setDns1(dns.first());
networkProfile.setDns2(dns.second());
dns = networkModel.getNetworkIp6Dns(network, dc);
networkProfile.setIp6Dns1(dns.first());
networkProfile.setIp6Dns2(dns.second());
}
}

View File

@ -1116,18 +1116,20 @@ public class CommandSetupHelper {
if (setupDns) {
final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
if (guestNic.getIPv4Dns1() != null) {
defaultDns1 = guestNic.getIPv4Dns1();
} else {
defaultDns1 = dcVo.getDns1();
defaultDns1 = guestNic.getIPv4Dns1();
defaultDns2 = guestNic.getIPv4Dns2();
if (org.apache.commons.lang3.StringUtils.isAllBlank(guestNic.getIPv4Dns1(), guestNic.getIPv4Dns2())) {
Pair<String, String> dns = _networkModel.getNetworkIp4Dns(network, dcVo);
defaultDns1 = dns.first();
defaultDns2 = dns.second();
}
if (guestNic.getIPv4Dns2() != null) {
defaultDns2 = guestNic.getIPv4Dns2();
} else {
defaultDns2 = dcVo.getDns2();
defaultIp6Dns1 = guestNic.getIPv6Dns1();
defaultIp6Dns2 = guestNic.getIPv6Dns2();
if (org.apache.commons.lang3.StringUtils.isAllBlank(guestNic.getIPv6Dns1(), guestNic.getIPv6Dns2())) {
Pair<String, String> dns = _networkModel.getNetworkIp6Dns(network, dcVo);
defaultIp6Dns1 = dns.first();
defaultIp6Dns2 = dns.second();
}
defaultIp6Dns1 = dcVo.getIp6Dns1();
defaultIp6Dns2 = dcVo.getIp6Dns2();
}
final Nic nic = _nicDao.findByNtwkIdAndInstanceId(network.getId(), router.getId());

View File

@ -1984,8 +1984,8 @@ Configurable, StateListener<VirtualMachine.State, VirtualMachine.Event, VirtualM
buf.append(" gateway=").append(nic.getIPv4Gateway());
}
if (ipv6) {
defaultIp6Dns1 = nic.getIPv6Dns1() != null? nic.getIPv6Dns1() : dc.getIp6Dns1();
defaultIp6Dns2 = nic.getIPv6Dns2() != null? nic.getIPv6Dns2() : dc.getIp6Dns2();
defaultIp6Dns1 = nic.getIPv6Dns1();
defaultIp6Dns2 = nic.getIPv6Dns2();
buf.append(" ip6gateway=").append(nic.getIPv6Gateway());
}
defaultDns1 = nic.getIPv4Dns1();

View File

@ -252,6 +252,8 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian
if (domainRouterVO.getState() == State.Starting || domainRouterVO.getState() == State.Running) {
String defaultDns1 = null;
String defaultDns2 = null;
String defaultIp6Dns1 = null;
String defaultIp6Dns2 = null;
// remove public and guest nics as we will plug them later
final Iterator<NicProfile> it = profile.getNics().iterator();
while (it.hasNext()) {
@ -261,6 +263,8 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian
if (nic.getTrafficType() == TrafficType.Public) {
defaultDns1 = nic.getIPv4Dns1();
defaultDns2 = nic.getIPv4Dns2();
defaultIp6Dns1 = nic.getIPv6Dns1();
defaultIp6Dns2 = nic.getIPv6Dns2();
}
s_logger.debug("Removing nic " + nic + " of type " + nic.getTrafficType() + " from the nics passed on vm start. " + "The nic will be plugged later");
it.remove();
@ -276,6 +280,12 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian
if (defaultDns2 != null) {
buf.append(" dns2=").append(defaultDns2);
}
if (defaultIp6Dns1 != null) {
buf.append(" ip6dns1=").append(defaultIp6Dns1);
}
if (defaultIp6Dns2 != null) {
buf.append(" ip6dns2=").append(defaultIp6Dns2);
}
}
}

View File

@ -47,6 +47,7 @@ import org.apache.cloudstack.api.command.admin.vpc.CreatePrivateGatewayByAdminCm
import org.apache.cloudstack.api.command.admin.vpc.CreateVPCOfferingCmd;
import org.apache.cloudstack.api.command.admin.vpc.UpdateVPCOfferingCmd;
import org.apache.cloudstack.api.command.user.vpc.CreatePrivateGatewayCmd;
import org.apache.cloudstack.api.command.user.vpc.CreateVPCCmd;
import org.apache.cloudstack.api.command.user.vpc.ListPrivateGatewaysCmd;
import org.apache.cloudstack.api.command.user.vpc.ListStaticRoutesCmd;
import org.apache.cloudstack.api.command.user.vpc.ListVPCOfferingsCmd;
@ -57,6 +58,7 @@ import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
import org.apache.cloudstack.query.QueryService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.log4j.Logger;
import com.cloud.api.query.dao.VpcOfferingJoinDao;
@ -261,6 +263,17 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
hTypes.add(HypervisorType.Ovm3);
}
private void checkVpcDns(VpcOffering vpcOffering, String ip4Dns1, String ip4Dns2, String ip6Dns1, String ip6Dns2) {
if (ObjectUtils.anyNotNull(ip4Dns1, ip4Dns2, ip6Dns1, ip6Dns2) && !areServicesSupportedByVpcOffering(vpcOffering.getId(), Service.Dns)) {
throw new InvalidParameterValueException("DNS can not be specified for VPCs with offering that do not support DNS service");
}
if (!_vpcOffDao.isIpv6Supported(vpcOffering.getId()) && !org.apache.commons.lang3.StringUtils.isAllBlank(ip6Dns1, ip6Dns2)) {
throw new InvalidParameterValueException("IPv6 DNS can be specified for IPv6 enabled VPC");
}
_ntwkModel.verifyIp4DnsPair(ip4Dns1, ip4Dns2);
_ntwkModel.verifyIp6DnsPair(ip6Dns1, ip6Dns2);
}
@Override
@DB
public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
@ -788,7 +801,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
}
protected boolean areServicesSupportedByVpcOffering(final long vpcOffId, final Service... services) {
return _vpcOffSvcMapDao.areServicesSupportedByNetworkOffering(vpcOffId, services);
return _vpcOffSvcMapDao.areServicesSupportedByVpcOffering(vpcOffId, services);
}
@Override
@ -969,7 +982,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
@Override
@ActionEvent(eventType = EventTypes.EVENT_VPC_CREATE, eventDescription = "creating vpc", create = true)
public Vpc createVpc(final long zoneId, final long vpcOffId, final long vpcOwnerId, final String vpcName, final String displayText, final String cidr, String networkDomain,
final Boolean displayVpc) throws ResourceAllocationException {
final String ip4Dns1, final String ip4Dns2, final String ip6Dns1, final String ip6Dns2, final Boolean displayVpc) throws ResourceAllocationException {
final Account caller = CallContext.current().getCallingAccount();
final Account owner = _accountMgr.getAccount(vpcOwnerId);
@ -979,9 +992,15 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
// check resource limit
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.vpc);
// Validate zone
final DataCenter zone = _dcDao.findById(zoneId);
if (zone == null) {
throw new InvalidParameterValueException("Can't find zone by id specified");
}
// Validate vpc offering
final VpcOfferingVO vpcOff = _vpcOffDao.findById(vpcOffId);
_accountMgr.checkAccess(owner, vpcOff, _dcDao.findById(zoneId));
_accountMgr.checkAccess(owner, vpcOff, zone);
if (vpcOff == null || vpcOff.getState() != State.Enabled) {
final InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find vpc offering in " + State.Enabled + " state by specified id");
if (vpcOff == null) {
@ -997,12 +1016,6 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
throw new InvalidParameterValueException("Network domain must be specified for region level VPC");
}
// Validate zone
final DataCenter zone = _entityMgr.findById(DataCenter.class, zoneId);
if (zone == null) {
throw new InvalidParameterValueException("Can't find zone by id specified");
}
if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getId())) {
// See DataCenterVO.java
final PermissionDeniedException ex = new PermissionDeniedException("Cannot perform this operation since specified Zone is currently disabled");
@ -1021,13 +1034,23 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
}
}
checkVpcDns(vpcOff, ip4Dns1, ip4Dns2, ip6Dns1, ip6Dns2);
final boolean useDistributedRouter = vpcOff.isSupportsDistributedRouter();
final VpcVO vpc = new VpcVO(zoneId, vpcName, displayText, owner.getId(), owner.getDomainId(), vpcOffId, cidr, networkDomain, useDistributedRouter, isRegionLevelVpcOff,
vpcOff.isRedundantRouter());
vpcOff.isRedundantRouter(), ip4Dns1, ip4Dns2, ip6Dns1, ip6Dns2);
return createVpc(displayVpc, vpc);
}
@Override
@ActionEvent(eventType = EventTypes.EVENT_VPC_CREATE, eventDescription = "creating vpc", create = true)
public Vpc createVpc(CreateVPCCmd cmd) throws ResourceAllocationException {
return createVpc(cmd.getZoneId(), cmd.getVpcOffering(), cmd.getEntityOwnerId(), cmd.getVpcName(), cmd.getDisplayText(),
cmd.getCidr(), cmd.getNetworkDomain(), cmd.getIp4Dns1(), cmd.getIp4Dns2(), cmd.getIp6Dns1(),
cmd.getIp6Dns2(), cmd.isDisplay());
}
@DB
protected Vpc createVpc(final Boolean displayVpc, final VpcVO vpc) {
final String cidr = vpc.getCidr();
@ -2687,7 +2710,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
@Override
public Network createVpcGuestNetwork(final long ntwkOffId, final String name, final String displayText, final String gateway, final String cidr, final String vlanId,
String networkDomain, final Account owner, final Long domainId, final PhysicalNetwork pNtwk, final long zoneId, final ACLType aclType, final Boolean subdomainAccess,
final long vpcId, final Long aclId, final Account caller, final Boolean isDisplayNetworkEnabled, String externalId, String ip6Gateway, String ip6Cidr) throws ConcurrentOperationException, InsufficientCapacityException,
final long vpcId, final Long aclId, final Account caller, final Boolean isDisplayNetworkEnabled, String externalId, String ip6Gateway, String ip6Cidr, final String ip4Dns1, final String ip4Dns2, final String ip6Dns1, final String ip6Dns2) throws ConcurrentOperationException, InsufficientCapacityException,
ResourceAllocationException {
final Vpc vpc = getActiveVpc(vpcId);
@ -2712,7 +2735,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
// 2) Create network
final Network guestNetwork = _ntwkMgr.createGuestNetwork(ntwkOffId, name, displayText, gateway, cidr, vlanId, false, networkDomain, owner, domainId, pNtwk, zoneId, aclType,
subdomainAccess, vpcId, ip6Gateway, ip6Cidr, isDisplayNetworkEnabled, null, null, externalId, null, null);
subdomainAccess, vpcId, ip6Gateway, ip6Cidr, isDisplayNetworkEnabled, null, null, externalId, null, null, ip4Dns1, ip4Dns2, ip6Dns1, ip6Dns2);
if (guestNetwork != null) {
guestNetwork.setNetworkACLId(aclId);

View File

@ -3752,7 +3752,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
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, false, null, owner, null, physicalNetwork, zone.getId(), ACLType.Account, null, null, null, null, true, null, null,
null, null, null);
null, null, null, null, null, null, null);
if (newNetwork != null) {
defaultNetwork = _networkDao.findById(newNetwork.getId());
}
@ -7277,7 +7277,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
Network newNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), newAccount.getAccountName() + "-network",
newAccount.getAccountName() + "-network", null, null, null, false, null, newAccount,
null, physicalNetwork, zone.getId(), ACLType.Account, null, null,
null, null, true, null, null, null, null, null);
null, null, true, null, null, null, null, null, null, null, null, null);
// if the network offering has persistent set to true, implement the network
if (requiredOfferings.get(0).isPersistent()) {
DeployDestination dest = new DeployDestination(zone, null, null, null);

View File

@ -129,7 +129,7 @@ public class CreatePrivateNetworkTest {
ACLType.Account, false, 1L, false);
when(networkService._networkMgr.createGuestNetwork(eq(ntwkOff.getId()), eq("bla"), eq("fake"), eq("10.1.1.1"), eq("10.1.1.0/24"), nullable(String.class), nullable(Boolean.class), nullable(String.class),
eq(account), nullable(Long.class), eq(physicalNetwork), eq(physicalNetwork.getDataCenterId()), eq(ACLType.Account), nullable(Boolean.class), eq(1L), nullable(String.class), nullable(String.class),
nullable(Boolean.class), nullable(String.class), nullable(Network.PVlanType.class), nullable(String.class), nullable(String.class), nullable(String.class))).thenReturn(net);
nullable(Boolean.class), nullable(String.class), nullable(Network.PVlanType.class), nullable(String.class), nullable(String.class), nullable(String.class), nullable(String.class), nullable(String.class), nullable(String.class), nullable(String.class))).thenReturn(net);
when(
networkService._networkMgr.createPrivateNetwork(eq(ntwkOff.getId()), eq("bla"), eq("fake"), eq("10.1.1.1"), eq("10.1.1.0/24"), anyString(), anyBoolean(), eq(account), eq(physicalNetwork), eq(1L))).thenReturn(net);

View File

@ -19,8 +19,6 @@ package com.cloud.network;
import static org.mockito.Mockito.mock;
import com.cloud.dc.DataCenter;
import com.cloud.vm.NicProfile;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@ -28,6 +26,7 @@ import org.mockito.InjectMocks;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import com.cloud.dc.DataCenter;
import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.network.IpAddress.State;
@ -36,7 +35,9 @@ import com.cloud.network.dao.IPAddressDaoImpl;
import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.dao.UserIpv6AddressDaoImpl;
import com.cloud.user.Account;
import com.cloud.utils.Pair;
import com.cloud.utils.net.NetUtils;
import com.cloud.vm.NicProfile;
import com.cloud.vm.dao.NicSecondaryIpDaoImpl;
import com.cloud.vm.dao.NicSecondaryIpVO;
@ -239,8 +240,7 @@ public class Ipv6AddressManagerTest {
Mockito.when(network.getIp6Cidr()).thenReturn("2001:db8:100::/64");
Mockito.when(network.getIp6Gateway()).thenReturn("2001:db8:100::1");
Mockito.when(dc.getIp6Dns1()).thenReturn("2001:db8::53:1");
Mockito.when(dc.getIp6Dns1()).thenReturn("2001:db8::53:2");
Mockito.when(networkModel.getNetworkIp6Dns(network, dc)).thenReturn(new Pair<>("2001:db8::53:1", "2001:db8::53:2"));
String expected = "2001:db8:100:0:1c00:b1ff:fe00:af6";

View File

@ -120,13 +120,11 @@ public class Ipv6ServiceImplTest {
DomainRouterDao domainRouterDao;
@Mock
AccountManager accountManager;
@Mock
NetworkModel networkModel = Mockito.mock(NetworkModelImpl.class);
@Mock
IPAddressDao ipAddressDao;
@Mock
NetworkOrchestrationService networkOrchestrationService;
FirewallManager firewallManager = Mockito.mock(FirewallManager.class);
@InjectMocks
@ -145,6 +143,7 @@ public class Ipv6ServiceImplTest {
final String gateway = "fd17:5:8a43:e2a5::1";
final String macAddress = "1e:00:4c:00:00:03";
final String ipv6Address = "fd17:5:8a43:e2a5:1c00:4cff:fe00:3"; // Resulting IPv6 address using SLAAC
final Pair<String, String> ipv6DnsPair = new Pair<>("2001:db8::53:1", "2001:db8::53:2");
public static final long ACCOUNT_ID = 1;
private AccountVO account;
@ -485,6 +484,7 @@ public class Ipv6ServiceImplTest {
@Test
public void testIpv6NetworkUpdateNicIpv6() {
Mockito.when(networkOfferingDao.isIpv6Supported(Mockito.anyLong())).thenReturn(true);
Mockito.when(networkModel.getNetworkIp6Dns(Mockito.any(Network.class), Mockito.any(DataCenter.class))).thenReturn(ipv6DnsPair);
NicProfile nicProfile = new NicProfile();
nicProfile.setBroadcastUri(URI.create(vlan));
nicProfile.setMacAddress(macAddress);
@ -502,6 +502,7 @@ public class Ipv6ServiceImplTest {
@Test
public void testIpv6NetworkFromPlaceholderUpdateNicIpv6() {
Mockito.when(networkOfferingDao.isIpv6Supported(Mockito.anyLong())).thenReturn(true);
Mockito.when(networkModel.getNetworkIp6Dns(Mockito.any(Network.class), Mockito.any(DataCenter.class))).thenReturn(ipv6DnsPair);
NicProfile nicProfile = new NicProfile();
nicProfile.setBroadcastUri(URI.create(vlan));
nicProfile.setMacAddress(macAddress);

View File

@ -24,6 +24,7 @@ import java.util.Set;
import javax.naming.ConfigurationException;
import com.cloud.dc.DataCenter;
import com.cloud.dc.Vlan;
import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InvalidParameterValueException;
@ -44,6 +45,7 @@ import com.cloud.offering.NetworkOffering;
import com.cloud.offering.NetworkOffering.Detail;
import com.cloud.offerings.NetworkOfferingVO;
import com.cloud.user.Account;
import com.cloud.utils.Pair;
import com.cloud.utils.component.ManagerBase;
import com.cloud.vm.Nic;
import com.cloud.vm.NicProfile;
@ -918,4 +920,19 @@ public class MockNetworkModelImpl extends ManagerBase implements NetworkModel {
return null;
}
@Override
public Pair<String, String> getNetworkIp4Dns(Network network, DataCenter zone) {
return new Pair<>(null, null);
}
@Override
public Pair<String, String> getNetworkIp6Dns(Network network, DataCenter zone) {
return new Pair<>(null, null);
}
@Override
public void verifyIp4DnsPair(String ip4Dns1, String ip4Dns2) {}
@Override
public void verifyIp6DnsPair(String ip4Dns1, String ip4Dns2) {}
}

View File

@ -0,0 +1,144 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with 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.
package com.cloud.network;
import org.junit.Assert;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mockito;
import com.cloud.dc.DataCenter;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.utils.Pair;
public class NetworkModelImplTest {
final String[] ip4Dns1 = {"5.5.5.5", "6.6.6.6"};
final String[] ip4Dns2 = {"7.7.7.7", "8.8.8.8"};
final String[] ip6Dns1 = {"2001:4860:4860::5555", "2001:4860:4860::6666"};
final String[] ip6Dns2 = {"2001:4860:4860::7777", "2001:4860:4860::8888"};
@InjectMocks
private NetworkModelImpl networkModel = new NetworkModelImpl();
private void prepareMocks(boolean isIp6, Network network, DataCenter zone,
String dns1, String dns2, String dns3, String dns4) {
if (isIp6) {
Mockito.when(network.getIp6Dns1()).thenReturn(dns1);
Mockito.when(zone.getIp6Dns1()).thenReturn(dns2);
Mockito.when(network.getIp6Dns2()).thenReturn(dns3);
Mockito.when(zone.getIp6Dns2()).thenReturn(dns4);
} else {
Mockito.when(network.getDns1()).thenReturn(dns1);
Mockito.when(zone.getDns1()).thenReturn(dns2);
Mockito.when(network.getDns2()).thenReturn(dns3);
Mockito.when(zone.getDns2()).thenReturn(dns4);
}
}
private void testDnsCases(boolean isIp6) {
String[] dns1 = isIp6 ? ip6Dns1 : ip4Dns1;
String[] dns2 = isIp6 ? ip6Dns2 : ip4Dns2;
Network network = Mockito.mock(Network.class);
DataCenter zone = Mockito.mock(DataCenter.class);
// Both network and zone have valid dns
prepareMocks(isIp6, network, zone, dns1[0], dns1[1], dns2[0], dns1[1]);
Pair<String, String> result = isIp6 ? networkModel.getNetworkIp6Dns(network, zone) :
networkModel.getNetworkIp4Dns(network, zone);
Assert.assertEquals(dns1[0], result.first());
Assert.assertEquals(dns2[0], result.second());
// Network has valid dns and zone don't
prepareMocks(isIp6, network, zone, dns1[0], null, dns2[0], null);
result = isIp6 ? networkModel.getNetworkIp6Dns(network, zone) :
networkModel.getNetworkIp4Dns(network, zone);
Assert.assertEquals(dns1[0], result.first());
Assert.assertEquals(dns2[0], result.second());
// Zone has a valid dns and network don't
prepareMocks(isIp6, network, zone, null, dns1[1], null, dns2[1]);
result = isIp6 ? networkModel.getNetworkIp6Dns(network, zone) :
networkModel.getNetworkIp4Dns(network, zone);
Assert.assertEquals(dns1[1], result.first());
Assert.assertEquals(dns2[1], result.second());
// Zone has a valid dns and network has only first dns
prepareMocks(isIp6, network, zone, dns1[0], dns1[1], null, dns2[1]);
result = isIp6 ? networkModel.getNetworkIp6Dns(network, zone) :
networkModel.getNetworkIp4Dns(network, zone);
Assert.assertEquals(dns1[0], result.first());
Assert.assertNull(result.second());
// Both network and zone only have the first dns
prepareMocks(isIp6, network, zone, dns1[0], dns1[1], null, null);
result = isIp6 ? networkModel.getNetworkIp6Dns(network, zone) :
networkModel.getNetworkIp4Dns(network, zone);
Assert.assertEquals(dns1[0], result.first());
Assert.assertNull(result.second());
// Both network and zone dns are null
prepareMocks(isIp6, network, zone, null, null, null, null);
result = isIp6 ? networkModel.getNetworkIp6Dns(network, zone) :
networkModel.getNetworkIp4Dns(network, zone);
Assert.assertNull(result.first());
Assert.assertNull(result.second());
}
@Test
public void testGetNetworkIp4Dns() {
testDnsCases(false);
}
@Test
public void testGetNetworkIp6Dns() {
testDnsCases(true);
}
@Test(expected = InvalidParameterValueException.class)
public void testVerifyIp4DnsPairDns1NullFailure() {
networkModel.verifyIp4DnsPair(null, ip4Dns1[1]);
}
@Test(expected = InvalidParameterValueException.class)
public void testVerifyIp4DnsPairInvalidDns1Failure() {
networkModel.verifyIp4DnsPair("invalid", ip4Dns1[1]);
}
@Test(expected = InvalidParameterValueException.class)
public void testVerifyIp4DnsPairInvalidDns2Failure() {
networkModel.verifyIp4DnsPair(ip4Dns1[0], "invalid");
}
@Test
public void testVerifyIp4DnsPairValid() {
networkModel.verifyIp4DnsPair(ip4Dns1[0], ip4Dns1[1]);
}
@Test(expected = InvalidParameterValueException.class)
public void testVerifyIp6DnsPairDns1NullFailure() {
networkModel.verifyIp6DnsPair(null, ip6Dns1[1]);
}
@Test(expected = InvalidParameterValueException.class)
public void testVerifyIp6DnsPairInvalidDns1Failure() {
networkModel.verifyIp6DnsPair("invalid", ip6Dns1[1]);
}
@Test(expected = InvalidParameterValueException.class)
public void testVerifyIp6DnsPairInvalidDns2Failure() {
networkModel.verifyIp6DnsPair(ip6Dns1[0], "invalid");
}
@Test
public void testVerifyIp6DnsPairValid() {
networkModel.verifyIp6DnsPair(ip6Dns1[0], ip6Dns1[1]);
}
}

View File

@ -16,18 +16,89 @@
// under the License.
package com.cloud.network;
import com.cloud.utils.Pair;
import com.cloud.utils.exception.CloudRuntimeException;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.UUID;
import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.dao.PhysicalNetworkDao;
import com.cloud.network.dao.PhysicalNetworkVO;
import com.cloud.offering.NetworkOffering;
import com.cloud.offerings.NetworkOfferingVO;
import com.cloud.offerings.dao.NetworkOfferingDao;
import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.AccountVO;
import com.cloud.user.User;
import com.cloud.user.UserVO;
import com.cloud.utils.Pair;
import com.cloud.utils.component.ComponentContext;
import com.cloud.utils.exception.CloudRuntimeException;
@RunWith(PowerMockRunner.class)
@PrepareForTest(ComponentContext.class)
public class NetworkServiceImplTest {
@Mock
AccountManager accountManager;
@Mock
NetworkOfferingDao networkOfferingDao;
@Mock
PhysicalNetworkDao physicalNetworkDao;
@Mock
DataCenterDao dataCenterDao;
@Mock
NetworkOrchestrationService networkOrchestrationService;
@Mock
Ipv6Service ipv6Service;
@Mock
NetworkModel networkModel;
@Mock
NetworkOfferingServiceMapDao networkOfferingServiceMapDao;
@InjectMocks
private NetworkServiceImpl service = new NetworkServiceImpl();
private static final String VLAN_ID_900 = "900";
private static final String VLAN_ID_901 = "901";
private static final String VLAN_ID_902 = "902";
public static final long ACCOUNT_ID = 1;
private static final String IP4_GATEWAY = "10.0.16.1";
private static final String IP4_NETMASK = "255.255.255.0";
private static final String IP6_GATEWAY = "fd17:ac56:1234:2000::1";
private static final String IP6_CIDR = "fd17:ac56:1234:2000::/64";
final String[] ip4Dns = {"5.5.5.5", "6.6.6.6"};
final String[] ip6Dns = {"2001:4860:4860::5555", "2001:4860:4860::6666"};
private AccountVO account;
private UserVO user;
private void registerCallContext() {
account = new AccountVO("testaccount", 1L, "networkdomain", Account.Type.NORMAL, "uuid");
account.setId(ACCOUNT_ID);
user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone",
UUID.randomUUID().toString(), User.Source.UNKNOWN);
CallContext.register(user, account);
}
@Test
public void testGetPrivateVlanPairNoVlans() {
@ -117,4 +188,229 @@ public class NetworkServiceImplTest {
service.performBasicPrivateVlanChecks(VLAN_ID_900, VLAN_ID_901, Network.PVlanType.Promiscuous);
}
private void prepareCreateNetworkDnsMocks(CreateNetworkCmd cmd, Network.GuestType guestType, boolean ipv6, boolean isVpc, boolean dnsServiceSupported) {
long networkOfferingId = 1L;
Mockito.when(cmd.getNetworkOfferingId()).thenReturn(networkOfferingId);
NetworkOfferingVO networkOfferingVO = Mockito.mock(NetworkOfferingVO.class);
Mockito.when(networkOfferingVO.getId()).thenReturn(networkOfferingId);
Mockito.when(networkOfferingVO.getGuestType()).thenReturn(guestType);
Mockito.when(networkOfferingVO.getTrafficType()).thenReturn(Networks.TrafficType.Guest);
Mockito.when(networkOfferingVO.isSpecifyIpRanges()).thenReturn(true);
Mockito.when(networkOfferingDao.findById(networkOfferingId)).thenReturn(networkOfferingVO);
Mockito.when(accountManager.finalizeOwner(Mockito.any(), Mockito.any(), Mockito.anyLong(), Mockito.anyLong())).thenReturn(account);
if (Network.GuestType.Shared.equals(guestType)) {
Mockito.when(networkModel.isProviderForNetworkOffering(Mockito.any(), Mockito.anyLong())).thenReturn(true);
Mockito.when(cmd.getGateway()).thenReturn(IP4_GATEWAY);
Mockito.when(cmd.getNetmask()).thenReturn(IP4_NETMASK);
}
Mockito.when(accountManager.isNormalUser(Mockito.anyLong())).thenReturn(true);
Mockito.when(physicalNetworkDao.findById(Mockito.anyLong())).thenReturn(Mockito.mock(PhysicalNetworkVO.class));
DataCenterVO zone = Mockito.mock(DataCenterVO.class);
Mockito.when(zone.getNetworkType()).thenReturn(DataCenter.NetworkType.Advanced);
Mockito.when(dataCenterDao.findById(Mockito.anyLong())).thenReturn(zone);
Mockito.when(networkOrchestrationService.finalizeServicesAndProvidersForNetwork(Mockito.any(), Mockito.anyLong())).thenReturn(new HashMap<>());
Mockito.when(networkOfferingServiceMapDao.areServicesSupportedByNetworkOffering(networkOfferingId, Network.Service.Dns)).thenReturn(dnsServiceSupported);
if(ipv6 && Network.GuestType.Isolated.equals(guestType)) {
Mockito.when(networkOfferingDao.isIpv6Supported(networkOfferingId)).thenReturn(true);
try {
Mockito.when(ipv6Service.preAllocateIpv6SubnetForNetwork(Mockito.anyLong())).thenReturn(new Pair<>(IP6_GATEWAY, IP6_CIDR));
} catch (ResourceAllocationException e) {
Assert.fail(String.format("failure with exception: %s", e.getMessage()));
}
}
Mockito.when(cmd.getSubdomainAccess()).thenReturn(null);
Mockito.when(cmd.getAssociatedNetworkId()).thenReturn(null);
if (isVpc) {
Mockito.when(cmd.getVpcId()).thenReturn(1L);
} else {
Mockito.when(cmd.getVpcId()).thenReturn(null);
}
}
@Test(expected = InvalidParameterValueException.class)
public void testCreateL2NetworkDnsFailure() {
registerCallContext();
CreateNetworkCmd cmd = Mockito.mock(CreateNetworkCmd.class);
prepareCreateNetworkDnsMocks(cmd, Network.GuestType.L2, false, false, true);
Mockito.when(cmd.getIp4Dns1()).thenReturn(ip4Dns[0]);
try {
service.createGuestNetwork(cmd);
} catch (InsufficientCapacityException | ResourceAllocationException e) {
Assert.fail(String.format("failure with exception: %s", e.getMessage()));
}
}
@Test(expected = InvalidParameterValueException.class)
public void testCreateNetworkDnsVpcFailure() {
registerCallContext();
CreateNetworkCmd cmd = Mockito.mock(CreateNetworkCmd.class);
prepareCreateNetworkDnsMocks(cmd, Network.GuestType.Isolated, false, true, true);
Mockito.when(cmd.getIp4Dns1()).thenReturn(ip4Dns[0]);
try {
service.createGuestNetwork(cmd);
} catch (InsufficientCapacityException | ResourceAllocationException e) {
Assert.fail(String.format("failure with exception: %s", e.getMessage()));
}
}
@Test(expected = InvalidParameterValueException.class)
public void testCreateNetworkDnsOfferingServiceFailure() {
registerCallContext();
CreateNetworkCmd cmd = Mockito.mock(CreateNetworkCmd.class);
prepareCreateNetworkDnsMocks(cmd, Network.GuestType.Isolated, false, false, false);
Mockito.when(cmd.getIp4Dns1()).thenReturn(ip4Dns[0]);
try {
service.createGuestNetwork(cmd);
} catch (InsufficientCapacityException | ResourceAllocationException e) {
Assert.fail(String.format("failure with exception: %s", e.getMessage()));
}
}
@Test(expected = InvalidParameterValueException.class)
public void testCreateIp4NetworkIp6DnsFailure() {
registerCallContext();
CreateNetworkCmd cmd = Mockito.mock(CreateNetworkCmd.class);
prepareCreateNetworkDnsMocks(cmd, Network.GuestType.Isolated, false, false, true);
Mockito.when(cmd.getIp6Dns1()).thenReturn(ip4Dns[0]);
try {
service.createGuestNetwork(cmd);
} catch (InsufficientCapacityException | ResourceAllocationException e) {
Assert.fail(String.format("failure with exception: %s", e.getMessage()));
}
}
@Test
public void testCheckAndUpdateNetworkNoUpdate() {
Assert.assertFalse(service.checkAndUpdateNetworkDns(Mockito.mock(NetworkVO.class), Mockito.mock(NetworkOffering.class), null, null, null, null));
NetworkVO network1 = Mockito.mock(NetworkVO.class);
Mockito.when(network1.getDns1()).thenReturn(ip4Dns[0]);
Long offeringId = 1L;
NetworkOffering offering = Mockito.mock(NetworkOffering.class);
Mockito.when(offering.getId()).thenReturn(offeringId);
Mockito.when(networkOfferingServiceMapDao.areServicesSupportedByNetworkOffering(offeringId, Network.Service.Dns)).thenReturn(true);
Assert.assertFalse(service.checkAndUpdateNetworkDns(network1, offering, null, null, null, null));
Assert.assertFalse(service.checkAndUpdateNetworkDns(network1, Mockito.mock(NetworkOffering.class), ip4Dns[0], null, null, null));
Mockito.when(network1.getIp6Dns1()).thenReturn(ip6Dns[0]);
Assert.assertFalse(service.checkAndUpdateNetworkDns(network1, Mockito.mock(NetworkOffering.class), ip4Dns[0], null, ip6Dns[0], null));
}
@Test
public void testCheckAndUpdateNetworkOfferingChangeReset() {
NetworkVO networkVO = new NetworkVO();
networkVO.setDns1(ip4Dns[0]);
Long offeringId = 1L;
NetworkOffering offering = Mockito.mock(NetworkOffering.class);
Mockito.when(offering.getId()).thenReturn(offeringId);
Mockito.when(networkOfferingServiceMapDao.areServicesSupportedByNetworkOffering(offeringId, Network.Service.Dns)).thenReturn(false);
Assert.assertTrue(service.checkAndUpdateNetworkDns(networkVO, offering, null, null, null, null));
Assert.assertNull(networkVO.getDns1());
Assert.assertNull(networkVO.getDns2());
Assert.assertNull(networkVO.getIp6Dns1());
Assert.assertNull(networkVO.getIp6Dns2());
}
@Test(expected = InvalidParameterValueException.class)
public void testCheckAndUpdateNetworkDnsL2NetworkFailure() {
NetworkVO networkVO = Mockito.mock(NetworkVO.class);
NetworkOffering offering = Mockito.mock(NetworkOffering.class);
Mockito.when(offering.getGuestType()).thenReturn(Network.GuestType.L2);
service.checkAndUpdateNetworkDns(networkVO, offering, ip4Dns[0], null, null, null);
}
@Test(expected = InvalidParameterValueException.class)
public void testCheckAndUpdateNetworkDnsVpcTierFailure() {
NetworkVO networkVO = Mockito.mock(NetworkVO.class);
Mockito.when(networkVO.getVpcId()).thenReturn(1L);
NetworkOffering offering = Mockito.mock(NetworkOffering.class);
Mockito.when(offering.getGuestType()).thenReturn(Network.GuestType.Shared);
service.checkAndUpdateNetworkDns(networkVO, offering, ip4Dns[0], null, null, null);
}
@Test(expected = InvalidParameterValueException.class)
public void testCheckAndUpdateNetworkDnsServiceFailure() {
NetworkVO networkVO = Mockito.mock(NetworkVO.class);
Mockito.when(networkVO.getVpcId()).thenReturn(null);
Long offeringId = 1L;
NetworkOffering offering = Mockito.mock(NetworkOffering.class);
Mockito.when(offering.getId()).thenReturn(offeringId);
Mockito.when(offering.getGuestType()).thenReturn(Network.GuestType.Shared);
Mockito.when(networkOfferingServiceMapDao.areServicesSupportedByNetworkOffering(offeringId, Network.Service.Dns)).thenReturn(false);
service.checkAndUpdateNetworkDns(networkVO, offering, ip4Dns[0], null, null, null);
}
@Test(expected = InvalidParameterValueException.class)
public void testCheckAndUpdateNetworkNotSharedIp6Failure() {
NetworkVO networkVO = Mockito.mock(NetworkVO.class);
Mockito.when(networkVO.getVpcId()).thenReturn(null);
Mockito.when(networkVO.getIp6Cidr()).thenReturn(null);
Mockito.when(networkVO.getGuestType()).thenReturn(Network.GuestType.Shared);
Long offeringId = 1L;
NetworkOffering offering = Mockito.mock(NetworkOffering.class);
Mockito.when(offering.getId()).thenReturn(offeringId);
Mockito.when(networkOfferingServiceMapDao.areServicesSupportedByNetworkOffering(offeringId, Network.Service.Dns)).thenReturn(true);
service.checkAndUpdateNetworkDns(networkVO, offering, null, null, ip6Dns[0], null);
}
@Test(expected = InvalidParameterValueException.class)
public void testCheckAndUpdateNetworkNotIsolatedIp6Failure() {
NetworkVO networkVO = Mockito.mock(NetworkVO.class);
Mockito.when(networkVO.getVpcId()).thenReturn(null);
Mockito.when(networkVO.getGuestType()).thenReturn(Network.GuestType.Isolated);
Long offeringId = 1L;
NetworkOffering offering = Mockito.mock(NetworkOffering.class);
Mockito.when(offering.getId()).thenReturn(offeringId);
Mockito.when(networkOfferingDao.isIpv6Supported(offeringId)).thenReturn(false);
Mockito.when(networkOfferingServiceMapDao.areServicesSupportedByNetworkOffering(offeringId, Network.Service.Dns)).thenReturn(true);
service.checkAndUpdateNetworkDns(networkVO, offering, null, null, ip6Dns[0], null);
}
@Test
public void testCheckAndUpdateNetworkSuccess() {
NetworkVO networkVO = new NetworkVO();
networkVO.setVpcId(null);
try {
Field id = networkVO.getClass().getDeclaredField("guestType");
id.setAccessible(true);
id.set(networkVO, Network.GuestType.Shared);
} catch (NoSuchFieldException | IllegalAccessException e) {
Assert.fail(String.format("Unable to set network guestType, %s", e.getMessage()));
}
networkVO.setIp6Cidr("cidr");
Long offeringId = 1L;
NetworkOffering offering = Mockito.mock(NetworkOffering.class);
Mockito.when(offering.getId()).thenReturn(offeringId);
Mockito.when(networkOfferingServiceMapDao.areServicesSupportedByNetworkOffering(offeringId, Network.Service.Dns)).thenReturn(true);
boolean updated = service.checkAndUpdateNetworkDns(networkVO, offering, ip4Dns[0], null, ip6Dns[0], null);
Assert.assertTrue(updated);
Assert.assertEquals(ip4Dns[0], networkVO.getDns1());
Assert.assertNull(networkVO.getDns2());
Assert.assertEquals(ip6Dns[0], networkVO.getIp6Dns1());
Assert.assertNull(networkVO.getIp6Dns2());
}
@Test
public void testCheckAndUpdateNetworkResetSuccess() {
NetworkVO networkVO = new NetworkVO();
networkVO.setVpcId(null);
networkVO.setDns1(ip4Dns[0]);
networkVO.setIp6Dns1(ip6Dns[0]);
try {
Field id = networkVO.getClass().getDeclaredField("guestType");
id.setAccessible(true);
id.set(networkVO, Network.GuestType.Shared);
} catch (NoSuchFieldException | IllegalAccessException e) {
Assert.fail(String.format("Unable to set network guestType, %s", e.getMessage()));
}
networkVO.setIp6Cidr("cidr");
Long offeringId = 1L;
NetworkOffering offering = Mockito.mock(NetworkOffering.class);
Mockito.when(offering.getId()).thenReturn(offeringId);
Mockito.when(networkOfferingServiceMapDao.areServicesSupportedByNetworkOffering(offeringId, Network.Service.Dns)).thenReturn(true);
boolean updated = service.checkAndUpdateNetworkDns(networkVO, offering, "", null, "", null);
Assert.assertTrue(updated);
Assert.assertNull(networkVO.getDns1());
Assert.assertNull(networkVO.getDns2());
Assert.assertNull(networkVO.getIp6Dns1());
Assert.assertNull(networkVO.getIp6Dns2());
}
}

View File

@ -16,31 +16,37 @@
// under the License.
package com.cloud.network.guru;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;
import java.util.Arrays;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import com.cloud.dc.DataCenter.NetworkType;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.deploy.DeploymentPlan;
import com.cloud.network.Network;
import com.cloud.network.NetworkModel;
import com.cloud.network.Networks.TrafficType;
import com.cloud.network.Network.GuestType;
import com.cloud.network.NetworkModel;
import com.cloud.network.NetworkProfile;
import com.cloud.network.Networks.TrafficType;
import com.cloud.network.PhysicalNetwork.IsolationMethod;
import com.cloud.network.dao.PhysicalNetworkDao;
import com.cloud.network.dao.PhysicalNetworkVO;
import com.cloud.offering.NetworkOffering;
import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
import com.cloud.user.Account;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.Arrays;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;
import com.cloud.utils.Pair;
import com.cloud.vm.NicProfile;
public class DirectNetworkGuruTest {
@ -76,6 +82,9 @@ public class DirectNetworkGuruTest {
@Mock
Account owner;
final String[] ip4Dns = {"5.5.5.5", "6.6.6.6"};
final String[] ip6Dns = {"2001:4860:4860::5555", "2001:4860:4860::6666"};
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
@ -128,4 +137,55 @@ public class DirectNetworkGuruTest {
assertNotNull(guru.design(offering, plan, network, owner));
}
@Test
public void testDesignDns() {
when(dcDao.findById(dc.getId())).thenReturn(dc);
when(plan.getDataCenterId()).thenReturn(1l);
when(plan.getPhysicalNetworkId()).thenReturn(1l);
when(physicalNetworkDao.findById(physicalNetwork.getId())).thenReturn(physicalNetwork);
when(offering.isRedundantRouter()).thenReturn(false);
when(network.getDns1()).thenReturn(ip4Dns[0]);
when(network.getDns2()).thenReturn(ip4Dns[1]);
when(network.getIp6Dns1()).thenReturn(ip6Dns[0]);
when(network.getIp6Dns2()).thenReturn(ip6Dns[1]);
when(networkModel.areServicesSupportedByNetworkOffering(offering.getId(), Network.Service.SecurityGroup)).thenReturn(false);
Network config = guru.design(offering, plan, network, owner);
assertNotNull(config);
assertEquals(ip4Dns[0], config.getDns1());
assertEquals(ip4Dns[1], config.getDns2());
assertEquals(ip6Dns[0], config.getIp6Dns1());
assertEquals(ip6Dns[1], config.getIp6Dns2());
}
@Test
public void testUpdateNicProfile() {
NicProfile nicProfile = new NicProfile();
when(dcDao.findById(Mockito.anyLong())).thenReturn(dc);
when(networkModel.getNetworkIp4Dns(network, dc)).thenReturn(new Pair<>(ip4Dns[0], ip4Dns[1]));
when(networkModel.getNetworkIp6Dns(network, dc)).thenReturn(new Pair<>(ip6Dns[0], ip6Dns[1]));
guru.updateNicProfile(nicProfile, network);
assertNotNull(nicProfile);
assertEquals(ip4Dns[0], nicProfile.getIPv4Dns1());
assertEquals(ip4Dns[1], nicProfile.getIPv4Dns2());
assertEquals(ip6Dns[0], nicProfile.getIPv6Dns1());
assertEquals(ip6Dns[1], nicProfile.getIPv6Dns2());
}
@Test
public void testUpdateNetworkProfile() {
NetworkProfile profile = new NetworkProfile(network);
when(dcDao.findById(Mockito.anyLong())).thenReturn(dc);
when(networkModel.getNetwork(Mockito.anyLong())).thenReturn(network);
when(networkModel.getNetworkIp4Dns(network, dc)).thenReturn(new Pair<>(ip4Dns[0], null));
when(networkModel.getNetworkIp6Dns(network, dc)).thenReturn(new Pair<>(ip6Dns[0], null));
guru.updateNetworkProfile(profile);
assertNotNull(profile);
assertEquals(ip4Dns[0], profile.getDns1());
assertNull(profile.getDns2());
assertEquals(ip6Dns[0], profile.getIp6Dns1());
assertNull(profile.getIp6Dns2());
}
}

View File

@ -0,0 +1,123 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with 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.
package com.cloud.network.guru;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.deploy.DeploymentPlan;
import com.cloud.network.Network;
import com.cloud.network.NetworkModel;
import com.cloud.network.NetworkProfile;
import com.cloud.network.Networks;
import com.cloud.network.dao.PhysicalNetworkDao;
import com.cloud.network.dao.PhysicalNetworkVO;
import com.cloud.offering.NetworkOffering;
import com.cloud.user.Account;
import com.cloud.utils.Pair;
import com.cloud.utils.component.ComponentContext;
import com.cloud.vm.NicProfile;
@RunWith(PowerMockRunner.class)
@PrepareForTest(ComponentContext.class)
public class ExternalGuestNetworkGuruTest {
@Mock
NetworkModel networkModel;
@Mock
DataCenterDao dataCenterDao;
@Mock
PhysicalNetworkDao physicalNetworkDao;
@InjectMocks
protected ExternalGuestNetworkGuru guru = new ExternalGuestNetworkGuru();
final String[] ip4Dns = {"5.5.5.5", "6.6.6.6"};
final String[] ip6Dns = {"2001:4860:4860::5555", "2001:4860:4860::6666"};
@Test
public void testDesignDns() {
Mockito.when(networkModel.areServicesSupportedByNetworkOffering(Mockito.anyLong(), Mockito.any())).thenReturn(false);
Mockito.when(networkModel.networkIsConfiguredForExternalNetworking(Mockito.anyLong(), Mockito.anyLong())).thenReturn(true);
NetworkOffering networkOffering = Mockito.mock(NetworkOffering.class);
Mockito.when(networkOffering.getTrafficType()).thenReturn(Networks.TrafficType.Guest);
Mockito.when(networkOffering.getGuestType()).thenReturn(Network.GuestType.Isolated);
DataCenterVO zone = Mockito.mock(DataCenterVO.class);
Mockito.when(zone.getNetworkType()).thenReturn(DataCenter.NetworkType.Advanced);
Mockito.when(dataCenterDao.findById(Mockito.anyLong())).thenReturn(zone);
PhysicalNetworkVO physicalNetwork = Mockito.mock(PhysicalNetworkVO.class);
Mockito.when(physicalNetwork.getId()).thenReturn(1L);
Mockito.when(physicalNetworkDao.findById(Mockito.anyLong())).thenReturn(physicalNetwork);
DeploymentPlan plan = Mockito.mock(DeploymentPlan.class);
Network network = Mockito.mock(Network.class);
Mockito.when(network.getDns1()).thenReturn(ip4Dns[0]);
Mockito.when(network.getDns2()).thenReturn(ip4Dns[1]);
Mockito.when(network.getIp6Dns1()).thenReturn(ip6Dns[0]);
Mockito.when(network.getIp6Dns2()).thenReturn(ip6Dns[1]);
Account owner = Mockito.mock(Account.class);
Network config = guru.design(networkOffering, plan, network, owner);
assertNotNull(config);
assertEquals(ip4Dns[0], config.getDns1());
assertEquals(ip4Dns[1], config.getDns2());
assertEquals(ip6Dns[0], config.getIp6Dns1());
assertEquals(ip6Dns[1], config.getIp6Dns2());
}
@Test
public void testUpdateNicProfile() {
NicProfile nicProfile = new NicProfile();
DataCenterVO zone = Mockito.mock(DataCenterVO.class);
Network network = Mockito.mock(Network.class);
Mockito.when(dataCenterDao.findById(Mockito.anyLong())).thenReturn(zone);
Mockito.when(networkModel.getNetworkIp4Dns(network, zone)).thenReturn(new Pair<>(ip4Dns[0], ip4Dns[1]));
Mockito.when(networkModel.getNetworkIp6Dns(network, zone)).thenReturn(new Pair<>(ip6Dns[0], ip6Dns[1]));
guru.updateNicProfile(nicProfile, network);
assertNotNull(nicProfile);
assertEquals(ip4Dns[0], nicProfile.getIPv4Dns1());
assertEquals(ip4Dns[1], nicProfile.getIPv4Dns2());
assertEquals(ip6Dns[0], nicProfile.getIPv6Dns1());
assertEquals(ip6Dns[1], nicProfile.getIPv6Dns2());
}
@Test
public void testUpdateNetworkProfile() {
DataCenterVO zone = Mockito.mock(DataCenterVO.class);
Network network = Mockito.mock(Network.class);
NetworkProfile profile = new NetworkProfile(network);
Mockito.when(dataCenterDao.findById(Mockito.anyLong())).thenReturn(zone);
Mockito.when(networkModel.getNetwork(Mockito.anyLong())).thenReturn(network);
Mockito.when(networkModel.getNetworkIp4Dns(network, zone)).thenReturn(new Pair<>(ip4Dns[0], null));
Mockito.when(networkModel.getNetworkIp6Dns(network, zone)).thenReturn(new Pair<>(ip6Dns[0], null));
guru.updateNetworkProfile(profile);
assertNotNull(profile);
assertEquals(ip4Dns[0], profile.getDns1());
assertNull(profile.getDns2());
assertEquals(ip6Dns[0], profile.getIp6Dns1());
assertNull(profile.getIp6Dns2());
}
}

View File

@ -29,8 +29,11 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import org.apache.cloudstack.api.command.admin.vpc.CreateVPCOfferingCmd;
import org.apache.cloudstack.context.CallContext;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
@ -38,28 +41,79 @@ import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.powermock.reflect.Whitebox;
import com.cloud.configuration.Resource;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceAllocationException;
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.NetworkModel;
import com.cloud.network.element.NetworkElement;
import com.cloud.network.vpc.dao.VpcOfferingDao;
import com.cloud.network.vpc.dao.VpcOfferingServiceMapDao;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.AccountVO;
import com.cloud.user.ResourceLimitService;
import com.cloud.user.User;
import com.cloud.user.UserVO;
import com.cloud.utils.net.NetUtils;
public class VpcManagerImplTest {
@Mock
VpcOfferingServiceMapDao vpcOffSvcMapDao;
AccountManager accountManager;
@Mock
ResourceLimitService resourceLimitService;
@Mock
VpcOfferingDao vpcOfferingDao;
@Mock
DataCenterDao dataCenterDao;
@Mock
VpcOfferingServiceMapDao vpcOfferingServiceMapDao;
VpcManagerImpl manager;
public static final long ACCOUNT_ID = 1;
private AccountVO account;
private UserVO user;
private static final String IP4_GATEWAY = "10.0.16.1";
private static final String IP4_NETMASK = "255.255.255.0";
private static final String IP6_GATEWAY = "fd17:ac56:1234:2000::1";
private static final String IP6_CIDR = "fd17:ac56:1234:2000::/64";
final String[] ip4Dns = {"5.5.5.5", "6.6.6.6"};
final String[] ip6Dns = {"2001:4860:4860::5555", "2001:4860:4860::6666"};
final String ip4Cidr = "172.16.0.0/22";
final Long zoneId = 1L;
final Long vpcOfferingId = 1L;
final Long vpcOwnerId = 1L;
final String vpcName = "Test-VPC";
final String vpcDomain = "domain";
private void registerCallContext() {
account = new AccountVO("testaccount", 1L, "networkdomain", Account.Type.NORMAL, "uuid");
account.setId(ACCOUNT_ID);
user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone",
UUID.randomUUID().toString(), User.Source.UNKNOWN);
CallContext.register(user, account);
}
@Before
public void setup()
{
MockitoAnnotations.initMocks(this);
manager = new VpcManagerImpl();
manager._vpcOffSvcMapDao = vpcOffSvcMapDao;
manager._accountMgr = accountManager;
manager._resourceLimitMgr = resourceLimitService;
manager._vpcOffDao = vpcOfferingDao;
manager._dcDao = dataCenterDao;
manager._vpcOffSvcMapDao = vpcOfferingServiceMapDao;
registerCallContext();
}
@Test
@ -171,4 +225,47 @@ public class VpcManagerImplTest {
Mockito.when(cmd.getInternetProtocol()).thenReturn(NetUtils.InternetProtocol.DualStack.toString());
manager.createVpcOffering(cmd);
}
private void mockVpcDnsResources(boolean supportDnsService, boolean isIpv6) {
Mockito.when(accountManager.getAccount(vpcOwnerId)).thenReturn(account);
VpcOfferingVO vpcOfferingVO = Mockito.mock(VpcOfferingVO.class);
Mockito.when(vpcOfferingVO.getId()).thenReturn(vpcOfferingId);
Mockito.when(vpcOfferingVO.getState()).thenReturn(VpcOffering.State.Enabled);
Mockito.when(vpcOfferingDao.findById(vpcOfferingId)).thenReturn(vpcOfferingVO);
DataCenterVO dataCenterVO = Mockito.mock(DataCenterVO.class);
Mockito.when(dataCenterVO.getId()).thenReturn(zoneId);
Mockito.when(dataCenterDao.findById(zoneId)).thenReturn(dataCenterVO);
Mockito.doNothing().when(accountManager).checkAccess(account, vpcOfferingVO, dataCenterVO);
Mockito.when(vpcOfferingServiceMapDao.areServicesSupportedByVpcOffering(vpcOfferingId, new Service[]{Service.Dns})).thenReturn(supportDnsService);
Mockito.when(vpcOfferingDao.isIpv6Supported(vpcOfferingId)).thenReturn(isIpv6);
try {
Mockito.doNothing().when(resourceLimitService).checkResourceLimit(account, Resource.ResourceType.vpc);
} catch (ResourceAllocationException e) {
Assert.fail(String.format("checkResourceLimit failure with exception: %s", e.getMessage()));
}
}
@Test(expected = InvalidParameterValueException.class)
public void testCreateVpcDnsOfferingServiceFailure() {
mockVpcDnsResources(false, false);
try {
Mockito.doNothing().when(resourceLimitService).checkResourceLimit(account, Resource.ResourceType.vpc);
manager.createVpc(zoneId, vpcOfferingId, vpcOwnerId, vpcName, vpcName, ip4Cidr, vpcDomain,
ip4Dns[0], null, null, null, true);
} catch (ResourceAllocationException e) {
Assert.fail(String.format("failure with exception: %s", e.getMessage()));
}
}
@Test(expected = InvalidParameterValueException.class)
public void testCreateVpcDnsIpv6OfferingFailure() {
mockVpcDnsResources(true, false);
try {
Mockito.doNothing().when(resourceLimitService).checkResourceLimit(account, Resource.ResourceType.vpc);
manager.createVpc(zoneId, vpcOfferingId, vpcOwnerId, vpcName, vpcName, ip4Cidr, vpcDomain,
ip4Dns[0], ip4Dns[1], ip6Dns[0], null, true);
} catch (ResourceAllocationException e) {
Assert.fail(String.format("failure with exception: %s", e.getMessage()));
}
}
}

View File

@ -663,8 +663,8 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkOrches
@Override
public Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, boolean bypassVlanOverlapCheck, String networkDomain,
Account owner, Long domainId, PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String gatewayv6,
String cidrv6, Boolean displayNetworkEnabled, String isolatedPvlan, Network.PVlanType isolatedPvlanType, String externalId, String routerIp, String routerIpv6) throws ConcurrentOperationException, InsufficientCapacityException,
ResourceAllocationException {
String cidrv6, Boolean displayNetworkEnabled, String isolatedPvlan, Network.PVlanType isolatedPvlanType, String externalId, String routerIp, String routerIpv6,
String ip4Dns1, String ip4Dns2, String ip6Dns1, String ip6Dns2) throws ConcurrentOperationException, ResourceAllocationException {
// TODO Auto-generated method stub
return null;
}

View File

@ -25,6 +25,7 @@ import java.util.Set;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import com.cloud.dc.DataCenter;
import com.cloud.dc.Vlan;
import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InvalidParameterValueException;
@ -52,6 +53,7 @@ import com.cloud.offering.NetworkOffering.Detail;
import com.cloud.offerings.NetworkOfferingVO;
import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
import com.cloud.user.Account;
import com.cloud.utils.Pair;
import com.cloud.utils.component.ManagerBase;
import com.cloud.vm.Nic;
import com.cloud.vm.NicProfile;
@ -933,4 +935,19 @@ public class MockNetworkModelImpl extends ManagerBase implements NetworkModel {
return null;
}
@Override
public Pair<String, String> getNetworkIp4Dns(Network network, DataCenter zone) {
return new Pair<>(null, null);
}
@Override
public Pair<String, String> getNetworkIp6Dns(Network network, DataCenter zone) {
return new Pair<>(null, null);
}
@Override
public void verifyIp4DnsPair(String ip4Dns1, String ip4Dns2) {}
@Override
public void verifyIp6DnsPair(String ip4Dns1, String ip4Dns2) {}
}

View File

@ -42,7 +42,7 @@ import junit.framework.TestCase;
public class VpcApiUnitTest extends TestCase {
@Inject
VpcManagerImpl _vpcService = null;
VpcVO _vo = new VpcVO(1, "new vpc", "new vpc", 1, 1, 1, "0.0.0.0/0", "vpc domain", false, false, false);
VpcVO _vo = new VpcVO(1, "new vpc", "new vpc", 1, 1, 1, "0.0.0.0/0", "vpc domain", false, false, false, null, null, null, null);
@Override
@Before

View File

@ -96,9 +96,9 @@ public class MockVpcDaoImpl extends GenericDaoBase<VpcVO, Long> implements VpcDa
public VpcVO findById(Long id) {
VpcVO vo = null;
if (id.longValue() == 1) {
vo = new VpcVO(1, "new vpc", "new vpc", 1, 1, 1, "0.0.0.0/0", "vpc domain", false, false, false);
vo = new VpcVO(1, "new vpc", "new vpc", 1, 1, 1, "0.0.0.0/0", "vpc domain", false, false, false, null, null, null, null);
} else if (id.longValue() == 2) {
vo = new VpcVO(1, "new vpc", "new vpc", 1, 1, 1, "0.0.0.0/0", "vpc domain", false, false, false);
vo = new VpcVO(1, "new vpc", "new vpc", 1, 1, 1, "0.0.0.0/0", "vpc domain", false, false, false, null, null, null, null);
vo.setState(State.Inactive);
}

View File

@ -41,7 +41,7 @@ public class MockVpcOfferingServiceMapDaoImpl extends GenericDaoBase<VpcOffering
* @see com.cloud.network.vpc.Dao.VpcOfferingServiceMapDao#areServicesSupportedByNetworkOffering(long, com.cloud.network.Network.Service[])
*/
@Override
public boolean areServicesSupportedByNetworkOffering(long networkOfferingId, Service[] services) {
public boolean areServicesSupportedByVpcOffering(long vpcOfferingId, Service[] services) {
// TODO Auto-generated method stub
return false;
}

View File

@ -59,6 +59,18 @@ EOF
echo "nameserver $NS2" >> /etc/dnsmasq-resolv.conf
echo "nameserver $NS2" >> /etc/resolv.conf
fi
if [ -n "$IP6_NS1" ]
then
echo "nameserver $IP6_NS1" >> /etc/dnsmasq-resolv.conf
echo "nameserver $IP6_NS1" >> /etc/resolv.conf
fi
if [ -n "$IP6_NS2" ]
then
echo "nameserver $IP6_NS2" >> /etc/dnsmasq-resolv.conf
echo "nameserver $IP6_NS2" >> /etc/resolv.conf
fi
if [ -n "$MGMTNET" -a -n "$LOCAL_GW" ]
then
if [ "$HYPERVISOR" == "vmware" ] || [ "$HYPERVISOR" == "hyperv" ];

View File

@ -0,0 +1,732 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with 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.
""" BVT test for custom DNS for Isolated network and VPC"""
#Import Local Modules
from marvin.codes import (PASS,
FAIL,
FAILED)
from marvin.cloudstackTestCase import cloudstackTestCase
from marvin.cloudstackAPI import (createGuestNetworkIpv6Prefix,
listGuestNetworkIpv6Prefixes,
deleteGuestNetworkIpv6Prefix)
from marvin.lib.utils import (get_process_status,
get_host_credentials)
from marvin.lib.base import (Configurations,
Domain,
NetworkOffering,
VpcOffering,
Account,
PublicIpRange,
Network,
VPC,
Router,
ServiceOffering,
VirtualMachine,
Host,
NetworkACLList,
NetworkACL)
from marvin.lib.common import (get_domain,
get_zone,
get_test_template)
from marvin.sshClient import SshClient
from marvin.cloudstackException import CloudstackAPIException
from marvin.lib.decoratorGenerators import skipTestIf
from nose.plugins.attrib import attr
from ipaddress import IPv6Network
from random import getrandbits
import time
import logging
IP6_OFFERING_CONFIG_NAME = "ipv6.offering.enabled"
IP4_DNS1 = "5.5.5.5"
IP4_DNS2 = "6.6.6.6"
IP6_DNS1 = "2001:4860:4860::5555"
IP6_DNS2 = "2001:4860:4860::6666"
VPC_DATA = {
"cidr": "10.1.0.0/22",
"tier1_gateway": "10.1.1.1",
"tier2_gateway": "10.1.2.1",
"tier_netmask": "255.255.255.0"
}
routerDetailsMap = {}
def getRouterProcessStatus(apiclient, hypervisor, config, router, cmd):
if router.id not in routerDetailsMap or routerDetailsMap[router.id] is None:
connect_ip = apiclient.connection.mgtSvr
connect_user = apiclient.connection.user
connect_passwd = apiclient.connection.passwd
if hypervisor.lower() not in ('vmware', 'hyperv'):
hosts = Host.list(
apiclient,
zoneid=router.zoneid,
type='Routing',
state='Up',
id=router.hostid
)
if not isinstance(hosts, list):
return [FAIL, "list host returns an invalid list"]
host = hosts[0]
connect_ip = host.ipaddress
hypervisor = None
try:
connect_user, connect_passwd= get_host_credentials(
config, host.ipaddress)
except KeyError:
return [FAIL, "Marvin configuration has no host credentials to check router services"]
details = {}
details['connect_ip'] = connect_ip
details['connect_user'] = connect_user
details['connect_passwd'] = connect_passwd
details['hypervisor'] = hypervisor
routerDetailsMap[router.id] = details
result = get_process_status(
routerDetailsMap[router.id]['connect_ip'],
22,
routerDetailsMap[router.id]['connect_user'],
routerDetailsMap[router.id]['connect_passwd'],
router.linklocalip,
cmd,
hypervisor=routerDetailsMap[router.id]['hypervisor']
)
if type(result) != list or len(result) == 0:
return [FAIL, "%s on router %s returned invalid result" % (cmd, router.id)]
result = '\n'.join(result)
return [PASS, result]
class TestNetworkCustomDns(cloudstackTestCase):
@classmethod
def setUpClass(cls):
testClient = super(TestNetworkCustomDns, cls).getClsTestClient()
cls.services = testClient.getParsedTestDataConfig()
cls.apiclient = testClient.getApiClient()
cls.dbclient = testClient.getDbConnection()
cls.test_ipv6_guestprefix = None
cls.initial_ipv6_offering_enabled = None
cls._cleanup = []
routerDetailsMap = {}
cls.logger = logging.getLogger('TestNetworkCustomDns')
cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests())
cls.services['mode'] = cls.zone.networktype
cls.ipv6NotSupported = False
ipv6_guestprefix = cls.getGuestIpv6Prefix()
if ipv6_guestprefix == None:
cls.ipv6NotSupported = True
if cls.ipv6NotSupported == False:
ipv6_publiciprange = cls.getPublicIpv6Range()
if ipv6_publiciprange == None:
cls.ipv6NotSupported = True
if cls.ipv6NotSupported == False:
cls.initial_ipv6_offering_enabled = Configurations.list(
cls.apiclient,
name=IP6_OFFERING_CONFIG_NAME)[0].value
Configurations.update(cls.apiclient,
IP6_OFFERING_CONFIG_NAME,
"true")
else:
cls.debug("IPv6 is not supported, skipping testing IPv6 details!")
cls.domain = get_domain(cls.apiclient)
cls.account = Account.create(
cls.apiclient,
cls.services["account"],
admin=True,
domainid=cls.domain.id
)
cls._cleanup.append(cls.account)
cls.hypervisor = testClient.getHypervisorInfo()
cls.template = get_test_template(
cls.apiclient,
cls.zone.id,
cls.hypervisor)
return
@classmethod
def tearDownClass(cls):
if cls.initial_ipv6_offering_enabled != None:
Configurations.update(cls.apiclient,
IP6_OFFERING_CONFIG_NAME,
cls.initial_ipv6_offering_enabled)
super(TestNetworkCustomDns, cls).tearDownClass()
if cls.test_ipv6_guestprefix != None:
cmd = deleteGuestNetworkIpv6Prefix.deleteGuestNetworkIpv6PrefixCmd()
cmd.id = cls.test_ipv6_guestprefix.id
cls.apiclient.deleteGuestNetworkIpv6Prefix(cmd)
@classmethod
def getGuestIpv6Prefix(cls):
cmd = listGuestNetworkIpv6Prefixes.listGuestNetworkIpv6PrefixesCmd()
cmd.zoneid = cls.zone.id
ipv6_prefixes_response = cls.apiclient.listGuestNetworkIpv6Prefixes(cmd)
if isinstance(ipv6_prefixes_response, list) == True and len(ipv6_prefixes_response) > 0:
return ipv6_prefixes_response[0]
ipv6_guestprefix_service = cls.services["guestip6prefix"]
cmd = createGuestNetworkIpv6Prefix.createGuestNetworkIpv6PrefixCmd()
cmd.zoneid = cls.zone.id
cmd.prefix = ipv6_guestprefix_service["prefix"]
ipv6_guestprefix = cls.apiclient.createGuestNetworkIpv6Prefix(cmd)
cls.test_ipv6_guestprefix = ipv6_guestprefix
return ipv6_guestprefix
@classmethod
def getPublicIpv6Range(cls):
list_public_ip_range_response = PublicIpRange.list(
cls.apiclient,
zoneid=cls.zone.id
)
ipv4_range_vlan = None
if isinstance(list_public_ip_range_response, list) == True and len(list_public_ip_range_response) > 0:
for ip_range in list_public_ip_range_response:
if ip_range.ip6cidr != None and ip_range.ip6gateway != None:
return ip_range
if ip_range.netmask != None and ip_range.gateway != None:
vlan = ip_range.vlan
if ipv4_range_vlan == None and vlan.startswith("vlan://"):
vlan = vlan.replace("vlan://", "")
if vlan == "untagged":
ipv4_range_vlan = None
else:
ipv4_range_vlan = int(vlan)
ipv6_publiciprange_service = cls.services["publicip6range"]
ipv6_publiciprange_service["zoneid"] = cls.zone.id
ipv6_publiciprange_service["vlan"] = ipv4_range_vlan
ipv6_publiciprange = PublicIpRange.create(
cls.apiclient,
ipv6_publiciprange_service
)
cls._cleanup.append(ipv6_publiciprange)
return ipv6_publiciprange
def setUp(self):
self.services = self.testClient.getParsedTestDataConfig()
self.apiclient = self.testClient.getApiClient()
self.dbclient = self.testClient.getDbConnection()
self.cleanup = []
return
def tearDown(self):
super(TestNetworkCustomDns, self).tearDown()
def createTinyServiceOffering(self):
self.service_offering = ServiceOffering.create(
self.apiclient,
self.services["service_offerings"]["big"],
)
self.cleanup.append(self.service_offering)
def createNetworkOffering(self):
off_service = self.services["network_offering"]
if not self.ipv6NotSupported:
off_service["internetprotocol"] = "dualstack"
self.network_offering = NetworkOffering.create(
self.apiclient,
off_service
)
self.cleanup.append(self.network_offering)
self.network_offering.update(self.apiclient, state='Enabled')
def deployNetwork(self):
network_service = self.services["network"]
network_service["networkoffering"] = self.network_offering.id
network_service["dns1"] = IP4_DNS1
network_service["dns2"] = IP4_DNS2
if not self.ipv6NotSupported:
network_service["ip6dns1"] = IP6_DNS1
network_service["ip6dns2"] = IP6_DNS2
self.network = Network.create(
self.apiclient,
self.services["network"],
self.account.name,
self.account.domainid,
zoneid=self.zone.id
)
self.cleanup.append(self.network)
def deployNetworkVm(self):
if self.template == FAILED:
assert False, "get_test_template() failed to return template"
self.services["virtual_machine"]["zoneid"] = self.zone.id
self.virtual_machine = VirtualMachine.create(
self.apiclient,
self.services["virtual_machine"],
templateid=self.template.id,
accountid=self.account.name,
domainid=self.account.domainid,
networkids=self.network.id,
serviceofferingid=self.service_offering.id
)
self.cleanup.append(self.virtual_machine)
def getNetworkRouter(self, network, red_state="PRIMARY"):
routers = Router.list(
self.apiclient,
networkid=network.id,
listall=True
)
self.assertTrue(
isinstance(routers, list) and len(routers) > 0,
"No routers found for network %s" % network.id
)
if len(routers) == 1:
return routers[0]
for router in routers:
if router.redundantstate == red_state:
return router
def checkNetwork(self):
self.debug("Listing network: %s" % (self.network.name))
network = Network.list(self.apiclient,listall="true",id=self.network.id)
self.assertTrue(
isinstance(network, list),
"Check listNetworks response returns a valid list"
)
self.assertEqual(
len(network),
1,
"Network not found"
)
network = network[0]
self.assertNotEqual(network,
None,
"User is not able to retrieve network details %s" % self.network.id)
self.assertEqual(network.dns1,
IP4_DNS1,
"IPv4 DNS1 is not same, expected=%s, actual=%s" % (IP4_DNS1, network.dns1))
self.assertEqual(network.dns2,
IP4_DNS2,
"IPv4 DNS2 is not same, expected=%s, actual=%s" % (IP4_DNS2, network.dns2))
if not self.ipv6NotSupported:
self.assertEqual(network.ip6dns1,
IP6_DNS1,
"IPv6 DNS1 is not same, expected=%s, actual=%s" % (IP6_DNS1, network.ip6dns1))
self.assertEqual(network.ip6dns2,
IP6_DNS2,
"IPv6 DNS2 is not same, expected=%s, actual=%s" % (IP6_DNS2, network.ip6dns2))
def checkNetworkRouter(self):
router = self.getNetworkRouter(self.network)
dns_cmd = "cat /etc/resolv.conf"
res = getRouterProcessStatus(self.apiclient, self.hypervisor, self.config, router, dns_cmd)
if res[0] == FAIL:
self.fail("Failed to get router command result. %s" % res[1])
res = res[1]
ns = "nameserver %s" % IP4_DNS1
self.assertTrue(ns in res,
"Network router doesn't contain nameserver for DNS1: %s" % IP4_DNS1)
ns = "nameserver %s" % IP4_DNS2
self.assertTrue(ns in res,
"Network router doesn't contain nameserver for DNS2: %s" % IP4_DNS2)
if not self.ipv6NotSupported:
ns = "nameserver %s" % IP6_DNS1
self.assertTrue(ns in res,
"Network router doesn't contain nameserver for IPv6 DNS1: %s" % IP6_DNS1)
ns = "nameserver %s" % IP6_DNS2
self.assertTrue(ns in res,
"Network router doesn't contain nameserver for IPv6 DNS2: %s" % IP6_DNS2)
@attr(
tags=[
"advanced",
"basic",
"eip",
"sg",
"advancedns",
"smoke"],
required_hardware="false")
def test_01_verify_network_dns(self):
"""Test to verify custom DNS for network
# Validate the following:
# 1. Create network, deploy VM
# 2. Verify network has required DNS details
# 3. SSH into VR for the network and verify it has required DNS details as nameserver
"""
self.createNetworkOffering()
self.createTinyServiceOffering()
self.deployNetwork()
self.deployNetworkVm()
self.checkNetwork()
self.checkNetworkRouter()
class TestVpcCustomDns(cloudstackTestCase):
@classmethod
def setUpClass(cls):
testClient = super(TestVpcCustomDns, cls).getClsTestClient()
cls.services = testClient.getParsedTestDataConfig()
cls.apiclient = testClient.getApiClient()
cls.dbclient = testClient.getDbConnection()
cls.test_ipv6_guestprefix = None
cls.initial_ipv6_offering_enabled = None
cls._cleanup = []
routerDetailsMap = {}
cls.vpcAllowAllAclDetailsMap = {}
cls.logger = logging.getLogger('TestVpcCustomDns')
cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests())
cls.services['mode'] = cls.zone.networktype
cls.ipv6NotSupported = False
ipv6_guestprefix = cls.getGuestIpv6Prefix()
if ipv6_guestprefix == None:
cls.ipv6NotSupported = True
if cls.ipv6NotSupported == False:
ipv6_publiciprange = cls.getPublicIpv6Range()
if ipv6_publiciprange == None:
cls.ipv6NotSupported = True
if cls.ipv6NotSupported == False:
cls.initial_ipv6_offering_enabled = Configurations.list(
cls.apiclient,
name=IP6_OFFERING_CONFIG_NAME)[0].value
Configurations.update(cls.apiclient,
IP6_OFFERING_CONFIG_NAME,
"true")
else:
cls.debug("IPv6 is not supported, skipping testing IPv6 details!")
cls.domain = get_domain(cls.apiclient)
cls.account = Account.create(
cls.apiclient,
cls.services["account"],
admin=True,
domainid=cls.domain.id
)
cls._cleanup.append(cls.account)
cls.hypervisor = testClient.getHypervisorInfo()
cls.template = get_test_template(
cls.apiclient,
cls.zone.id,
cls.hypervisor)
return
@classmethod
def tearDownClass(cls):
if cls.initial_ipv6_offering_enabled != None:
Configurations.update(cls.apiclient,
IP6_OFFERING_CONFIG_NAME,
cls.initial_ipv6_offering_enabled)
super(TestVpcCustomDns, cls).tearDownClass()
if cls.test_ipv6_guestprefix != None:
cmd = deleteGuestNetworkIpv6Prefix.deleteGuestNetworkIpv6PrefixCmd()
cmd.id = cls.test_ipv6_guestprefix.id
cls.apiclient.deleteGuestNetworkIpv6Prefix(cmd)
@classmethod
def getGuestIpv6Prefix(cls):
cmd = listGuestNetworkIpv6Prefixes.listGuestNetworkIpv6PrefixesCmd()
cmd.zoneid = cls.zone.id
ipv6_prefixes_response = cls.apiclient.listGuestNetworkIpv6Prefixes(cmd)
if isinstance(ipv6_prefixes_response, list) == True and len(ipv6_prefixes_response) > 0:
return ipv6_prefixes_response[0]
ipv6_guestprefix_service = cls.services["guestip6prefix"]
cmd = createGuestNetworkIpv6Prefix.createGuestNetworkIpv6PrefixCmd()
cmd.zoneid = cls.zone.id
cmd.prefix = ipv6_guestprefix_service["prefix"]
ipv6_guestprefix = cls.apiclient.createGuestNetworkIpv6Prefix(cmd)
cls.test_ipv6_guestprefix = ipv6_guestprefix
return ipv6_guestprefix
@classmethod
def getPublicIpv6Range(cls):
list_public_ip_range_response = PublicIpRange.list(
cls.apiclient,
zoneid=cls.zone.id
)
ipv4_range_vlan = None
if isinstance(list_public_ip_range_response, list) == True and len(list_public_ip_range_response) > 0:
for ip_range in list_public_ip_range_response:
if ip_range.ip6cidr != None and ip_range.ip6gateway != None:
return ip_range
if ip_range.netmask != None and ip_range.gateway != None:
vlan = ip_range.vlan
if ipv4_range_vlan == None and vlan.startswith("vlan://"):
vlan = vlan.replace("vlan://", "")
if vlan == "untagged":
ipv4_range_vlan = None
else:
ipv4_range_vlan = int(vlan)
ipv6_publiciprange_service = cls.services["publicip6range"]
ipv6_publiciprange_service["zoneid"] = cls.zone.id
ipv6_publiciprange_service["vlan"] = ipv4_range_vlan
ipv6_publiciprange = PublicIpRange.create(
cls.apiclient,
ipv6_publiciprange_service
)
cls._cleanup.append(ipv6_publiciprange)
return ipv6_publiciprange
def setUp(self):
self.services = self.testClient.getParsedTestDataConfig()
self.apiclient = self.testClient.getApiClient()
self.dbclient = self.testClient.getDbConnection()
self.cleanup = []
return
def tearDown(self):
super(TestVpcCustomDns, self).tearDown()
def createTinyServiceOffering(self):
self.service_offering = ServiceOffering.create(
self.apiclient,
self.services["service_offerings"]["big"],
)
self.cleanup.append(self.service_offering)
def createVpcOfferingInternal(self, is_redundant, is_ipv6):
off_service = self.services["vpc_offering"]
if is_redundant:
off_service["serviceCapabilityList"] = {
"SourceNat": {
"RedundantRouter": 'true'
},
}
if is_ipv6:
off_service["internetprotocol"] = "dualstack"
vpc_offering = VpcOffering.create(
self.apiclient,
off_service
)
self.cleanup.append(vpc_offering)
vpc_offering.update(self.apiclient, state='Enabled')
return vpc_offering
def createVpcOffering(self, is_redundant=False):
self.vpc_offering = self.createVpcOfferingInternal(is_redundant, self.ipv6NotSupported == False)
def deployAllowAllVpcInternal(self, cidr):
service = self.services["vpc"]
service["cidr"] = cidr
ip6Dns1 = None
ip6Dns2 = None
if not self.ipv6NotSupported:
ip6Dns1 = IP6_DNS1
ip6Dns2 = IP6_DNS2
vpc = VPC.create(
self.apiclient,
self.services["vpc"],
vpcofferingid=self.vpc_offering.id,
zoneid=self.zone.id,
account=self.account.name,
domainid=self.account.domainid,
dns1=IP4_DNS1,
dns2=IP4_DNS2,
ip6dns1=ip6Dns1,
ip6dns2=ip6Dns2
)
self.cleanup.append(vpc)
acl = NetworkACLList.create(
self.apiclient,
services={},
name="allowall",
description="allowall",
vpcid=vpc.id
)
rule ={
"protocol": "all",
"traffictype": "ingress",
}
NetworkACL.create(self.apiclient,
services=rule,
aclid=acl.id
)
rule["traffictype"] = "egress"
NetworkACL.create(self.apiclient,
services=rule,
aclid=acl.id
)
self.vpcAllowAllAclDetailsMap[vpc.id] = acl.id
return vpc
def deployVpc(self):
self.vpc = self.deployAllowAllVpcInternal(VPC_DATA["cidr"])
def createNetworkTierOfferingInternal(self, is_ipv6, remove_lb=True):
off_service = self.services["nw_offering_isolated_vpc"]
if not remove_lb: # Remove Lb service
if "serviceProviderList" in off_service and "Lb" in off_service["serviceProviderList"].keys():
providers = off_service["serviceProviderList"]
providers.pop("Lb")
off_service["serviceProviderList"] = providers
if "supportedservices" in off_service and "Lb" in off_service["supportedservices"]:
supportedServices = off_service["supportedservices"].split(",")
supportedServices.remove("Lb")
off_service["supportedservices"] = ",".join(supportedServices)
if is_ipv6:
off_service["internetprotocol"] = "dualstack"
network_offering = NetworkOffering.create(
self.apiclient,
off_service,
conservemode=False
)
self.cleanup.append(network_offering)
network_offering.update(self.apiclient, state='Enabled')
return network_offering
def createNetworkTierOffering(self):
self.network_offering = self.createNetworkTierOfferingInternal(self.ipv6NotSupported == False)
def deployNetworkTierInternal(self, network_offering_id, vpc_id, tier_gateway, tier_netmask, acl_id=None, tier_name=None):
if not acl_id and vpc_id in self.vpcAllowAllAclDetailsMap:
acl_id = self.vpcAllowAllAclDetailsMap[vpc_id]
service = self.services["ntwk"]
if tier_name:
service["name"] = tier_name
service["displaytext"] = "vpc-%s" % tier_name
network = Network.create(
self.apiclient,
service,
self.account.name,
self.account.domainid,
networkofferingid=network_offering_id,
vpcid=vpc_id,
zoneid=self.zone.id,
gateway=tier_gateway,
netmask=tier_netmask,
aclid=acl_id
)
self.cleanup.append(network)
return network
def deployNetworkTier(self):
self.network = self.deployNetworkTierInternal(
self.network_offering.id,
self.vpc.id,
VPC_DATA["tier1_gateway"],
VPC_DATA["tier_netmask"]
)
def deployNetworkTierVmInternal(self, network):
if self.template == FAILED:
assert False, "get_test_template() failed to return template"
self.services["virtual_machine"]["zoneid"] = self.zone.id
virtual_machine = VirtualMachine.create(
self.apiclient,
self.services["virtual_machine"],
templateid=self.template.id,
accountid=self.account.name,
domainid=self.account.domainid,
networkids=network,
serviceofferingid=self.service_offering.id
)
self.cleanup.append(virtual_machine)
return virtual_machine
def deployNetworkTierVm(self):
self.virtual_machine = self.deployNetworkTierVmInternal(self.network.id)
def checkVpcBasic(self):
self.debug("Listing VPC: %s" % (self.vpc.name))
vpc = VPC.list(self.apiclient,listall="true",id=self.vpc.id)
self.assertTrue(
isinstance(vpc, list),
"Check listVpcs response returns a valid list"
)
self.assertEqual(
len(vpc),
1,
"Network not found"
)
vpc = vpc[0]
self.assertEqual(vpc.dns1,
IP4_DNS1,
"IPv4 DNS1 is not same, expected=%s, actual=%s" % (IP4_DNS1, vpc.dns1))
self.assertEqual(vpc.dns2,
IP4_DNS2,
"IPv4 DNS2 is not same, expected=%s, actual=%s" % (IP4_DNS2, vpc.dns2))
if not self.ipv6NotSupported:
self.assertEqual(vpc.ip6dns1,
IP6_DNS1,
"IPv6 DNS1 is not same, expected=%s, actual=%s" % (IP6_DNS1, vpc.ip6dns1))
self.assertEqual(vpc.ip6dns2,
IP6_DNS2,
"IPv6 DNS2 is not same, expected=%s, actual=%s" % (IP6_DNS2, vpc.ip6dns2))
def getVpcRouter(self, vpc, red_state="PRIMARY"):
routers = Router.list(
self.apiclient,
vpcid=vpc.id,
listall=True
)
self.assertTrue(
isinstance(routers, list) and len(routers) > 0,
"No routers found for VPC %s" % vpc.id
)
if len(routers) == 1:
return routers[0]
for router in routers:
if router.redundantstate == red_state:
return router
def checkVpcRouter(self):
router = self.getVpcRouter(self.vpc)
dns_cmd = "cat /etc/resolv.conf"
res = getRouterProcessStatus(self.apiclient, self.hypervisor, self.config, router, dns_cmd)
if res[0] == FAIL:
self.fail("Failed to get router command result. %s" % res[1])
res = res[1]
ns = "nameserver %s" % IP4_DNS1
self.assertTrue(ns in res,
"Network router doesn't contain nameserver for DNS1: %s" % IP4_DNS1)
ns = "nameserver %s" % IP4_DNS2
self.assertTrue(ns in res,
"Network router doesn't contain nameserver for DNS2: %s" % IP4_DNS2)
if not self.ipv6NotSupported:
ns = "nameserver %s" % IP6_DNS1
self.assertTrue(ns in res,
"Network router doesn't contain nameserver for IPv6 DNS1: %s" % IP6_DNS1)
ns = "nameserver %s" % IP6_DNS2
self.assertTrue(ns in res,
"Network router doesn't contain nameserver for IPv6 DNS2: %s" % IP6_DNS2)
@attr(
tags=[
"advanced",
"basic",
"eip",
"sg",
"advancedns",
"smoke"],
required_hardware="false")
def test_01_verify_vpc_dns(self):
"""Test to verify custom DNS for VPC
# Validate the following:
# 1. Create VPC, deploy network tier and VM in it
# 2. Verify VPC details
# 3. Verify VPC router details
"""
self.createVpcOffering()
self.createNetworkTierOffering()
self.createTinyServiceOffering()
self.deployVpc()
self.deployNetworkTier()
self.deployNetworkTierVm()
self.checkVpcBasic()
self.checkVpcRouter()

View File

@ -3240,6 +3240,14 @@ class Network:
cmd.endipv6 = services["endipv6"]
if "routeripv6" in services:
cmd.routeripv6 = services["routeripv6"]
if "dns1" in services:
cmd.dns1 = services["dns1"]
if "dns2" in services:
cmd.dns2 = services["dns2"]
if "ip6dns1" in services:
cmd.ip6dns1 = services["ip6dns1"]
if "ip6dns2" in services:
cmd.ip6dns2 = services["ip6dns2"]
if accountid:
cmd.account = accountid

View File

@ -39,7 +39,7 @@ export default {
return fields
},
details: () => {
var fields = ['name', 'id', 'description', 'type', 'traffictype', 'vpcid', 'vlan', 'broadcasturi', 'cidr', 'ip6cidr', 'netmask', 'gateway', 'aclname', 'ispersistent', 'restartrequired', 'reservediprange', 'redundantrouter', 'networkdomain', 'egressdefaultpolicy', 'zonename', 'account', 'domain', 'associatednetwork', 'associatednetworkid', 'ip6firewall', 'ip6routing', 'ip6routes']
var fields = ['name', 'id', 'description', 'type', 'traffictype', 'vpcid', 'vlan', 'broadcasturi', 'cidr', 'ip6cidr', 'netmask', 'gateway', 'aclname', 'ispersistent', 'restartrequired', 'reservediprange', 'redundantrouter', 'networkdomain', 'egressdefaultpolicy', 'zonename', 'account', 'domain', 'associatednetwork', 'associatednetworkid', 'ip6firewall', 'ip6routing', 'ip6routes', 'dns1', 'dns2', 'ip6dns1', 'ip6dns2']
if (!isAdmin()) {
fields = fields.filter(function (e) { return e !== 'broadcasturi' })
}
@ -166,7 +166,7 @@ export default {
permission: ['listVPCs'],
resourceType: 'Vpc',
columns: ['name', 'state', 'displaytext', 'cidr', 'account', 'zonename'],
details: ['name', 'id', 'displaytext', 'cidr', 'networkdomain', 'ip6routes', 'ispersistent', 'redundantvpcrouter', 'restartrequired', 'zonename', 'account', 'domain'],
details: ['name', 'id', 'displaytext', 'cidr', 'networkdomain', 'ip6routes', 'ispersistent', 'redundantvpcrouter', 'restartrequired', 'zonename', 'account', 'domain', 'dns1', 'dns2', 'ip6dns1', 'ip6dns2'],
searchFilters: ['name', 'zoneid', 'domainid', 'account', 'tags'],
related: [{
name: 'vm',

View File

@ -105,14 +105,14 @@
</a-select>
</a-form-item>
<a-form-item
ref="vlanid"
name="vlanid"
ref="vlan"
name="vlan"
v-if="!isObjectEmpty(selectedNetworkOffering) && selectedNetworkOffering.specifyvlan">
<template #label>
<tooltip-label :title="$t('label.vlan')" :tooltip="apiParams.vlan.description"/>
</template>
<a-input
v-model:value="form.vlanid"
v-model:value="form.vlan"
:placeholder="apiParams.vlan.description"/>
</a-form-item>
<a-form-item
@ -167,22 +167,68 @@
v-model:value="form.netmask"
:placeholder="apiParams.netmask.description"/>
</a-form-item>
<a-form-item v-if="selectedNetworkOffering && selectedNetworkOffering.specifyipranges" name="startipv4" ref="startipv4">
<a-form-item v-if="selectedNetworkOffering && selectedNetworkOffering.specifyipranges" name="startip" ref="startip">
<template #label>
<tooltip-label :title="$t('label.startipv4')" :tooltip="apiParams.startip.description"/>
</template>
<a-input
v-model:value="form.startipv4"
v-model:value="form.startip"
:placeholder="apiParams.startip.description"/>
</a-form-item>
<a-form-item v-if="selectedNetworkOffering && selectedNetworkOffering.specifyipranges" name="endipv4" ref="endipv4">
<a-form-item v-if="selectedNetworkOffering && selectedNetworkOffering.specifyipranges" name="endip" ref="endip">
<template #label>
<tooltip-label :title="$t('label.endipv4')" :tooltip="apiParams.endip.description"/>
<tooltip-label :title="$t('label.endip')" :tooltip="apiParams.endip.description"/>
</template>
<a-input
v-model:value="form.endipv4"
v-model:value="form.endip"
:placeholder="apiParams.endip.description"/>
</a-form-item>
<div v-if="selectedNetworkOfferingSupportsDns">
<a-row :gutter="12">
<a-col :md="12" :lg="12">
<a-form-item v-if="'dns1' in apiParams" name="dns1" ref="dns1">
<template #label>
<tooltip-label :title="$t('label.dns1')" :tooltip="apiParams.dns1.description"/>
</template>
<a-input
v-model:value="form.dns1"
:placeholder="apiParams.dns1.description"/>
</a-form-item>
</a-col>
<a-col :md="12" :lg="12">
<a-form-item v-if="'dns2' in apiParams" name="dns2" ref="dns2">
<template #label>
<tooltip-label :title="$t('label.dns2')" :tooltip="apiParams.dns2.description"/>
</template>
<a-input
v-model:value="form.dns2"
:placeholder="apiParams.dns2.description"/>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="12">
<a-col :md="12" :lg="12">
<a-form-item v-if="selectedNetworkOffering && selectedNetworkOffering.internetprotocol === 'DualStack' && 'ip6dns1' in apiParams" name="ip6dns1" ref="ip6dns1">
<template #label>
<tooltip-label :title="$t('label.ip6dns1')" :tooltip="apiParams.ip6dns1.description"/>
</template>
<a-input
v-model:value="form.ip6dns1"
:placeholder="apiParams.ip6dns1.description"/>
</a-form-item>
</a-col>
<a-col :md="12" :lg="12">
<a-form-item v-if="selectedNetworkOffering && selectedNetworkOffering.internetprotocol === 'DualStack' && 'ip6dns2' in apiParams" name="ip6dns2" ref="ip6dns2">
<template #label>
<tooltip-label :title="$t('label.ip6dns2')" :tooltip="apiParams.ip6dns2.description"/>
</template>
<a-input
v-model:value="form.ip6dns2"
:placeholder="apiParams.ip6dns2.description"/>
</a-form-item>
</a-col>
</a-row>
</div>
<a-form-item
ref="networkdomain"
name="networkdomain"
@ -294,6 +340,16 @@ export default {
this.initForm()
this.fetchData()
},
computed: {
selectedNetworkOfferingSupportsDns () {
if (this.selectedNetworkOffering) {
const services = this.selectedNetworkOffering?.service || []
const dnsServices = services.filter(service => service.name === 'Dns')
return dnsServices && dnsServices.length === 1
}
return false
}
},
methods: {
initForm () {
this.formRef = ref()
@ -457,29 +513,11 @@ export default {
displayText: values.displaytext,
networkOfferingId: this.selectedNetworkOffering.id
}
if (this.isValidTextValueForKey(values, 'gateway')) {
params.gateway = values.gateway
}
if (this.isValidTextValueForKey(values, 'netmask')) {
params.netmask = values.netmask
}
if (this.isValidTextValueForKey(values, 'startipv4')) {
params.startip = values.startipv4
}
if (this.isValidTextValueForKey(values, 'endipv4')) {
params.endip = values.endipv4
}
if (this.isValidTextValueForKey(values, 'externalid')) {
params.externalid = values.externalid
}
if (this.isValidTextValueForKey(values, 'vpcid')) {
params.vpcid = this.selectedVpc.id
}
if (this.isValidTextValueForKey(values, 'vlanid')) {
params.vlan = values.vlanid
}
if (this.isValidTextValueForKey(values, 'networkdomain')) {
params.networkdomain = values.networkdomain
var usefulFields = ['gateway', 'netmask', 'startip', 'endip', 'dns1', 'dns2', 'ip6dns1', 'ip6dns2', 'externalid', 'vpcid', 'vlan', 'networkdomain']
for (var field of usefulFields) {
if (this.isValidTextValueForKey(values, field)) {
params[field] = values[field]
}
}
if ('domainid' in values && values.domainid > 0) {
params.domainid = this.selectedDomain.id

View File

@ -85,12 +85,12 @@
</a-select-option>
</a-select>
</a-form-item>
<a-form-item v-if="!this.isObjectEmpty(this.selectedNetworkOffering) && this.selectedNetworkOffering.specifyvlan && isAdmin()" name="vlanid" ref="vlanid">
<a-form-item v-if="!this.isObjectEmpty(this.selectedNetworkOffering) && this.selectedNetworkOffering.specifyvlan && isAdmin()" name="vlan" ref="vlan">
<template #label>
<tooltip-label :title="$t('label.vlan')" :tooltip="apiParams.vlan.description"/>
</template>
<a-input
v-model:value="form.vlanid"
v-model:value="form.vlan"
:placeholder="apiParams.vlan.description"/>
</a-form-item>
<a-form-item name="bypassvlanoverlapcheck" ref="bypassvlanoverlapcheck" v-if="isAdmin()">
@ -265,86 +265,158 @@
</a-select-option>
</a-select>
</a-form-item>
<a-form-item name="ip4gateway" ref="ip4gateway">
<template #label>
<tooltip-label :title="$t('label.ip4gateway')" :tooltip="apiParams.gateway.description"/>
</template>
<a-input
v-model:value="form.ip4gateway"
:placeholder="apiParams.gateway.description"/>
</a-form-item>
<a-form-item name="ip4netmask" ref="ip4netmask">
<template #label>
<tooltip-label :title="$t('label.ip4netmask')" :tooltip="apiParams.netmask.description"/>
</template>
<a-input
v-model:value="form.ip4netmask"
:placeholder="apiParams.netmask.description"/>
</a-form-item>
<a-form-item name="startipv4" ref="startipv4">
<template #label>
<tooltip-label :title="$t('label.startipv4')" :tooltip="apiParams.startip.description"/>
</template>
<a-input
v-model:value="form.startipv4"
:placeholder="apiParams.startip.description"/>
</a-form-item>
<a-form-item name="endipv4" ref="endipv4">
<template #label>
<tooltip-label :title="$t('label.endipv4')" :tooltip="apiParams.endip.description"/>
</template>
<a-input
v-model:value="form.endipv4"
:placeholder="apiParams.endip.description"/>
</a-form-item>
<a-form-item v-if="isVirtualRouterForAtLeastOneService" name="routerip" ref="routerip">
<template #label>
<tooltip-label :title="$t('label.routerip')" :tooltip="apiParams.routerip.description"/>
</template>
<a-input
v-model:value="form.routerip"
:placeholder="apiParams.routerip.description"/>
</a-form-item>
<a-form-item name="ip6gateway" ref="ip6gateway">
<template #label>
<tooltip-label :title="$t('label.ip6gateway')" :tooltip="apiParams.ip6gateway.description"/>
</template>
<a-input
v-model:value="form.ip6gateway"
:placeholder="apiParams.ip6gateway.description"/>
</a-form-item>
<a-form-item name="ip6cidr" ref="ip6cidr">
<template #label>
<tooltip-label :title="$t('label.ip6cidr')" :tooltip="apiParams.ip6cidr.description"/>
</template>
<a-input
v-model:value="form.ip6cidr"
:placeholder="apiParams.ip6cidr.description"/>
</a-form-item>
<a-form-item name="startipv6" ref="startipv6">
<template #label>
<tooltip-label :title="$t('label.startipv6')" :tooltip="apiParams.startipv6.description"/>
</template>
<a-input
v-model:value="form.startipv6"
:placeholder="apiParams.startipv6.description"/>
</a-form-item>
<a-form-item name="endipv6" ref="endipv6">
<template #label>
<tooltip-label :title="$t('label.endipv6')" :tooltip="apiParams.endipv6.description"/>
</template>
<a-input
v-model:value="form.endipv6"
:placeholder="apiParams.endipv6.description"/>
</a-form-item>
<a-form-item v-if="isVirtualRouterForAtLeastOneService" name="routeripv6" ref="routeripv6">
<template #label>
<tooltip-label :title="$t('label.routeripv6')" :tooltip="apiParams.routeripv6.description"/>
</template>
<a-input
v-model:value="form.routeripv6"
:placeholder="apiParams.routeripv6.description"/>
</a-form-item>
<a-card size="small" :title="$t('label.ip.v4')" style="margin-top: 15px">
<a-row :gutter="12">
<a-col :md="12" :lg="12">
<a-form-item name="gateway" ref="gateway">
<template #label>
<tooltip-label :title="$t('label.ip4gateway')" :tooltip="apiParams.gateway.description"/>
</template>
<a-input
v-model:value="form.gateway"
:placeholder="apiParams.gateway.description"/>
</a-form-item>
</a-col>
<a-col :md="12" :lg="12">
<a-form-item name="netmask" ref="netmask">
<template #label>
<tooltip-label :title="$t('label.ip4netmask')" :tooltip="apiParams.netmask.description"/>
</template>
<a-input
v-model:value="form.netmask"
:placeholder="apiParams.netmask.description"/>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="12">
<a-col :md="12" :lg="12">
<a-form-item name="startip" ref="startip">
<template #label>
<tooltip-label :title="$t('label.startipv4')" :tooltip="apiParams.startip.description"/>
</template>
<a-input
v-model:value="form.startip"
:placeholder="apiParams.startip.description"/>
</a-form-item>
</a-col>
<a-col :md="12" :lg="12">
<a-form-item name="endip" ref="endip">
<template #label>
<tooltip-label :title="$t('label.endipv4')" :tooltip="apiParams.endip.description"/>
</template>
<a-input
v-model:value="form.endip"
:placeholder="apiParams.endip.description"/>
</a-form-item>
</a-col>
</a-row>
<a-form-item v-if="isVirtualRouterForAtLeastOneService" name="routerip" ref="routerip">
<template #label>
<tooltip-label :title="$t('label.routerip')" :tooltip="apiParams.routerip.description"/>
</template>
<a-input
v-model:value="form.routerip"
:placeholder="apiParams.routerip.description"/>
</a-form-item>
<a-row :gutter="12" v-if="selectedNetworkOfferingSupportsDns">
<a-col :md="12" :lg="12">
<a-form-item v-if="'dns1' in apiParams" name="dns1" ref="dns1">
<template #label>
<tooltip-label :title="$t('label.dns1')" :tooltip="apiParams.dns1.description"/>
</template>
<a-input
v-model:value="form.dns1"
:placeholder="apiParams.dns1.description"/>
</a-form-item>
</a-col>
<a-col :md="12" :lg="12">
<a-form-item v-if="'dns2' in apiParams" name="dns2" ref="dns2">
<template #label>
<tooltip-label :title="$t('label.dns2')" :tooltip="apiParams.dns2.description"/>
</template>
<a-input
v-model:value="form.dns2"
:placeholder="apiParams.dns2.description"/>
</a-form-item>
</a-col>
</a-row>
</a-card>
<a-card size="small" :title="$t('label.ip.v6')" style="margin-top: 15px; margin-bottom: 10px">
<a-row :gutter="12">
<a-col :md="12" :lg="12">
<a-form-item name="ip6gateway" ref="ip6gateway">
<template #label>
<tooltip-label :title="$t('label.ip6gateway')" :tooltip="apiParams.ip6gateway.description"/>
</template>
<a-input
v-model:value="form.ip6gateway"
:placeholder="apiParams.ip6gateway.description"/>
</a-form-item>
</a-col>
<a-col :md="12" :lg="12">
<a-form-item name="ip6cidr" ref="ip6cidr">
<template #label>
<tooltip-label :title="$t('label.ip6cidr')" :tooltip="apiParams.ip6cidr.description"/>
</template>
<a-input
v-model:value="form.ip6cidr"
:placeholder="apiParams.ip6cidr.description"/>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="12">
<a-col :md="12" :lg="12">
<a-form-item name="startipv6" ref="startipv6">
<template #label>
<tooltip-label :title="$t('label.startipv6')" :tooltip="apiParams.startipv6.description"/>
</template>
<a-input
v-model:value="form.startipv6"
:placeholder="apiParams.startipv6.description"/>
</a-form-item>
</a-col>
<a-col :md="12" :lg="12">
<a-form-item name="endipv6" ref="endipv6">
<template #label>
<tooltip-label :title="$t('label.endipv6')" :tooltip="apiParams.endipv6.description"/>
</template>
<a-input
v-model:value="form.endipv6"
:placeholder="apiParams.endipv6.description"/>
</a-form-item>
</a-col>
</a-row>
<a-form-item v-if="isVirtualRouterForAtLeastOneService" name="routeripv6" ref="routeripv6">
<template #label>
<tooltip-label :title="$t('label.routeripv6')" :tooltip="apiParams.routeripv6.description"/>
</template>
<a-input
v-model:value="form.routeripv6"
:placeholder="apiParams.routeripv6.description"/>
</a-form-item>
<a-row :gutter="12" v-if="selectedNetworkOfferingSupportsDns">
<a-col :md="12" :lg="12">
<a-form-item v-if="'ip6dns1' in apiParams" name="ip6dns1" ref="ip6dns1">
<template #label>
<tooltip-label :title="$t('label.ip6dns1')" :tooltip="apiParams.ip6dns1.description"/>
</template>
<a-input
v-model:value="form.ip6dns1"
:placeholder="apiParams.ip6dns1.description"/>
</a-form-item>
</a-col>
<a-col :md="12" :lg="12">
<a-form-item v-if="'ip6dns2' in apiParams" name="ip6dns2" ref="ip6dns2">
<template #label>
<tooltip-label :title="$t('label.ip6dns2')" :tooltip="apiParams.ip6dns2.description"/>
</template>
<a-input
v-model:value="form.ip6dns2"
:placeholder="apiParams.ip6dns2.description"/>
</a-form-item>
</a-col>
</a-row>
</a-card>
<a-form-item name="networkdomain" ref="networkdomain">
<template #label>
<tooltip-label :title="$t('label.networkdomain')" :tooltip="apiParams.networkdomain.description"/>
@ -453,6 +525,16 @@ export default {
this.initForm()
this.fetchData()
},
computed: {
selectedNetworkOfferingSupportsDns () {
if (this.selectedNetworkOffering) {
const services = this.selectedNetworkOffering?.service || []
const dnsServices = services.filter(service => service.name === 'Dns')
return dnsServices && dnsServices.length === 1
}
return false
}
},
methods: {
initForm () {
this.formRef = ref()
@ -471,7 +553,7 @@ export default {
name: [{ required: true, message: this.$t('message.error.name') }],
displaytext: [{ required: true, message: this.$t('message.error.display.text') }],
zoneid: [{ type: 'number', required: true, message: this.$t('message.error.select') }],
vlanid: [{ required: true, message: this.$t('message.please.enter.value') }],
vlan: [{ required: true, message: this.$t('message.please.enter.value') }],
networkofferingid: [{ type: 'number', required: true, message: this.$t('message.error.select') }],
domainid: [{ type: 'number', required: true, message: this.$t('message.error.select') }],
account: [{ type: 'number', required: true, message: this.$t('message.error.select') }],
@ -872,8 +954,8 @@ export default {
const formRaw = toRaw(this.form)
const values = this.handleRemoveFields(formRaw)
if (
(!this.isValidTextValueForKey(values, 'ip4gateway') && !this.isValidTextValueForKey(values, 'ip4netmask') &&
!this.isValidTextValueForKey(values, 'startipv4') && !this.isValidTextValueForKey(values, 'endipv4') &&
(!this.isValidTextValueForKey(values, 'gateway') && !this.isValidTextValueForKey(values, 'netmask') &&
!this.isValidTextValueForKey(values, 'startip') && !this.isValidTextValueForKey(values, 'endip') &&
!this.isValidTextValueForKey(values, 'ip6gateway') && !this.isValidTextValueForKey(values, 'ip6cidr') &&
!this.isValidTextValueForKey(values, 'startipv6') && !this.isValidTextValueForKey(values, 'endipv6'))
) {
@ -893,8 +975,8 @@ export default {
if (this.selectedNetworkOffering.guestiptype === 'Shared') {
params.physicalnetworkid = this.formSelectedPhysicalNetwork.id
}
if (this.isValidTextValueForKey(values, 'vlanid')) {
params.vlan = values.vlanid
if (this.isValidTextValueForKey(values, 'vlan')) {
params.vlan = values.vlan
}
if (this.isValidValueForKey(values, 'bypassvlanoverlapcheck')) {
params.bypassvlanoverlapcheck = values.bypassvlanoverlapcheck
@ -927,43 +1009,19 @@ export default {
params.acltype = 'account' // acl type is "account" for regular users
}
// IPv4 (begin)
if (this.isValidTextValueForKey(values, 'ip4gateway')) {
params.gateway = values.ip4gateway
}
if (this.isValidTextValueForKey(values, 'ip4netmask')) {
params.netmask = values.ip4netmask
}
if (this.isValidTextValueForKey(values, 'startipv4')) {
params.startip = values.startipv4
}
if (this.isValidTextValueForKey(values, 'endipv4')) {
params.endip = values.endipv4
}
if (this.isValidTextValueForKey(values, 'routerip')) {
params.routerip = values.routerip
}
var usefulFields = ['gateway', 'netmask', 'startip', 'endip', 'routerip', 'dns1', 'dns2']
// IPv4 (end)
// IPv6 (begin)
if (this.isValidTextValueForKey(values, 'ip6gateway')) {
params.ip6gateway = values.ip6gateway
}
if (this.isValidTextValueForKey(values, 'ip6cidr')) {
params.ip6cidr = values.ip6cidr
}
if (this.isValidTextValueForKey(values, 'startipv6')) {
params.startipv6 = values.startipv6
}
if (this.isValidTextValueForKey(values, 'endipv6')) {
params.endipv6 = values.endipv6
}
if (this.isValidTextValueForKey(values, 'routeripv6')) {
params.routeripv6 = values.routeripv6
}
usefulFields = [...usefulFields, 'ip6gateway', 'ip6cidr', 'startipv6', 'endipv6', 'routeripv6', 'ip6dns1', 'ip6dns2']
// IPv6 (end)
if (this.isValidTextValueForKey(values, 'networkdomain')) {
params.networkdomain = values.networkdomain
usefulFields.push('networkdomain')
for (var field of usefulFields) {
if (this.isValidTextValueForKey(values, field)) {
params[field] = values[field]
}
}
var hideipaddressusage = this.parseBooleanValueForKey(values, 'hideipaddressusage')
if (hideipaddressusage) {

View File

@ -89,12 +89,57 @@
optionFilterProp="label"
:filterOption="(input, option) => {
return option.children[0].children.toLowerCase().indexOf(input.toLowerCase()) >= 0
}" >
}"
@change="handleVpcOfferingChange" >
<a-select-option :value="offering.id" v-for="offering in vpcOfferings" :key="offering.id">
{{ offering.name }}
</a-select-option>
</a-select>
</a-form-item>
<a-row :gutter="12" v-if="selectedVpcOfferingSupportsDns">
<a-col :md="12" :lg="12">
<a-form-item v-if="'dns1' in apiParams" name="dns1" ref="dns1">
<template #label>
<tooltip-label :title="$t('label.dns1')" :tooltip="apiParams.dns1.description"/>
</template>
<a-input
v-model:value="form.dns1"
:placeholder="apiParams.dns1.description"/>
</a-form-item>
</a-col>
<a-col :md="12" :lg="12">
<a-form-item v-if="'dns2' in apiParams" name="dns2" ref="dns2">
<template #label>
<tooltip-label :title="$t('label.dns2')" :tooltip="apiParams.dns2.description"/>
</template>
<a-input
v-model:value="form.dns2"
:placeholder="apiParams.dns2.description"/>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="12" v-if="selectedVpcOfferingSupportsDns">
<a-col :md="12" :lg="12">
<a-form-item v-if="selectedVpcOffering && selectedVpcOffering.internetprotocol === 'DualStack' && 'ip6dns1' in apiParams" name="ip6dns1" ref="ip6dns1">
<template #label>
<tooltip-label :title="$t('label.ip6dns1')" :tooltip="apiParams.ip6dns1.description"/>
</template>
<a-input
v-model:value="form.ip6dns1"
:placeholder="apiParams.ip6dns1.description"/>
</a-form-item>
</a-col>
<a-col :md="12" :lg="12">
<a-form-item v-if="selectedVpcOffering && selectedVpcOffering.internetprotocol === 'DualStack' && 'ip6dns2' in apiParams" name="ip6dns2" ref="ip6dns2">
<template #label>
<tooltip-label :title="$t('label.ip6dns2')" :tooltip="apiParams.ip6dns2.description"/>
</template>
<a-input
v-model:value="form.ip6dns2"
:placeholder="apiParams.ip6dns2.description"/>
</a-form-item>
</a-col>
</a-row>
<a-form-item name="start" ref="start">
<template #label>
<tooltip-label :title="$t('label.start')" :tooltip="apiParams.start.description"/>
@ -127,7 +172,8 @@ export default {
loadingZone: false,
loadingOffering: false,
zones: [],
vpcOfferings: []
vpcOfferings: [],
selectedVpcOffering: {}
}
},
beforeCreate () {
@ -137,6 +183,16 @@ export default {
this.initForm()
this.fetchData()
},
computed: {
selectedVpcOfferingSupportsDns () {
if (this.selectedVpcOffering) {
const services = this.selectedVpcOffering?.service || []
const dnsServices = services.filter(service => service.name === 'Dns')
return dnsServices && dnsServices.length === 1
}
return false
}
},
methods: {
initForm () {
this.formRef = ref()
@ -181,10 +237,23 @@ export default {
api('listVPCOfferings', { zoneid: this.form.zoneid, state: 'Enabled' }).then((reponse) => {
this.vpcOfferings = reponse.listvpcofferingsresponse.vpcoffering
this.form.vpcofferingid = this.vpcOfferings[0].id || ''
this.selectedVpcOffering = this.vpcOfferings[0] || {}
}).finally(() => {
this.loadingOffering = false
})
},
handleVpcOfferingChange (value) {
this.selectedVpcOffering = {}
if (!value) {
return
}
for (var offering of this.vpcOfferings) {
if (offering.id === value) {
this.selectedVpcOffering = offering
return
}
}
},
closeAction () {
this.$emit('close-action')
},

View File

@ -101,6 +101,52 @@
</template>
<a-switch v-model:checked="form.updateinsequence" />
</a-form-item>
<div v-if="selectedNetworkOfferingSupportsDns">
<a-row :gutter="12">
<a-col :md="12" :lg="12">
<a-form-item v-if="'dns1' in apiParams" name="dns1" ref="dns1">
<template #label>
<tooltip-label :title="$t('label.dns1')" :tooltip="apiParams.dns1.description"/>
</template>
<a-input
v-model:value="form.dns1"
:placeholder="apiParams.dns1.description"/>
</a-form-item>
</a-col>
<a-col :md="12" :lg="12">
<a-form-item v-if="'dns2' in apiParams" name="dns2" ref="dns2">
<template #label>
<tooltip-label :title="$t('label.dns2')" :tooltip="apiParams.dns2.description"/>
</template>
<a-input
v-model:value="form.dns2"
:placeholder="apiParams.dns2.description"/>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="12">
<a-col :md="12" :lg="12">
<a-form-item v-if="networkOffering && ((networkOffering.guestiptype === 'Isolated' && networkOffering.internetprotocol === 'DualStack') || (networkOffering.guestiptype === 'Shared' && resource.ip6cidr)) && 'ip6dns1' in apiParams" name="ip6dns1" ref="ip6dns1">
<template #label>
<tooltip-label :title="$t('label.ip6dns1')" :tooltip="apiParams.ip6dns1.description"/>
</template>
<a-input
v-model:value="form.ip6dns1"
:placeholder="apiParams.ip6dns1.description"/>
</a-form-item>
</a-col>
<a-col :md="12" :lg="12">
<a-form-item v-if="networkOffering && ((networkOffering.guestiptype === 'Isolated' && networkOffering.internetprotocol === 'DualStack') || (networkOffering.guestiptype === 'Shared' && resource.ip6cidr)) && 'ip6dns1' in apiParams" name="ip6dns2" ref="ip6dns2">
<template #label>
<tooltip-label :title="$t('label.ip6dns2')" :tooltip="apiParams.ip6dns2.description"/>
</template>
<a-input
v-model:value="form.ip6dns2"
:placeholder="apiParams.ip6dns2.description"/>
</a-form-item>
</a-col>
</a-row>
</div>
<a-form-item name="displaynetwork" ref="displaynetwork" v-if="isAdmin()">
<template #label>
<tooltip-label :title="$t('label.displaynetwork')" :tooltip="apiParams.displaynetwork.description"/>
@ -160,7 +206,11 @@ export default {
this.resourceValues = {
name: this.resource.name,
displaytext: this.resource.displaytext,
guestvmcidr: this.resource.cidr
guestvmcidr: this.resource.cidr,
dns1: this.resource.dns1,
dns2: this.resource.dns2,
ip6dns1: this.resource.ip6dns1,
ip6dns2: this.resource.ip6dns2
}
if (this.isUpdatingIsolatedNetwork) {
this.resourceValues.networkdomain = this.resource.networkdomain
@ -176,6 +226,14 @@ export default {
computed: {
isUpdatingIsolatedNetwork () {
return this.resource && this.resource.type === 'Isolated'
},
selectedNetworkOfferingSupportsDns () {
if (this.networkOffering) {
const services = this.networkOffering?.service || []
const dnsServices = services.filter(service => service.name === 'Dns')
return dnsServices && dnsServices.length === 1
}
return false
}
},
methods: {
@ -200,13 +258,15 @@ export default {
},
fetchNetworkOfferingData () {
this.networkOfferings = []
if (!this.isUpdatingIsolatedNetwork) return
const params = {
zoneid: this.resource.zoneid,
state: 'Enabled',
guestiptype: this.resource.type,
forvpc: !!this.resource.vpcid
}
if (!this.isUpdatingIsolatedNetwork) {
params.id = this.resource.networkofferingid
}
this.networkOfferingLoading = true
api('listNetworkOfferings', params).then(json => {
this.networkOfferings = json.listnetworkofferingsresponse.networkoffering