mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
network: Specify IP for VR in shared networks (#4503)
This PR enables admins to specify IP for a VR in a shared network.
This commit is contained in:
parent
b6fe9f99eb
commit
aa01580381
@ -452,4 +452,8 @@ public interface Network extends ControlledEntity, StateObject<Network.State>, I
|
|||||||
String getExternalId();
|
String getExternalId();
|
||||||
|
|
||||||
PVlanType getPvlanType();
|
PVlanType getPvlanType();
|
||||||
|
|
||||||
|
String getRouterIp();
|
||||||
|
|
||||||
|
String getRouterIpv6();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -319,4 +319,14 @@ public class NetworkProfile implements Network {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRouterIp() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRouterIpv6() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -802,6 +802,8 @@ public class ApiConstants {
|
|||||||
public static final String ROUTER_HEALTH_CHECKS = "healthchecks";
|
public static final String ROUTER_HEALTH_CHECKS = "healthchecks";
|
||||||
public static final String ROUTER_CHECK_NAME = "checkname";
|
public static final String ROUTER_CHECK_NAME = "checkname";
|
||||||
public static final String ROUTER_CHECK_TYPE = "checktype";
|
public static final String ROUTER_CHECK_TYPE = "checktype";
|
||||||
|
public static final String ROUTER_IP = "routerip";
|
||||||
|
public static final String ROUTER_IPV6 = "routeripv6";
|
||||||
public static final String LAST_UPDATED = "lastupdated";
|
public static final String LAST_UPDATED = "lastupdated";
|
||||||
public static final String PERFORM_FRESH_CHECKS = "performfreshchecks";
|
public static final String PERFORM_FRESH_CHECKS = "performfreshchecks";
|
||||||
public static final String CACHE_MODE = "cachemode";
|
public static final String CACHE_MODE = "cachemode";
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
package org.apache.cloudstack.api.command.admin.network;
|
package org.apache.cloudstack.api.command.admin.network;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.api.ApiArgValidator;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import org.apache.cloudstack.api.APICommand;
|
import org.apache.cloudstack.api.APICommand;
|
||||||
@ -42,6 +43,14 @@ public class CreateNetworkCmdByAdmin extends CreateNetworkCmd implements AdminCm
|
|||||||
@Parameter(name=ApiConstants.HIDE_IP_ADDRESS_USAGE, type=CommandType.BOOLEAN, description="when true ip address usage for the network will not be exported by the listUsageRecords API")
|
@Parameter(name=ApiConstants.HIDE_IP_ADDRESS_USAGE, type=CommandType.BOOLEAN, description="when true ip address usage for the network will not be exported by the listUsageRecords API")
|
||||||
private Boolean hideIpAddressUsage;
|
private Boolean hideIpAddressUsage;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.ROUTER_IP, type = CommandType.STRING, description = "IPV4 address to be assigned to a router in a shared network", since = "4.16",
|
||||||
|
validations = {ApiArgValidator.NotNullOrEmpty})
|
||||||
|
private String routerIp;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.ROUTER_IPV6, type = CommandType.STRING, description = "IPV6 address to be assigned to a router in a shared network", since = "4.16",
|
||||||
|
validations = {ApiArgValidator.NotNullOrEmpty})
|
||||||
|
private String routerIpv6;
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////////// Accessors ///////////////////////
|
/////////////////// Accessors ///////////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
@ -63,4 +72,12 @@ public class CreateNetworkCmdByAdmin extends CreateNetworkCmd implements AdminCm
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getRouterIp() {
|
||||||
|
return routerIp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRouterIpv6() {
|
||||||
|
return routerIpv6;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -182,7 +182,7 @@ public interface NetworkOrchestrationService {
|
|||||||
|
|
||||||
Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, boolean bypassVlanOverlapCheck, String networkDomain, Account owner,
|
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,
|
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) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException;
|
Boolean displayNetworkEnabled, String isolatedPvlan, Network.PVlanType isolatedPvlanType, String externalId, String routerIp, String routerIpv6) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException;
|
||||||
|
|
||||||
UserDataServiceProvider getPasswordResetProvider(Network network);
|
UserDataServiceProvider getPasswordResetProvider(Network network);
|
||||||
|
|
||||||
|
|||||||
@ -623,6 +623,15 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||||||
setStateMachine();
|
setStateMachine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateRouterIpInNetworkDetails(Long networkId, String routerIp, String routerIpv6) {
|
||||||
|
if (isNotBlank(routerIp)) {
|
||||||
|
networkDetailsDao.addDetail(networkId, ApiConstants.ROUTER_IP, routerIp, true);
|
||||||
|
}
|
||||||
|
if (isNotBlank(routerIpv6)) {
|
||||||
|
networkDetailsDao.addDetail(networkId, ApiConstants.ROUTER_IPV6, routerIpv6, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<? extends Network> setupNetwork(final Account owner, final NetworkOffering offering, final DeploymentPlan plan, final String name, final String displayText, final boolean isDefault)
|
public List<? extends Network> setupNetwork(final Account owner, final NetworkOffering offering, final DeploymentPlan plan, final String name, final String displayText, final boolean isDefault)
|
||||||
throws ConcurrentOperationException {
|
throws ConcurrentOperationException {
|
||||||
@ -705,6 +714,8 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||||||
networkDetailsDao.persist(detailVO);
|
networkDetailsDao.persist(detailVO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateRouterIpInNetworkDetails(networkPersisted.getId(), network.getRouterIp(), network.getRouterIpv6());
|
||||||
|
|
||||||
if (predefined instanceof NetworkVO && guru instanceof NetworkGuruAdditionalFunctions){
|
if (predefined instanceof NetworkVO && guru instanceof NetworkGuruAdditionalFunctions){
|
||||||
final NetworkGuruAdditionalFunctions functions = (NetworkGuruAdditionalFunctions) guru;
|
final NetworkGuruAdditionalFunctions functions = (NetworkGuruAdditionalFunctions) guru;
|
||||||
functions.finalizeNetworkDesign(networkPersisted.getId(), ((NetworkVO)predefined).getVlanIdAsUUID());
|
functions.finalizeNetworkDesign(networkPersisted.getId(), ((NetworkVO)predefined).getVlanIdAsUUID());
|
||||||
@ -2297,7 +2308,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||||||
// create network for private gateway
|
// create network for private gateway
|
||||||
return createGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId,
|
return createGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId,
|
||||||
bypassVlanOverlapCheck, null, owner, null, pNtwk, pNtwk.getDataCenterId(), ACLType.Account, null,
|
bypassVlanOverlapCheck, null, owner, null, pNtwk, pNtwk.getDataCenterId(), ACLType.Account, null,
|
||||||
vpcId, null, null, true, null, null, null, true);
|
vpcId, null, null, true, null, null, null, true, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -2305,18 +2316,18 @@ 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,
|
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,
|
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 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) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
|
final Boolean isDisplayNetworkEnabled, final String isolatedPvlan, Network.PVlanType isolatedPvlanType, String externalId, String routerIp, String routerIpv6) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
|
||||||
// create Isolated/Shared/L2 network
|
// create Isolated/Shared/L2 network
|
||||||
return createGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, bypassVlanOverlapCheck,
|
return createGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, bypassVlanOverlapCheck,
|
||||||
networkDomain, owner, domainId, pNtwk, zoneId, aclType, subdomainAccess, vpcId, ip6Gateway, ip6Cidr,
|
networkDomain, owner, domainId, pNtwk, zoneId, aclType, subdomainAccess, vpcId, ip6Gateway, ip6Cidr,
|
||||||
isDisplayNetworkEnabled, isolatedPvlan, isolatedPvlanType, externalId, false);
|
isDisplayNetworkEnabled, isolatedPvlan, isolatedPvlanType, externalId, false, routerIp, routerIpv6);
|
||||||
}
|
}
|
||||||
|
|
||||||
@DB
|
@DB
|
||||||
private Network createGuestNetwork(final long networkOfferingId, final String name, final String displayText, final String gateway, final String cidr, String vlanId,
|
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,
|
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 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) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
|
final Boolean isDisplayNetworkEnabled, final String isolatedPvlan, Network.PVlanType isolatedPvlanType, String externalId, final Boolean isPrivateNetwork, String routerIp, String routerIpv6) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
|
||||||
|
|
||||||
final NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId);
|
final NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId);
|
||||||
final DataCenterVO zone = _dcDao.findById(zoneId);
|
final DataCenterVO zone = _dcDao.findById(zoneId);
|
||||||
@ -2577,6 +2588,14 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||||||
userNetwork.setExternalId(externalId);
|
userNetwork.setExternalId(externalId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isNotBlank(routerIp)) {
|
||||||
|
userNetwork.setRouterIp(routerIp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNotBlank(routerIpv6)) {
|
||||||
|
userNetwork.setRouterIpv6(routerIpv6);
|
||||||
|
}
|
||||||
|
|
||||||
if (vlanIdFinal != null) {
|
if (vlanIdFinal != null) {
|
||||||
if (isolatedPvlan == null) {
|
if (isolatedPvlan == null) {
|
||||||
URI uri = null;
|
URI uri = null;
|
||||||
@ -2616,7 +2635,6 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
|||||||
|
|
||||||
final List<? extends Network> networks = setupNetwork(owner, ntwkOff, userNetwork, plan, name, displayText, true, domainId, aclType, subdomainAccessFinal, vpcId,
|
final List<? extends Network> networks = setupNetwork(owner, ntwkOff, userNetwork, plan, name, displayText, true, domainId, aclType, subdomainAccessFinal, vpcId,
|
||||||
isDisplayNetworkEnabled);
|
isDisplayNetworkEnabled);
|
||||||
|
|
||||||
Network network = null;
|
Network network = null;
|
||||||
if (networks == null || networks.isEmpty()) {
|
if (networks == null || networks.isEmpty()) {
|
||||||
throw new CloudRuntimeException("Fail to create a network");
|
throw new CloudRuntimeException("Fail to create a network");
|
||||||
|
|||||||
@ -175,6 +175,12 @@ public class NetworkVO implements Network {
|
|||||||
@Column(name = "external_id")
|
@Column(name = "external_id")
|
||||||
String externalId;
|
String externalId;
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
String routerIp;
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
String routerIpv6;
|
||||||
|
|
||||||
@Transient
|
@Transient
|
||||||
transient String vlanIdAsUUID;
|
transient String vlanIdAsUUID;
|
||||||
|
|
||||||
@ -672,4 +678,20 @@ public class NetworkVO implements Network {
|
|||||||
public void setPvlanType(PVlanType pvlanType) {
|
public void setPvlanType(PVlanType pvlanType) {
|
||||||
this.pVlanType = pvlanType;
|
this.pVlanType = pvlanType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getRouterIp() {
|
||||||
|
return routerIp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRouterIp(String routerIp) {
|
||||||
|
this.routerIp = routerIp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRouterIpv6() {
|
||||||
|
return routerIpv6;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRouterIpv6(String routerIpv6) {
|
||||||
|
this.routerIpv6 = routerIpv6;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -797,7 +797,7 @@ public class KubernetesClusterManagerImpl extends ManagerBase implements Kuberne
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
network = networkMgr.createGuestNetwork(networkOffering.getId(), clusterName + "-network", owner.getAccountName() + "-network",
|
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, false, null, owner, null, physicalNetwork, zone.getId(), ControlledEntity.ACLType.Account, null, null, null, null, true, null, null, null, null, null);
|
||||||
} catch (ConcurrentOperationException | InsufficientCapacityException | ResourceAllocationException e) {
|
} catch (ConcurrentOperationException | InsufficientCapacityException | ResourceAllocationException e) {
|
||||||
logAndThrow(Level.ERROR, String.format("Unable to create network for the Kubernetes cluster: %s", clusterName));
|
logAndThrow(Level.ERROR, String.format("Unable to create network for the Kubernetes cluster: %s", clusterName));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,6 +32,7 @@ import javax.inject.Inject;
|
|||||||
|
|
||||||
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
|
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
|
||||||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||||
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
import org.apache.cloudstack.api.response.AcquirePodIpCmdResponse;
|
import org.apache.cloudstack.api.response.AcquirePodIpCmdResponse;
|
||||||
import org.apache.cloudstack.context.CallContext;
|
import org.apache.cloudstack.context.CallContext;
|
||||||
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
|
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
|
||||||
@ -850,10 +851,16 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
|
|||||||
errorMessage.append(", network id=" + guestNetworkId);
|
errorMessage.append(", network id=" + guestNetworkId);
|
||||||
}
|
}
|
||||||
sc.setJoinParameters("vlan", "type", vlanUse);
|
sc.setJoinParameters("vlan", "type", vlanUse);
|
||||||
|
String routerIpAddress = null;
|
||||||
|
if (network != null) {
|
||||||
|
NetworkDetailVO routerIpDetail = _networkDetailsDao.findDetail(network.getId(), ApiConstants.ROUTER_IP);
|
||||||
|
routerIpAddress = routerIpDetail != null ? routerIpDetail.getValue() : null;
|
||||||
|
}
|
||||||
if (requestedIp != null) {
|
if (requestedIp != null) {
|
||||||
sc.addAnd("address", SearchCriteria.Op.EQ, requestedIp);
|
sc.addAnd("address", SearchCriteria.Op.EQ, requestedIp);
|
||||||
errorMessage.append(": requested ip " + requestedIp + " is not available");
|
errorMessage.append(": requested ip " + requestedIp + " is not available");
|
||||||
|
} else if (routerIpAddress != null) {
|
||||||
|
sc.addAnd("address", Op.NEQ, routerIpAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean ascOrder = ! forSystemVms;
|
boolean ascOrder = ! forSystemVms;
|
||||||
@ -1729,7 +1736,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
|
|||||||
s_logger.debug("Creating network for account " + owner + " from the network offering id=" + requiredOfferings.get(0).getId()
|
s_logger.debug("Creating network for account " + owner + " from the network offering id=" + requiredOfferings.get(0).getId()
|
||||||
+ " as a part of createVlanIpRange process");
|
+ " as a part of createVlanIpRange process");
|
||||||
guestNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), owner.getAccountName() + "-network", owner.getAccountName()
|
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);
|
+ "-network", null, null, null, false, null, owner, null, physicalNetwork, zoneId, ACLType.Account, null, null, null, null, true, null, null, null, null, null);
|
||||||
if (guestNetwork == null) {
|
if (guestNetwork == null) {
|
||||||
s_logger.warn("Failed to create default Virtual network for the account " + accountId + "in zone " + zoneId);
|
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 "
|
throw new CloudRuntimeException("Failed to create a Guest Isolated Networks with SourceNAT "
|
||||||
@ -2104,7 +2111,6 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
|
|||||||
public void doInTransactionWithoutResult(TransactionStatus status) throws InsufficientAddressCapacityException {
|
public void doInTransactionWithoutResult(TransactionStatus status) throws InsufficientAddressCapacityException {
|
||||||
//This method allocates direct ip for the Shared network in Advance zones
|
//This method allocates direct ip for the Shared network in Advance zones
|
||||||
boolean ipv4 = false;
|
boolean ipv4 = false;
|
||||||
|
|
||||||
if (network.getGateway() != null) {
|
if (network.getGateway() != null) {
|
||||||
if (nic.getIPv4Address() == null) {
|
if (nic.getIPv4Address() == null) {
|
||||||
PublicIp ip = null;
|
PublicIp ip = null;
|
||||||
|
|||||||
@ -1029,6 +1029,46 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void validateRouterIps(String routerIp, String routerIpv6, String startIp, String endIp, String gateway,
|
||||||
|
String netmask, String startIpv6, String endIpv6, String ip6Cidr) {
|
||||||
|
if (isNotBlank(routerIp)) {
|
||||||
|
if (startIp != null && endIp == null) {
|
||||||
|
endIp = startIp;
|
||||||
|
}
|
||||||
|
if (!NetUtils.isValidIp4(routerIp)) {
|
||||||
|
throw new CloudRuntimeException("Router IPv4 IP provided is of incorrect format");
|
||||||
|
}
|
||||||
|
if (isNotBlank(startIp) && isNotBlank(endIp)) {
|
||||||
|
if (!NetUtils.isIpInRange(routerIp, startIp, endIp)) {
|
||||||
|
throw new CloudRuntimeException("Router IPv4 IP provided is not within the specified range: " + startIp + " - " + endIp);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String cidr = NetUtils.ipAndNetMaskToCidr(gateway, netmask);
|
||||||
|
if (!NetUtils.isIpWithInCidrRange(routerIp, cidr)) {
|
||||||
|
throw new CloudRuntimeException("Router IP provided in not within the network range");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isNotBlank(routerIpv6)) {
|
||||||
|
if (startIpv6 != null && endIpv6 == null) {
|
||||||
|
endIpv6 = startIpv6;
|
||||||
|
}
|
||||||
|
if (!NetUtils.isValidIp6(routerIpv6)) {
|
||||||
|
throw new CloudRuntimeException("Router IPv6 address provided is of incorrect format");
|
||||||
|
}
|
||||||
|
if (isNotBlank(startIpv6) && isNotBlank(endIpv6)) {
|
||||||
|
String ipv6Range = startIpv6 + "-" + endIpv6;
|
||||||
|
if (!NetUtils.isIp6InRange(routerIpv6, ipv6Range)) {
|
||||||
|
throw new CloudRuntimeException("Router IPv6 address provided is not within the specified range: " + startIpv6 + " - " + endIpv6);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!NetUtils.isIp6InNetwork(routerIpv6, ip6Cidr)) {
|
||||||
|
throw new CloudRuntimeException("Router IPv6 address provided is not with the network range");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@DB
|
@DB
|
||||||
@ActionEvent(eventType = EventTypes.EVENT_NETWORK_CREATE, eventDescription = "creating network")
|
@ActionEvent(eventType = EventTypes.EVENT_NETWORK_CREATE, eventDescription = "creating network")
|
||||||
@ -1042,10 +1082,14 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||||||
String vlanId = null;
|
String vlanId = null;
|
||||||
boolean bypassVlanOverlapCheck = false;
|
boolean bypassVlanOverlapCheck = false;
|
||||||
boolean hideIpAddressUsage = false;
|
boolean hideIpAddressUsage = false;
|
||||||
|
String routerIp = null;
|
||||||
|
String routerIpv6 = null;
|
||||||
if (cmd instanceof CreateNetworkCmdByAdmin) {
|
if (cmd instanceof CreateNetworkCmdByAdmin) {
|
||||||
vlanId = ((CreateNetworkCmdByAdmin)cmd).getVlan();
|
vlanId = ((CreateNetworkCmdByAdmin)cmd).getVlan();
|
||||||
bypassVlanOverlapCheck = ((CreateNetworkCmdByAdmin)cmd).getBypassVlanOverlapCheck();
|
bypassVlanOverlapCheck = ((CreateNetworkCmdByAdmin)cmd).getBypassVlanOverlapCheck();
|
||||||
hideIpAddressUsage = ((CreateNetworkCmdByAdmin)cmd).getHideIpAddressUsage();
|
hideIpAddressUsage = ((CreateNetworkCmdByAdmin)cmd).getHideIpAddressUsage();
|
||||||
|
routerIp = ((CreateNetworkCmdByAdmin)cmd).getRouterIp();
|
||||||
|
routerIpv6 = ((CreateNetworkCmdByAdmin)cmd).getRouterIpv6();
|
||||||
}
|
}
|
||||||
|
|
||||||
String name = cmd.getNetworkName();
|
String name = cmd.getNetworkName();
|
||||||
@ -1150,6 +1194,15 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||||||
throw new InvalidParameterValueException("Only Admins can create network with guest type " + GuestType.Shared);
|
throw new InvalidParameterValueException("Only Admins can create network with guest type " + GuestType.Shared);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ntwkOff.getGuestType() != GuestType.Shared && (isNotBlank(routerIp) || isNotBlank(routerIpv6))) {
|
||||||
|
throw new InvalidParameterValueException("Router IP can be specified only for Shared networks");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ntwkOff.getGuestType() == GuestType.Shared && !_networkModel.isProviderForNetworkOffering(Provider.VirtualRouter, networkOfferingId)
|
||||||
|
&& (isNotBlank(routerIp) || isNotBlank(routerIpv6))) {
|
||||||
|
throw new InvalidParameterValueException("Virtual Router is not a supported provider for the Shared network, hence router ip should not be provided");
|
||||||
|
}
|
||||||
|
|
||||||
// Check if the network is domain specific
|
// Check if the network is domain specific
|
||||||
if (aclType == ACLType.Domain) {
|
if (aclType == ACLType.Domain) {
|
||||||
// only Admin can create domain with aclType=Domain
|
// only Admin can create domain with aclType=Domain
|
||||||
@ -1279,6 +1332,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
validateRouterIps(routerIp, routerIpv6, startIP, endIP, gateway, netmask, startIPv6, endIPv6, ip6Cidr);
|
||||||
|
|
||||||
if (isNotBlank(isolatedPvlan) && (zone.getNetworkType() != NetworkType.Advanced || ntwkOff.getGuestType() == GuestType.Isolated)) {
|
if (isNotBlank(isolatedPvlan) && (zone.getNetworkType() != NetworkType.Advanced || ntwkOff.getGuestType() == GuestType.Isolated)) {
|
||||||
throw new InvalidParameterValueException("Can only support create Private VLAN network with advanced shared or L2 network!");
|
throw new InvalidParameterValueException("Can only support create Private VLAN network with advanced shared or L2 network!");
|
||||||
}
|
}
|
||||||
@ -1365,7 +1420,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||||||
|
|
||||||
Network network = commitNetwork(networkOfferingId, gateway, startIP, endIP, netmask, networkDomain, vlanId, bypassVlanOverlapCheck, name, displayText, caller, physicalNetworkId, zoneId,
|
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,
|
domainId, isDomainSpecific, subdomainAccess, vpcId, startIPv6, endIPv6, ip6Gateway, ip6Cidr, displayNetwork, aclId, secondaryVlanId, privateVlanType, ntwkOff, pNtwk, aclType, owner, cidr, createVlan,
|
||||||
externalId);
|
externalId, routerIp, routerIpv6);
|
||||||
|
|
||||||
if (hideIpAddressUsage) {
|
if (hideIpAddressUsage) {
|
||||||
_networkDetailsDao.persist(new NetworkDetailVO(network.getId(), Network.hideIpAddressUsage, String.valueOf(hideIpAddressUsage), false));
|
_networkDetailsDao.persist(new NetworkDetailVO(network.getId(), Network.hideIpAddressUsage, String.valueOf(hideIpAddressUsage), false));
|
||||||
@ -1445,7 +1500,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||||||
final Boolean bypassVlanOverlapCheck, final String name, final String displayText, final Account caller, final Long physicalNetworkId, final Long zoneId, final Long domainId,
|
final Boolean bypassVlanOverlapCheck, final String name, final String displayText, final Account caller, final Long physicalNetworkId, final Long zoneId, final Long domainId,
|
||||||
final boolean isDomainSpecific, final Boolean subdomainAccessFinal, final Long vpcId, final String startIPv6, final String endIPv6, final String ip6Gateway, final String ip6Cidr,
|
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 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) throws InsufficientCapacityException, ResourceAllocationException {
|
final String cidr, final boolean createVlan, final String externalId, String routerIp, String routerIpv6) throws InsufficientCapacityException, ResourceAllocationException {
|
||||||
try {
|
try {
|
||||||
Network network = Transaction.execute(new TransactionCallbackWithException<Network, Exception>() {
|
Network network = Transaction.execute(new TransactionCallbackWithException<Network, Exception>() {
|
||||||
@Override
|
@Override
|
||||||
@ -1500,7 +1555,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
|||||||
}
|
}
|
||||||
|
|
||||||
network = _networkMgr.createGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, bypassVlanOverlapCheck, networkDomain, owner, sharedDomainId, pNtwk,
|
network = _networkMgr.createGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, bypassVlanOverlapCheck, networkDomain, owner, sharedDomainId, pNtwk,
|
||||||
zoneId, aclType, subdomainAccess, vpcId, ip6Gateway, ip6Cidr, displayNetwork, isolatedPvlan, isolatedPvlanType, externalId);
|
zoneId, aclType, subdomainAccess, vpcId, ip6Gateway, ip6Cidr, displayNetwork, isolatedPvlan, isolatedPvlanType, externalId, routerIp, routerIpv6);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_accountMgr.isRootAdmin(caller.getId()) && createVlan && network != null) {
|
if (_accountMgr.isRootAdmin(caller.getId()) && createVlan && network != null) {
|
||||||
|
|||||||
@ -205,6 +205,13 @@ public class DirectNetworkGuru extends AdapterBase implements NetworkGuru {
|
|||||||
if (userSpecified.getPvlanType() != null) {
|
if (userSpecified.getPvlanType() != null) {
|
||||||
config.setPvlanType(userSpecified.getPvlanType());
|
config.setPvlanType(userSpecified.getPvlanType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (userSpecified.getRouterIp() != null) {
|
||||||
|
config.setRouterIp(userSpecified.getRouterIp());
|
||||||
|
}
|
||||||
|
if (userSpecified.getRouterIpv6() != null) {
|
||||||
|
config.setRouterIpv6(userSpecified.getRouterIpv6());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isSecurityGroupEnabled = _networkModel.areServicesSupportedByNetworkOffering(offering.getId(), Service.SecurityGroup);
|
boolean isSecurityGroupEnabled = _networkModel.areServicesSupportedByNetworkOffering(offering.getId(), Service.SecurityGroup);
|
||||||
|
|||||||
@ -27,6 +27,7 @@ import java.util.Map;
|
|||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.cloud.network.router.deployment.RouterDeploymentDefinition;
|
import org.cloud.network.router.deployment.RouterDeploymentDefinition;
|
||||||
|
|
||||||
@ -71,6 +72,8 @@ import com.cloud.network.Networks.IsolationType;
|
|||||||
import com.cloud.network.addr.PublicIp;
|
import com.cloud.network.addr.PublicIp;
|
||||||
import com.cloud.network.dao.IPAddressDao;
|
import com.cloud.network.dao.IPAddressDao;
|
||||||
import com.cloud.network.dao.NetworkDao;
|
import com.cloud.network.dao.NetworkDao;
|
||||||
|
import com.cloud.network.dao.NetworkDetailVO;
|
||||||
|
import com.cloud.network.dao.NetworkDetailsDao;
|
||||||
import com.cloud.network.dao.UserIpv6AddressDao;
|
import com.cloud.network.dao.UserIpv6AddressDao;
|
||||||
import com.cloud.network.lb.LoadBalancingRule;
|
import com.cloud.network.lb.LoadBalancingRule;
|
||||||
import com.cloud.network.router.VirtualRouter.RedundantState;
|
import com.cloud.network.router.VirtualRouter.RedundantState;
|
||||||
@ -156,6 +159,8 @@ public class NetworkHelperImpl implements NetworkHelper {
|
|||||||
ConfigurationDao _configDao;
|
ConfigurationDao _configDao;
|
||||||
@Inject
|
@Inject
|
||||||
VpcVirtualNetworkApplianceManager _vpcRouterMgr;
|
VpcVirtualNetworkApplianceManager _vpcRouterMgr;
|
||||||
|
@Inject
|
||||||
|
NetworkDetailsDao networkDetailsDao;
|
||||||
|
|
||||||
protected final Map<HypervisorType, ConfigKey<String>> hypervisorsMap = new HashMap<>();
|
protected final Map<HypervisorType, ConfigKey<String>> hypervisorsMap = new HashMap<>();
|
||||||
|
|
||||||
@ -718,13 +723,19 @@ public class NetworkHelperImpl implements NetworkHelper {
|
|||||||
+ guestNetwork);
|
+ guestNetwork);
|
||||||
defaultNetworkStartIp = placeholder.getIPv4Address();
|
defaultNetworkStartIp = placeholder.getIPv4Address();
|
||||||
} else {
|
} else {
|
||||||
final String startIp = _networkModel.getStartIpAddress(guestNetwork.getId());
|
NetworkDetailVO routerIpDetail = networkDetailsDao.findDetail(guestNetwork.getId(), ApiConstants.ROUTER_IP);
|
||||||
if (startIp != null
|
String routerIp = routerIpDetail != null ? routerIpDetail.getValue() : null;
|
||||||
&& _ipAddressDao.findByIpAndSourceNetworkId(guestNetwork.getId(), startIp).getAllocatedTime() == null) {
|
if (routerIp != null) {
|
||||||
defaultNetworkStartIp = startIp;
|
defaultNetworkStartIp = routerIp;
|
||||||
} else if (s_logger.isDebugEnabled()) {
|
} else {
|
||||||
s_logger.debug("First ipv4 " + startIp + " in network id=" + guestNetwork.getId()
|
final String startIp = _networkModel.getStartIpAddress(guestNetwork.getId());
|
||||||
+ " is already allocated, can't use it for domain router; will get random ip address from the range");
|
if (startIp != null
|
||||||
|
&& _ipAddressDao.findByIpAndSourceNetworkId(guestNetwork.getId(), startIp).getAllocatedTime() == null) {
|
||||||
|
defaultNetworkStartIp = startIp;
|
||||||
|
} else if (s_logger.isDebugEnabled()) {
|
||||||
|
s_logger.debug("First ipv4 " + startIp + " in network id=" + guestNetwork.getId()
|
||||||
|
+ " is already allocated, can't use it for domain router; will get random ip address from the range");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -735,12 +746,18 @@ public class NetworkHelperImpl implements NetworkHelper {
|
|||||||
+ guestNetwork);
|
+ guestNetwork);
|
||||||
defaultNetworkStartIpv6 = placeholder.getIPv6Address();
|
defaultNetworkStartIpv6 = placeholder.getIPv6Address();
|
||||||
} else {
|
} else {
|
||||||
final String startIpv6 = _networkModel.getStartIpv6Address(guestNetwork.getId());
|
NetworkDetailVO routerIpDetail = networkDetailsDao.findDetail(guestNetwork.getId(), ApiConstants.ROUTER_IPV6);
|
||||||
if (startIpv6 != null && _ipv6Dao.findByNetworkIdAndIp(guestNetwork.getId(), startIpv6) == null) {
|
String routerIpv6 = routerIpDetail != null ? routerIpDetail.getValue() : null;
|
||||||
defaultNetworkStartIpv6 = startIpv6;
|
if (routerIpv6 != null) {
|
||||||
} else if (s_logger.isDebugEnabled()) {
|
defaultNetworkStartIpv6 = routerIpv6;
|
||||||
s_logger.debug("First ipv6 " + startIpv6 + " in network id=" + guestNetwork.getId()
|
} else {
|
||||||
+ " is already allocated, can't use it for domain router; will get random ipv6 address from the range");
|
final String startIpv6 = _networkModel.getStartIpv6Address(guestNetwork.getId());
|
||||||
|
if (startIpv6 != null && _ipv6Dao.findByNetworkIdAndIp(guestNetwork.getId(), startIpv6) == null) {
|
||||||
|
defaultNetworkStartIpv6 = startIpv6;
|
||||||
|
} else if (s_logger.isDebugEnabled()) {
|
||||||
|
s_logger.debug("First ipv6 " + startIpv6 + " in network id=" + guestNetwork.getId()
|
||||||
|
+ " is already allocated, can't use it for domain router; will get random ipv6 address from the range");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2596,7 +2596,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
|
|||||||
|
|
||||||
// 2) Create network
|
// 2) Create network
|
||||||
final Network guestNetwork = _ntwkMgr.createGuestNetwork(ntwkOffId, name, displayText, gateway, cidr, vlanId, false, networkDomain, owner, domainId, pNtwk, zoneId, aclType,
|
final Network guestNetwork = _ntwkMgr.createGuestNetwork(ntwkOffId, name, displayText, gateway, cidr, vlanId, false, networkDomain, owner, domainId, pNtwk, zoneId, aclType,
|
||||||
subdomainAccess, vpcId, null, null, isDisplayNetworkEnabled, null, null, externalId);
|
subdomainAccess, vpcId, null, null, isDisplayNetworkEnabled, null, null, externalId, null, null);
|
||||||
|
|
||||||
if (guestNetwork != null) {
|
if (guestNetwork != null) {
|
||||||
guestNetwork.setNetworkACLId(aclId);
|
guestNetwork.setNetworkACLId(aclId);
|
||||||
|
|||||||
@ -3488,7 +3488,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");
|
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",
|
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, false, null, owner, null, physicalNetwork, zone.getId(), ACLType.Account, null, null, null, null, true, null, null,
|
||||||
null);
|
null, null, null);
|
||||||
if (newNetwork != null) {
|
if (newNetwork != null) {
|
||||||
defaultNetwork = _networkDao.findById(newNetwork.getId());
|
defaultNetwork = _networkDao.findById(newNetwork.getId());
|
||||||
}
|
}
|
||||||
@ -6775,7 +6775,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
Network newNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), newAccount.getAccountName() + "-network",
|
Network newNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), newAccount.getAccountName() + "-network",
|
||||||
newAccount.getAccountName() + "-network", null, null, null, false, null, newAccount,
|
newAccount.getAccountName() + "-network", null, null, null, false, null, newAccount,
|
||||||
null, physicalNetwork, zone.getId(), ACLType.Account, null, null,
|
null, physicalNetwork, zone.getId(), ACLType.Account, null, null,
|
||||||
null, null, true, null, null, null);
|
null, null, true, null, null, null, null, null);
|
||||||
// if the network offering has persistent set to true, implement the network
|
// if the network offering has persistent set to true, implement the network
|
||||||
if (requiredOfferings.get(0).isPersistent()) {
|
if (requiredOfferings.get(0).isPersistent()) {
|
||||||
DeployDestination dest = new DeployDestination(zone, null, null, null);
|
DeployDestination dest = new DeployDestination(zone, null, null, null);
|
||||||
|
|||||||
@ -123,7 +123,7 @@ public class CreatePrivateNetworkTest {
|
|||||||
ACLType.Account, false, 1L, false);
|
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),
|
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),
|
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))).thenReturn(net);
|
nullable(Boolean.class), nullable(String.class), nullable(Network.PVlanType.class), nullable(String.class), nullable(String.class), nullable(String.class))).thenReturn(net);
|
||||||
when(
|
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);
|
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);
|
||||||
|
|
||||||
|
|||||||
@ -646,7 +646,7 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkOrches
|
|||||||
@Override
|
@Override
|
||||||
public Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, boolean bypassVlanOverlapCheck, String networkDomain,
|
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,
|
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) throws ConcurrentOperationException, InsufficientCapacityException,
|
String cidrv6, Boolean displayNetworkEnabled, String isolatedPvlan, Network.PVlanType isolatedPvlanType, String externalId, String routerIp, String routerIpv6) throws ConcurrentOperationException, InsufficientCapacityException,
|
||||||
ResourceAllocationException {
|
ResourceAllocationException {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@ -23,7 +23,7 @@ from marvin.cloudstackTestCase import cloudstackTestCase
|
|||||||
from marvin.cloudstackException import CloudstackAPIException
|
from marvin.cloudstackException import CloudstackAPIException
|
||||||
from marvin.cloudstackAPI import rebootRouter
|
from marvin.cloudstackAPI import rebootRouter
|
||||||
from marvin.sshClient import SshClient
|
from marvin.sshClient import SshClient
|
||||||
from marvin.lib.utils import cleanup_resources, get_process_status
|
from marvin.lib.utils import cleanup_resources, get_process_status, get_host_credentials
|
||||||
from marvin.lib.base import (Account,
|
from marvin.lib.base import (Account,
|
||||||
VirtualMachine,
|
VirtualMachine,
|
||||||
ServiceOffering,
|
ServiceOffering,
|
||||||
@ -38,7 +38,9 @@ from marvin.lib.base import (Account,
|
|||||||
NIC,
|
NIC,
|
||||||
Cluster)
|
Cluster)
|
||||||
from marvin.lib.common import (get_domain,
|
from marvin.lib.common import (get_domain,
|
||||||
|
get_free_vlan,
|
||||||
get_zone,
|
get_zone,
|
||||||
|
get_template,
|
||||||
get_test_template,
|
get_test_template,
|
||||||
list_hosts,
|
list_hosts,
|
||||||
list_publicIP,
|
list_publicIP,
|
||||||
@ -54,6 +56,7 @@ from ddt import ddt, data
|
|||||||
# Import System modules
|
# Import System modules
|
||||||
import time
|
import time
|
||||||
import logging
|
import logging
|
||||||
|
import random
|
||||||
|
|
||||||
_multiprocess_shared_ = True
|
_multiprocess_shared_ = True
|
||||||
|
|
||||||
@ -1838,3 +1841,195 @@ class TestPrivateVlansL2Networks(cloudstackTestCase):
|
|||||||
self.fail("Failing test. Error: %s" % e)
|
self.fail("Failing test. Error: %s" % e)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
class TestSharedNetwork(cloudstackTestCase):
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
cls.testClient = super(TestSharedNetwork, cls).getClsTestClient()
|
||||||
|
cls.apiclient = cls.testClient.getApiClient()
|
||||||
|
|
||||||
|
cls.services = cls.testClient.getParsedTestDataConfig()
|
||||||
|
# Get Zone, Domain and templates
|
||||||
|
cls.domain = get_domain(cls.apiclient)
|
||||||
|
cls.zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests())
|
||||||
|
cls.template = get_template(cls.apiclient, cls.zone.id,
|
||||||
|
cls.services["ostype"])
|
||||||
|
|
||||||
|
cls.services["virtual_machine"]["zoneid"] = cls.zone.id
|
||||||
|
cls.services["virtual_machine"]["template"] = cls.template.id
|
||||||
|
# Create Network Offering
|
||||||
|
cls.services["shared_network_offering"]["specifyVlan"] = "True"
|
||||||
|
cls.services["shared_network_offering"]["specifyIpRanges"] = "True"
|
||||||
|
cls.shared_network_offering = NetworkOffering.create(cls.apiclient, cls.services["shared_network_offering"],
|
||||||
|
conservemode=False)
|
||||||
|
|
||||||
|
# Update network offering state from disabled to enabled.
|
||||||
|
NetworkOffering.update(cls.shared_network_offering, cls.apiclient, state="enabled")
|
||||||
|
|
||||||
|
cls.service_offering = ServiceOffering.create(cls.apiclient, cls.services["service_offering"])
|
||||||
|
physical_network, vlan = get_free_vlan(cls.apiclient, cls.zone.id)
|
||||||
|
# create network using the shared network offering created
|
||||||
|
|
||||||
|
cls.services["shared_network"]["acltype"] = "domain"
|
||||||
|
cls.services["shared_network"]["vlan"] = vlan
|
||||||
|
cls.services["shared_network"]["networkofferingid"] = cls.shared_network_offering.id
|
||||||
|
cls.services["shared_network"]["physicalnetworkid"] = physical_network.id
|
||||||
|
|
||||||
|
cls.setSharedNetworkParams("shared_network")
|
||||||
|
cls.shared_network = Network.create(cls.apiclient,
|
||||||
|
cls.services["shared_network"],
|
||||||
|
networkofferingid=cls.shared_network_offering.id,
|
||||||
|
zoneid=cls.zone.id)
|
||||||
|
cls._cleanup = [
|
||||||
|
cls.service_offering,
|
||||||
|
cls.shared_network_offering
|
||||||
|
]
|
||||||
|
return
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.apiclient = self.testClient.getApiClient()
|
||||||
|
self.dbclient = self.testClient.getDbConnection()
|
||||||
|
self.cleanup = []
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def tearDownClass(cls):
|
||||||
|
try:
|
||||||
|
# Cleanup resources used
|
||||||
|
cleanup_resources(cls.apiclient, cls._cleanup)
|
||||||
|
except Exception as e:
|
||||||
|
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||||
|
return
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
cleanup_resources(self.apiclient, self.cleanup)
|
||||||
|
return
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setSharedNetworkParams(cls, network, range=20):
|
||||||
|
|
||||||
|
# @range: range decides the endip. Pass the range as "x" if you want the difference between the startip
|
||||||
|
# and endip as "x"
|
||||||
|
# Set the subnet number of shared networks randomly prior to execution
|
||||||
|
# of each test case to avoid overlapping of ip addresses
|
||||||
|
shared_network_subnet_number = random.randrange(1, 254)
|
||||||
|
cls.services[network]["routerip"] = "172.16." + str(shared_network_subnet_number) + "." + str(15)
|
||||||
|
cls.services[network]["gateway"] = "172.16." + str(shared_network_subnet_number) + ".1"
|
||||||
|
cls.services[network]["startip"] = "172.16." + str(shared_network_subnet_number) + ".2"
|
||||||
|
cls.services[network]["endip"] = "172.16." + str(shared_network_subnet_number) + "." + str(range + 1)
|
||||||
|
cls.services[network]["netmask"] = "255.255.255.0"
|
||||||
|
logger.debug("Executing command '%s'" % cls.services[network])
|
||||||
|
|
||||||
|
def get_router_host(self, router):
|
||||||
|
self.assertEqual(
|
||||||
|
router.state,
|
||||||
|
'Running',
|
||||||
|
"Check list router response for router state"
|
||||||
|
)
|
||||||
|
hosts = list_hosts(
|
||||||
|
self.apiclient,
|
||||||
|
id=router.hostid)
|
||||||
|
self.assertEqual(
|
||||||
|
isinstance(hosts, list),
|
||||||
|
True,
|
||||||
|
"Check for list hosts response return valid data")
|
||||||
|
host = hosts[0]
|
||||||
|
if host.hypervisor.lower() in ("vmware", "hyperv"):
|
||||||
|
host.ipaddress = self.apiclient.connection.mgtSvr
|
||||||
|
host.user = self.apiclient.connection.user
|
||||||
|
host.password = self.apiclient.connection.passwd
|
||||||
|
host.port = 22
|
||||||
|
else:
|
||||||
|
host.user, host.password = get_host_credentials(self.config, host.ipaddress)
|
||||||
|
host.port = 22
|
||||||
|
return host
|
||||||
|
|
||||||
|
def verify_ip_address_in_router(self, router, host, ipaddress, device, isExist=True):
|
||||||
|
command = 'ip addr show %s |grep "inet "|cut -d " " -f6 |cut -d "/" -f1 |grep -w %s' % (device, ipaddress)
|
||||||
|
logger.debug("Executing command '%s'" % command)
|
||||||
|
result = get_process_status(
|
||||||
|
host.ipaddress,
|
||||||
|
host.port,
|
||||||
|
host.user,
|
||||||
|
host.password,
|
||||||
|
router.linklocalip,
|
||||||
|
command,
|
||||||
|
host.hypervisor.lower())
|
||||||
|
self.assertEqual(len(result) > 0 and result[0] == ipaddress, isExist, "ip %s verification failed" % ipaddress)
|
||||||
|
|
||||||
|
@attr(tags=["advanced", "shared"])
|
||||||
|
def test_01_deployVMInSharedNetwork(self):
|
||||||
|
try:
|
||||||
|
self.virtual_machine = VirtualMachine.create(self.apiclient, self.services["virtual_machine"],
|
||||||
|
networkids=[self.shared_network.id],
|
||||||
|
serviceofferingid=self.service_offering.id
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
self.fail("Exception while deploying virtual machine: %s" % e)
|
||||||
|
|
||||||
|
routerIp = self.services["shared_network"]["routerip"]
|
||||||
|
nic_ip_address = self.dbclient.execute(
|
||||||
|
"select ip4_address from nics where strategy='Placeholder' and ip4_address = '%s';" % routerIp);
|
||||||
|
|
||||||
|
self.assertNotEqual(
|
||||||
|
len(nic_ip_address),
|
||||||
|
0,
|
||||||
|
"Placeholder ip for the VR in shared network isn't the same as what was passed"
|
||||||
|
)
|
||||||
|
|
||||||
|
routers = Router.list(
|
||||||
|
self.apiclient,
|
||||||
|
networkid=self.shared_network.id,
|
||||||
|
listall=True
|
||||||
|
)
|
||||||
|
|
||||||
|
for router in routers:
|
||||||
|
host = self.get_router_host(router)
|
||||||
|
self.verify_ip_address_in_router(router, host, routerIp, "eth0", True)
|
||||||
|
|
||||||
|
# expunge VM
|
||||||
|
VirtualMachine.delete(self.virtual_machine, self.apiclient, expunge=True)
|
||||||
|
|
||||||
|
@attr(tags=["advanced", "shared"])
|
||||||
|
def test_02_verifyRouterIpAfterNetworkRestart(self):
|
||||||
|
routerIp = self.services["shared_network"]["routerip"]
|
||||||
|
self.debug("restarting network with cleanup")
|
||||||
|
try:
|
||||||
|
self.shared_network.restart(self.apiclient, cleanup=True)
|
||||||
|
except Exception as e:
|
||||||
|
self.fail("Failed to cleanup network - %s" % e)
|
||||||
|
|
||||||
|
self.debug("Listing routers for network: %s" % self.shared_network.name)
|
||||||
|
routers = Router.list(
|
||||||
|
self.apiclient,
|
||||||
|
networkid=self.shared_network.id,
|
||||||
|
listall=True
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
len(routers),
|
||||||
|
1,
|
||||||
|
"Router for the shared network wasn't found)"
|
||||||
|
)
|
||||||
|
|
||||||
|
for router in routers:
|
||||||
|
host = self.get_router_host(router)
|
||||||
|
self.verify_ip_address_in_router(router, host, routerIp, "eth0", True)
|
||||||
|
|
||||||
|
@attr(tags=["advanced", "shared"])
|
||||||
|
def test_03_destroySharedNetwork(self):
|
||||||
|
routerIp = self.services["shared_network"]["routerip"]
|
||||||
|
try:
|
||||||
|
self.shared_network.delete(self.apiclient)
|
||||||
|
except Exception as e:
|
||||||
|
self.fail("Failed to destroy the shared network")
|
||||||
|
|
||||||
|
self.debug("Fetch the placeholder record for the router")
|
||||||
|
nic_ip_address = self.dbclient.execute(
|
||||||
|
"select ip4_address from nics where strategy='Placeholder' and ip4_address = '%s' and removed is NOT NULL;" % routerIp);
|
||||||
|
|
||||||
|
self.assertNotEqual(
|
||||||
|
len(nic_ip_address),
|
||||||
|
0,
|
||||||
|
"Failed to find the placeholder IP"
|
||||||
|
)
|
||||||
@ -3158,6 +3158,18 @@ class Network:
|
|||||||
cmd.isolatedpvlan = services["isolatedpvlan"]
|
cmd.isolatedpvlan = services["isolatedpvlan"]
|
||||||
if "isolatedpvlantype" in services:
|
if "isolatedpvlantype" in services:
|
||||||
cmd.isolatedpvlantype = services["isolatedpvlantype"]
|
cmd.isolatedpvlantype = services["isolatedpvlantype"]
|
||||||
|
if "routerip" in services:
|
||||||
|
cmd.routerip = services["routerip"]
|
||||||
|
if "ip6gateway" in services:
|
||||||
|
cmd.ip6gateway = services["ip6gateway"]
|
||||||
|
if "ip6cidr" in services:
|
||||||
|
cmd.ip6cidr = services["ip6cidr"]
|
||||||
|
if "startipv6" in services:
|
||||||
|
cmd.startipv6 = services["startipv6"]
|
||||||
|
if "endipv6" in services:
|
||||||
|
cmd.endipv6 = services["endipv6"]
|
||||||
|
if "routeripv6" in services:
|
||||||
|
cmd.routeripv6 = services["routeripv6"]
|
||||||
|
|
||||||
if accountid:
|
if accountid:
|
||||||
cmd.account = accountid
|
cmd.account = accountid
|
||||||
|
|||||||
@ -1815,6 +1815,8 @@
|
|||||||
"label.root.disk.size": "Root disk size (GB)",
|
"label.root.disk.size": "Root disk size (GB)",
|
||||||
"label.rootdiskcontrollertype": "Root disk controller",
|
"label.rootdiskcontrollertype": "Root disk controller",
|
||||||
"label.rootdiskcontrollertypekvm": "Root disk controller",
|
"label.rootdiskcontrollertypekvm": "Root disk controller",
|
||||||
|
"label.routerip": "IPv4 address for Router in Shared Network",
|
||||||
|
"label.routeripv6": "IPv6 address for Router in Shared Network",
|
||||||
"label.router.health.check.last.updated": "Last updated",
|
"label.router.health.check.last.updated": "Last updated",
|
||||||
"label.router.health.check.name": "Check name",
|
"label.router.health.check.name": "Check name",
|
||||||
"label.router.health.check.success": "Success",
|
"label.router.health.check.success": "Success",
|
||||||
|
|||||||
@ -332,6 +332,17 @@
|
|||||||
v-decorator="['endipv4', {}]"
|
v-decorator="['endipv4', {}]"
|
||||||
:placeholder="this.$t('label.endipv4')"/>
|
:placeholder="this.$t('label.endipv4')"/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
<a-form-item v-if="isVirtualRouterForAtLeastOneService">
|
||||||
|
<span slot="label">
|
||||||
|
{{ $t('label.routerip') }}
|
||||||
|
<a-tooltip :title="apiParams.routerip.description" v-if="'routerip' in apiParams">
|
||||||
|
<a-icon type="info-circle" style="color: rgba(0,0,0,.45)" />
|
||||||
|
</a-tooltip>
|
||||||
|
</span>
|
||||||
|
<a-input
|
||||||
|
v-decorator="['routerip', {}]"
|
||||||
|
:placeholder="this.$t('label.routerip')"/>
|
||||||
|
</a-form-item>
|
||||||
<a-form-item>
|
<a-form-item>
|
||||||
<span slot="label">
|
<span slot="label">
|
||||||
{{ $t('label.ip6gateway') }}
|
{{ $t('label.ip6gateway') }}
|
||||||
@ -376,6 +387,17 @@
|
|||||||
v-decorator="['endipv6', {}]"
|
v-decorator="['endipv6', {}]"
|
||||||
:placeholder="this.$t('label.endipv6')"/>
|
:placeholder="this.$t('label.endipv6')"/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
<a-form-item v-if="isVirtualRouterForAtLeastOneService">
|
||||||
|
<span slot="label">
|
||||||
|
{{ $t('label.routeripv6') }}
|
||||||
|
<a-tooltip :title="apiParams.routeripv6.description" v-if="'routeripv6' in apiParams">
|
||||||
|
<a-icon type="info-circle" style="color: rgba(0,0,0,.45)" />
|
||||||
|
</a-tooltip>
|
||||||
|
</span>
|
||||||
|
<a-input
|
||||||
|
v-decorator="['routeripv6', {}]"
|
||||||
|
:placeholder="this.$t('label.routeripv6')"/>
|
||||||
|
</a-form-item>
|
||||||
<a-form-item>
|
<a-form-item>
|
||||||
<span slot="label">
|
<span slot="label">
|
||||||
{{ $t('label.networkdomain') }}
|
{{ $t('label.networkdomain') }}
|
||||||
@ -457,7 +479,9 @@ export default {
|
|||||||
selectedNetworkOffering: {},
|
selectedNetworkOffering: {},
|
||||||
projects: [],
|
projects: [],
|
||||||
projectLoading: false,
|
projectLoading: false,
|
||||||
selectedProject: {}
|
selectedProject: {},
|
||||||
|
isVirtualRouterForAtLeastOneService: false,
|
||||||
|
selectedServiceProviderMap: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
@ -654,6 +678,7 @@ export default {
|
|||||||
this.networkOfferings = []
|
this.networkOfferings = []
|
||||||
api('listNetworkOfferings', params).then(json => {
|
api('listNetworkOfferings', params).then(json => {
|
||||||
this.networkOfferings = json.listnetworkofferingsresponse.networkoffering
|
this.networkOfferings = json.listnetworkofferingsresponse.networkoffering
|
||||||
|
this.handleNetworkOfferingChange(this.networkOfferings[0])
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
this.$notifyError(error)
|
this.$notifyError(error)
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
@ -662,7 +687,6 @@ export default {
|
|||||||
this.form.setFieldsValue({
|
this.form.setFieldsValue({
|
||||||
networkofferingid: 0
|
networkofferingid: 0
|
||||||
})
|
})
|
||||||
this.handleNetworkOfferingChange(this.networkOfferings[0])
|
|
||||||
} else {
|
} else {
|
||||||
this.form.setFieldsValue({
|
this.form.setFieldsValue({
|
||||||
networkofferingid: null
|
networkofferingid: null
|
||||||
@ -672,6 +696,27 @@ export default {
|
|||||||
},
|
},
|
||||||
handleNetworkOfferingChange (networkOffering) {
|
handleNetworkOfferingChange (networkOffering) {
|
||||||
this.selectedNetworkOffering = networkOffering
|
this.selectedNetworkOffering = networkOffering
|
||||||
|
if (networkOffering) {
|
||||||
|
this.networkServiceProviderMap(this.selectedNetworkOffering.id)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
networkServiceProviderMap (id) {
|
||||||
|
api('listNetworkOfferings', { id: id }).then(json => {
|
||||||
|
var networkOffering = json.listnetworkofferingsresponse.networkoffering[0]
|
||||||
|
const services = networkOffering.service
|
||||||
|
this.selectedServiceProviderMap = {}
|
||||||
|
for (const svc of services) {
|
||||||
|
this.selectedServiceProviderMap[svc.name] = svc.provider[0].name
|
||||||
|
}
|
||||||
|
var providers = Object.values(this.selectedServiceProviderMap)
|
||||||
|
this.isVirtualRouterForAtLeastOneService = false
|
||||||
|
var self = this
|
||||||
|
providers.forEach(function (prvdr, idx) {
|
||||||
|
if (prvdr === 'VirtualRouter') {
|
||||||
|
self.isVirtualRouterForAtLeastOneService = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
},
|
},
|
||||||
fetchDomainData () {
|
fetchDomainData () {
|
||||||
const params = {}
|
const params = {}
|
||||||
@ -791,6 +836,9 @@ export default {
|
|||||||
if (this.isValidTextValueForKey(values, 'ip4gateway')) {
|
if (this.isValidTextValueForKey(values, 'ip4gateway')) {
|
||||||
params.ip6gateway = values.ip6gateway
|
params.ip6gateway = values.ip6gateway
|
||||||
}
|
}
|
||||||
|
if (this.isValidTextValueForKey(values, 'routerip')) {
|
||||||
|
params.routerip = values.routerip
|
||||||
|
}
|
||||||
if (this.isValidTextValueForKey(values, 'ip6cidr')) {
|
if (this.isValidTextValueForKey(values, 'ip6cidr')) {
|
||||||
params.ip6cidr = values.ip6cidr
|
params.ip6cidr = values.ip6cidr
|
||||||
}
|
}
|
||||||
@ -800,6 +848,9 @@ export default {
|
|||||||
if (this.isValidTextValueForKey(values, 'endipv6')) {
|
if (this.isValidTextValueForKey(values, 'endipv6')) {
|
||||||
params.endipv6 = values.endipv6
|
params.endipv6 = values.endipv6
|
||||||
}
|
}
|
||||||
|
if (this.isValidTextValueForKey(values, 'routeripv6')) {
|
||||||
|
params.routeripv6 = values.routeripv6
|
||||||
|
}
|
||||||
// IPv6 (end)
|
// IPv6 (end)
|
||||||
|
|
||||||
if (this.isValidTextValueForKey(values, 'networkdomain')) {
|
if (this.isValidTextValueForKey(values, 'networkdomain')) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user