Configurable MTU for VR (#6426)

Co-authored-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
This commit is contained in:
Pearl Dsilva 2023-01-04 03:42:24 -05:00 committed by GitHub
parent 4d76054377
commit 3044d63a8b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
85 changed files with 3353 additions and 185 deletions

View File

@ -39,10 +39,12 @@ public class IpAddressTO {
private boolean newNic;
private boolean isPrivateGateway;
private NicTO nicTO;
private Integer mtu;
Map<String, String> details;
public IpAddressTO(long accountId, String ipAddress, boolean add, boolean firstIP, boolean sourceNat, String broadcastUri, String vlanGateway, String vlanNetmask,
String vifMacAddress, Integer networkRate, boolean isOneToOneNat) {
String vifMacAddress, Integer networkRate, boolean isOneToOneNat) {
this.accountId = accountId;
this.publicIp = ipAddress;
this.add = add;
@ -56,6 +58,12 @@ public class IpAddressTO {
this.oneToOneNat = isOneToOneNat;
}
public IpAddressTO(String ipAddress, Integer mtu, String vlanNetmask ) {
this.publicIp = ipAddress;
this.mtu = mtu;
this.vlanNetmask = vlanNetmask;
}
protected IpAddressTO() {
}
@ -155,6 +163,14 @@ public class IpAddressTO {
this.nicTO = nicTO;
}
public Integer getMtu() {
return mtu;
}
public void setMtu(Integer mtu) {
this.mtu = mtu;
}
public Map<String, String> getDetails() {
return details;

View File

@ -31,6 +31,7 @@ public class NicTO extends NetworkTO {
List<String> nicSecIps;
Map<NetworkOffering.Detail, String> details;
boolean dpdkEnabled;
Integer mtu;
public NicTO() {
super();
@ -118,4 +119,12 @@ public class NicTO extends NetworkTO {
public void setDpdkEnabled(boolean dpdkEnabled) {
this.dpdkEnabled = dpdkEnabled;
}
public Integer getMtu() {
return mtu;
}
public void setMtu(Integer mtu) {
this.mtu = mtu;
}
}

View File

@ -493,4 +493,8 @@ public interface Network extends ControlledEntity, StateObject<Network.State>, I
String getIp6Dns2();
Date getCreated();
Integer getPublicMtu();
Integer getPrivateMtu();
}

View File

@ -22,8 +22,10 @@ import java.util.Date;
import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.Networks.Mode;
import com.cloud.network.Networks.TrafficType;
import org.apache.log4j.Logger;
public class NetworkProfile implements Network {
static final Logger s_logger = Logger.getLogger(NetworkProfile.class);
private final long id;
private final String uuid;
private final long dataCenterId;
@ -357,4 +359,14 @@ public class NetworkProfile implements Network {
return null;
}
@Override
public Integer getPublicMtu() {
return null;
}
@Override
public Integer getPrivateMtu() {
return null;
}
}

View File

@ -34,6 +34,7 @@ import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd;
import org.apache.cloudstack.api.command.user.network.UpdateNetworkCmd;
import org.apache.cloudstack.api.command.user.vm.ListNicsCmd;
import org.apache.cloudstack.api.response.AcquirePodIpCmdResponse;
import org.apache.cloudstack.framework.config.ConfigKey;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientAddressCapacityException;
@ -59,6 +60,21 @@ import com.cloud.vm.NicSecondaryIp;
*/
public interface NetworkService {
public static final Integer DEFAULT_MTU = 1500;
public static final Integer MINIMUM_MTU = 68;
public static final ConfigKey<Integer> VRPublicInterfaceMtu = new ConfigKey<>("VirtualRouter", Integer.class,
"vr.public.interface.max.mtu", "1500", "The maximum value the MTU can have on the VR's public interfaces",
true, ConfigKey.Scope.Zone);
public static final ConfigKey<Integer> VRPrivateInterfaceMtu = new ConfigKey<>("VirtualRouter", Integer.class,
"vr.private.interface.max.mtu", "1500", "The maximum value the MTU can have on the VR's private interfaces",
true, ConfigKey.Scope.Zone);
public static final ConfigKey<Boolean> AllowUsersToSpecifyVRMtu = new ConfigKey<>("Advanced", Boolean.class,
"allow.end.users.to.specify.vr.mtu", "false", "Allow end users to specify VR MTU",
true, ConfigKey.Scope.Zone);
List<? extends Network> getIsolatedNetworksOwnedByAccountInZone(long zoneId, Account owner);
IpAddress allocateIP(Account ipOwner, long zoneId, Long networkId, Boolean displayIp, String ipaddress) throws ResourceAllocationException, InsufficientAddressCapacityException,

View File

@ -96,6 +96,8 @@ public interface Vpc extends ControlledEntity, Identity, InternalIdentity {
Date getCreated();
Integer getPublicMtu();
String getIp4Dns1();
String getIp4Dns2();

View File

@ -53,7 +53,7 @@ public interface VpcService {
* @throws ResourceAllocationException TODO
*/
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)
String dns1, String dns2, String ip6Dns1, String ip6Dns2, Boolean displayVpc, Integer publicMtu)
throws ResourceAllocationException;
/**
@ -73,11 +73,12 @@ public interface VpcService {
* @param vpcId
* @param vpcName
* @param displayText
* @param customId TODO
* @param displayVpc TODO
* @param customId TODO
* @param displayVpc TODO
* @param mtu
* @return
*/
public Vpc updateVpc(long vpcId, String vpcName, String displayText, String customId, Boolean displayVpc);
public Vpc updateVpc(long vpcId, String vpcName, String displayText, String customId, Boolean displayVpc, Integer mtu);
/**
* Lists VPC(s) based on the parameters passed to the method call

View File

@ -160,4 +160,6 @@ public interface Nic extends Identity, InternalIdentity {
String getIPv6Cidr();
String getIPv6Address();
Integer getMtu();
}

View File

@ -70,6 +70,7 @@ public class NicProfile implements InternalIdentity, Serializable {
String iPv6Dns1;
String iPv6Dns2;
String requestedIPv6;
Integer mtu;
//
// CONSTRUCTORS
@ -396,6 +397,15 @@ public class NicProfile implements InternalIdentity, Serializable {
this.orderIndex = orderIndex;
}
public Integer getMtu() {
return mtu;
}
public void setMtu(Integer mtu) {
this.mtu = mtu;
}
//
// OTHER METHODS
//
@ -426,6 +436,7 @@ public class NicProfile implements InternalIdentity, Serializable {
isolationUri = null;
orderIndex = null;
mtu = null;
}

View File

@ -71,6 +71,8 @@ public interface AlertService {
public static final AlertType ALERT_TYPE_HA_ACTION = new AlertType((short)30, "ALERT.HA.ACTION", true);
public static final AlertType ALERT_TYPE_CA_CERT = new AlertType((short)31, "ALERT.CA.CERT", true);
public static final AlertType ALERT_TYPE_VM_SNAPSHOT = new AlertType((short)32, "ALERT.VM.SNAPSHOT", true);
public static final AlertType ALERT_TYPE_VR_PUBLIC_IFACE_MTU = new AlertType((short)32, "ALERT.VR.PUBLIC.IFACE.MTU", true);
public static final AlertType ALERT_TYPE_VR_PRIVATE_IFACE_MTU = new AlertType((short)32, "ALERT.VR.PRIVATE.IFACE.MTU", true);
public short getType() {
return type;

View File

@ -618,6 +618,7 @@ public class ApiConstants {
public static final String RESTART_REQUIRED = "restartrequired";
public static final String ALLOW_USER_CREATE_PROJECTS = "allowusercreateprojects";
public static final String ALLOW_USER_DRIVEN_BACKUPS = "allowuserdrivenbackups";
public static final String ALLOW_USER_SPECIFY_VR_MTU = "allowuserspecifyvrmtu";
public static final String CONSERVE_MODE = "conservemode";
public static final String TRAFFIC_TYPE_IMPLEMENTOR = "traffictypeimplementor";
public static final String KEYWORD = "keyword";
@ -882,6 +883,8 @@ public class ApiConstants {
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 ROUTER_PRIVATE_INTERFACE_MAX_MTU = "routerprivateinterfacemaxmtu";
public static final String ROUTER_PUBLIC_INTERFACE_MAX_MTU = "routerpublicinterfacemaxmtu";
public static final String LAST_UPDATED = "lastupdated";
public static final String PERFORM_FRESH_CHECKS = "performfreshchecks";
public static final String CACHE_MODE = "cachemode";
@ -920,6 +923,7 @@ public class ApiConstants {
public static final String DYNAMIC_SCALING_ENABLED = "dynamicscalingenabled";
public static final String POOL_TYPE = "pooltype";
public static final String REDUNDANT_STATE = "redundantstate";
public static final String ADMINS_ONLY = "adminsonly";
public static final String ANNOTATION_FILTER = "annotationfilter";
@ -927,6 +931,9 @@ public class ApiConstants {
public static final String LOGOUT = "logout";
public static final String LIST_IDPS = "listIdps";
public static final String PUBLIC_MTU = "publicmtu";
public static final String PRIVATE_MTU = "privatemtu";
public static final String MTU = "mtu";
public enum BootType {
UEFI, BIOS;

View File

@ -16,6 +16,7 @@
// under the License.
package org.apache.cloudstack.api.command.user.network;
import com.cloud.network.NetworkService;
import org.apache.log4j.Logger;
import org.apache.cloudstack.acl.RoleType;
@ -157,6 +158,14 @@ 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.PUBLIC_MTU, type = CommandType.INTEGER,
description = "MTU to be configured on the network VR's public facing interfaces", since = "4.18.0")
private Integer publicMtu;
@Parameter(name = ApiConstants.PRIVATE_MTU, type = CommandType.INTEGER,
description = "MTU to be configured on the network VR's private interface(s)", since = "4.18.0")
private Integer privateMtu;
@Parameter(name = ApiConstants.DNS1, type = CommandType.STRING, description = "the first IPv4 DNS for the network", since = "4.18.0")
private String ip4Dns1;
@ -338,6 +347,13 @@ public class CreateNetworkCmd extends BaseCmd implements UserCmd {
return aclId;
}
public Integer getPublicMtu() {
return publicMtu != null ? publicMtu : NetworkService.DEFAULT_MTU;
}
public Integer getPrivateMtu() {
return privateMtu != null ? privateMtu : NetworkService.DEFAULT_MTU;
}
public String getIp4Dns1() {
return ip4Dns1;
}

View File

@ -78,12 +78,20 @@ public class UpdateNetworkCmd extends BaseAsyncCustomIdCmd implements UserCmd {
@Parameter(name = ApiConstants.DISPLAY_NETWORK,
type = CommandType.BOOLEAN,
description = "an optional field, whether to the display the network to the end user or not.", authorized = {RoleType.Admin})
description = "an optional field, whether to the display the network to the end user or not.", authorized = {RoleType.Admin})
private Boolean displayNetwork;
@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.PUBLIC_MTU, type = CommandType.INTEGER,
description = "MTU to be configured on the network VR's public facing interfaces", since = "4.18.0")
private Integer publicMtu;
@Parameter(name = ApiConstants.PRIVATE_MTU, type = CommandType.INTEGER,
description = "MTU to be configured on the network VR's public facing interfaces", since = "4.18.0")
private Integer privateMtu;
@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;
@ -149,6 +157,14 @@ public class UpdateNetworkCmd extends BaseAsyncCustomIdCmd implements UserCmd {
return forced;
}
public Integer getPublicMtu() {
return publicMtu;
}
public Integer getPrivateMtu() {
return privateMtu;
}
public String getIp4Dns1() {
return ip4Dns1;
}

View File

@ -16,6 +16,7 @@
// under the License.
package org.apache.cloudstack.api.command.user.vpc;
import com.cloud.network.NetworkService;
import org.apache.log4j.Logger;
import org.apache.cloudstack.acl.RoleType;
@ -95,6 +96,10 @@ 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.PUBLIC_MTU, type = CommandType.INTEGER,
description = "MTU to be configured on the network VR's public facing interfaces", since = "4.18.0")
private Integer publicMtu;
@Parameter(name = ApiConstants.DNS1, type = CommandType.STRING, description = "the first IPv4 DNS for the VPC", since = "4.18.0")
private String ip4Dns1;
@ -143,6 +148,10 @@ public class CreateVPCCmd extends BaseAsyncCreateCmd implements UserCmd {
return networkDomain;
}
public Integer getPublicMtu() {
return publicMtu != null ? publicMtu : NetworkService.DEFAULT_MTU;
}
public String getIp4Dns1() {
return ip4Dns1;
}

View File

@ -59,6 +59,10 @@ public class UpdateVPCCmd extends BaseAsyncCustomIdCmd 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.PUBLIC_MTU, type = CommandType.INTEGER,
description = "MTU to be configured on the network VR's public facing interfaces", since = "4.18.0")
private Integer publicMtu;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@ -79,6 +83,10 @@ public class UpdateVPCCmd extends BaseAsyncCustomIdCmd implements UserCmd {
return display;
}
public Integer getPublicMtu() {
return publicMtu;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@ -99,7 +107,7 @@ public class UpdateVPCCmd extends BaseAsyncCustomIdCmd implements UserCmd {
@Override
public void execute() {
Vpc result = _vpcService.updateVpc(getId(), getVpcName(), getDisplayText(), getCustomId(), isDisplayVpc());
Vpc result = _vpcService.updateVpc(getId(), getVpcName(), getDisplayText(), getCustomId(), isDisplayVpc(), getPublicMtu());
if (result != null) {
VpcResponse response = _responseGenerator.createVpcResponse(getResponseView(), result);
response.setResponseName(getCommandName());

View File

@ -291,6 +291,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.PUBLIC_MTU)
@Param(description = "MTU configured on the network VR's public facing interfaces")
private Integer publicMtu;
@SerializedName(ApiConstants.PRIVATE_MTU)
@Param(description = "MTU configured on the network VR's private interfaces")
private Integer privateMtu;
@SerializedName(ApiConstants.IP6_DNS1)
@Param(description = "the first IPv6 DNS for the network", since = "4.18.0")
private String ipv6Dns1;
@ -607,6 +615,22 @@ public class NetworkResponse extends BaseResponseWithAssociatedNetwork implement
this.ipv6Routes.add(ipv6Route);
}
public Integer getPublicMtu() {
return publicMtu;
}
public void setPublicMtu(Integer publicMtu) {
this.publicMtu = publicMtu;
}
public Integer getPrivateMtu() {
return privateMtu;
}
public void setPrivateMtu(Integer privateMtu) {
this.privateMtu = privateMtu;
}
public void setIpv6Dns1(String ipv6Dns1) {
this.ipv6Dns1 = ipv6Dns1;
}

View File

@ -134,6 +134,10 @@ public class NicResponse extends BaseResponse {
@Param(description = "IP addresses associated with NIC found for unmanaged VM", since="4.14.0")
private List<String> ipAddresses;
@SerializedName(ApiConstants.MTU)
@Param(description = "MTU configured on the NIC", since="4.18.0")
private Integer mtu;
public void setVmId(String vmId) {
this.vmId = vmId;
}
@ -373,8 +377,8 @@ public class NicResponse extends BaseResponse {
this.ipAddresses = ipAddresses;
}
public String getVpcId() {
return vpcId;
public Integer getMtu() {
return mtu;
}
public void setVpcId(String vpcId) {
@ -388,4 +392,12 @@ public class NicResponse extends BaseResponse {
public void setVpcName(String vpcName) {
this.vpcName = vpcName;
}
public void setMtu(Integer mtu) {
this.mtu = mtu;
}
public String getVpcId() {
return vpcId;
}
}

View File

@ -136,6 +136,10 @@ 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.PUBLIC_MTU)
@Param(description = "MTU configured on the public interfaces of the VPC VR", since = "4.18.0")
private Integer publicMtu;
@SerializedName(ApiConstants.DNS1)
@Param(description = "the first IPv4 DNS for the VPC")
private String dns1;
@ -274,6 +278,10 @@ public class VpcResponse extends BaseResponseWithAnnotations implements Controll
return ipv6Routes;
}
public void setPublicMtu(Integer publicMtu) {
this.publicMtu = publicMtu;
}
public void setDns1(String dns1) {
this.dns1 = dns1;
}

View File

@ -129,6 +129,18 @@ public class ZoneResponse extends BaseResponseWithAnnotations implements SetReso
@Param(description = "Base64 string representation of the resource icon", since = "4.16.0.0")
ResourceIconResponse resourceIconResponse;
@SerializedName(ApiConstants.ALLOW_USER_SPECIFY_VR_MTU)
@Param(description = "Allow end users to specify VR MTU", since = "4.18.0")
private boolean allowUserSpecifyVRMtu;
@SerializedName(ApiConstants.ROUTER_PRIVATE_INTERFACE_MAX_MTU)
@Param(description = "The maximum value the MTU can have on the VR's private interfaces", since = "4.18.0")
private Integer routerPrivateInterfaceMaxMtu;
@SerializedName(ApiConstants.ROUTER_PUBLIC_INTERFACE_MAX_MTU)
@Param(description = "The maximum value the MTU can have on the VR's public interfaces", since = "4.18.0")
private Integer routerPublicInterfaceMaxMtu;
public ZoneResponse() {
tags = new LinkedHashSet<ResourceTagResponse>();
}
@ -328,4 +340,16 @@ public class ZoneResponse extends BaseResponseWithAnnotations implements SetReso
public ResourceIconResponse getResourceIconResponse() {
return resourceIconResponse;
}
public void setAllowUserSpecifyVRMtu(boolean allowUserSpecifyVRMtu) {
this.allowUserSpecifyVRMtu = allowUserSpecifyVRMtu;
}
public void setRouterPrivateInterfaceMaxMtu(Integer routerPrivateInterfaceMaxMtu) {
this.routerPrivateInterfaceMaxMtu = routerPrivateInterfaceMaxMtu;
}
public void setRouterPublicInterfaceMaxMtu(Integer routerPublicInterfaceMaxMtu) {
this.routerPublicInterfaceMaxMtu = routerPublicInterfaceMaxMtu;
}
}

View File

@ -0,0 +1,298 @@
// 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 org.apache.cloudstack.api.command.user.network;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.network.Network;
import com.cloud.network.NetworkService;
import com.cloud.offering.NetworkOffering;
import com.cloud.utils.db.EntityManager;
import junit.framework.TestCase;
import org.apache.cloudstack.api.ResponseGenerator;
import org.apache.cloudstack.api.ResponseObject;
import org.apache.cloudstack.api.response.NetworkResponse;
import org.junit.Assert;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.powermock.modules.junit4.PowerMockRunner;
import org.springframework.test.util.ReflectionTestUtils;
@RunWith(PowerMockRunner.class)
public class CreateNetworkCmdTest extends TestCase {
@Mock
public EntityManager _entityMgr;
@Mock
public NetworkService networkService;
private ResponseGenerator responseGenerator;
@InjectMocks
CreateNetworkCmd cmd = new CreateNetworkCmd();
public void testGetNetworkOfferingId() {
Long networkOfferingId = 1L;
ReflectionTestUtils.setField(cmd, "networkOfferingId", networkOfferingId);
Assert.assertEquals(cmd.getNetworkOfferingId(), networkOfferingId);
}
public void testGetGateway() {
String gateway = "10.10.10.1";
ReflectionTestUtils.setField(cmd, "gateway", gateway);
Assert.assertEquals(cmd.getGateway(), gateway);
}
public void testGetIsolatedPvlan() {
String isolatedPvlan = "1234";
ReflectionTestUtils.setField(cmd, "isolatedPvlan", isolatedPvlan);
Assert.assertEquals(cmd.getIsolatedPvlan(), isolatedPvlan);
}
public void testGetAccountName() {
String accountName = "admin";
ReflectionTestUtils.setField(cmd, "accountName", accountName);
Assert.assertEquals(cmd.getAccountName(), accountName);
}
public void testGetDomainId() {
Long domainId = 1L;
ReflectionTestUtils.setField(cmd, "domainId", domainId);
Assert.assertEquals(cmd.getDomainId(), domainId);
}
public void testGetNetmask() {
String netmask = "255.255.255.0";
ReflectionTestUtils.setField(cmd, "netmask", netmask);
Assert.assertEquals(cmd.getNetmask(), netmask);
}
public void testGetStartIp() {
String startIp = "10.10.10.2";
ReflectionTestUtils.setField(cmd, "startIp", startIp);
Assert.assertEquals(cmd.getStartIp(), startIp);
}
public void testGetEndIp() {
String endIp = "10.10.10.10";
ReflectionTestUtils.setField(cmd, "endIp", endIp);
Assert.assertEquals(cmd.getEndIp(), endIp);
}
public void testGetNetworkName() {
String netName = "net-isolated";
ReflectionTestUtils.setField(cmd, "name", netName);
Assert.assertEquals(cmd.getNetworkName(), netName);
}
public void testGetDisplayText() {
String description = "Isolated Network";
ReflectionTestUtils.setField(cmd, "displayText", description);
Assert.assertEquals(cmd.getDisplayText(), description);
}
public void testGetNetworkDomain() {
String netDomain = "cs1cloud.internal";
ReflectionTestUtils.setField(cmd, "networkDomain", netDomain);
Assert.assertEquals(cmd.getNetworkDomain(), netDomain);
}
public void testGetProjectId() {
Long projectId = 1L;
ReflectionTestUtils.setField(cmd, "projectId", projectId);
Assert.assertEquals(cmd.getProjectId(), projectId);
}
public void testGetAclType() {
String aclType = "account";
ReflectionTestUtils.setField(cmd, "aclType", aclType);
Assert.assertEquals(cmd.getAclType(), aclType);
}
public void testGetSubdomainAccess() {
Boolean subDomAccess = false;
ReflectionTestUtils.setField(cmd, "subdomainAccess", subDomAccess);
Assert.assertEquals(cmd.getSubdomainAccess(), subDomAccess);
}
public void testGetVpcId() {
Long vpcId = 1L;
ReflectionTestUtils.setField(cmd, "vpcId", vpcId);
Assert.assertEquals(cmd.getVpcId(), vpcId);
}
public void testGetDisplayNetwork() {
Boolean displayNet = true;
ReflectionTestUtils.setField(cmd, "displayNetwork", displayNet);
Assert.assertEquals(cmd.getDisplayNetwork(), displayNet);
}
public void testGetExternalId() {
String externalId = "1";
ReflectionTestUtils.setField(cmd, "externalId", externalId);
Assert.assertEquals(cmd.getExternalId(), externalId);
}
public void testGetAssociatedNetworkId() {
Long associatedNetId = 1L;
ReflectionTestUtils.setField(cmd, "associatedNetworkId", associatedNetId);
Assert.assertEquals(cmd.getAssociatedNetworkId(), associatedNetId);
}
public void testIsDisplayNullDefaultsToTrue() {
Boolean displayNetwork = null;
ReflectionTestUtils.setField(cmd, "displayNetwork", displayNetwork);
Assert.assertTrue(cmd.isDisplay());
}
public void testGetPhysicalNetworkIdForInvalidNetOfferingId() {
Long physicalNetworkId = 1L;
ReflectionTestUtils.setField(cmd, "physicalNetworkId", physicalNetworkId);
Mockito.when(_entityMgr.findById(NetworkOffering.class, 1L)).thenReturn(null);
try {
cmd.getPhysicalNetworkId();
} catch (Exception e) {
Assert.assertTrue(e.getMessage().startsWith("Unable to find network offering by ID"));
}
}
public void testGetPhysicalNetworkIdForInvalidAssociatedNetId() {
Long physicalNetworkId = 1L;
Long networkOfferingId = 1L;
Long associatedNetworkId = 1L;
ReflectionTestUtils.setField(cmd, "networkOfferingId", networkOfferingId);
ReflectionTestUtils.setField(cmd, "associatedNetworkId", associatedNetworkId);
NetworkOffering networkOffering = Mockito.mock(NetworkOffering.class);
ReflectionTestUtils.setField(cmd, "physicalNetworkId", physicalNetworkId);
Mockito.when(_entityMgr.findById(NetworkOffering.class, networkOfferingId)).thenReturn(networkOffering);
Mockito.when(_entityMgr.findById(Network.class, associatedNetworkId)).thenReturn(null);
try {
cmd.getPhysicalNetworkId();
} catch (Exception e) {
Assert.assertTrue(e.getMessage().startsWith("Unable to find network by ID"));
}
}
public void testGetPhysicalNetworkIdForAssociatedNetIdForNonSharedNet() {
Long physicalNetworkId = 1L;
Long networkOfferingId = 1L;
Long associatedNetworkId = 1L;
ReflectionTestUtils.setField(cmd, "networkOfferingId", networkOfferingId);
ReflectionTestUtils.setField(cmd, "associatedNetworkId", associatedNetworkId);
NetworkOffering networkOffering = Mockito.mock(NetworkOffering.class);
Network network = Mockito.mock(Network.class);
ReflectionTestUtils.setField(cmd, "physicalNetworkId", physicalNetworkId);
Mockito.when(_entityMgr.findById(NetworkOffering.class, networkOfferingId)).thenReturn(networkOffering);
Mockito.when(_entityMgr.findById(Network.class, associatedNetworkId)).thenReturn(network);
Mockito.when(networkOffering.getGuestType()).thenReturn(Network.GuestType.Isolated);
try {
cmd.getPhysicalNetworkId();
} catch (Exception e) {
Assert.assertTrue(e.getMessage().startsWith("Associated network ID can be specified for networks of guest IP type Shared only"));
}
}
public void testGetPhysicalNetworkIdForNonSharedNet() {
Long physicalNetworkId = 1L;
Long networkOfferingId = 1L;
ReflectionTestUtils.setField(cmd, "networkOfferingId", networkOfferingId);
NetworkOffering networkOffering = Mockito.mock(NetworkOffering.class);
ReflectionTestUtils.setField(cmd, "physicalNetworkId", physicalNetworkId);
Mockito.when(_entityMgr.findById(NetworkOffering.class, networkOfferingId)).thenReturn(networkOffering);
Mockito.when(networkOffering.getGuestType()).thenReturn(Network.GuestType.Isolated);
try {
cmd.getPhysicalNetworkId();
} catch (Exception e) {
Assert.assertTrue(e.getMessage().startsWith("Physical network ID can be specified for networks of guest IP type Shared only"));
}
}
public void testGetPhysicalNetworkIdForSharedNet() {
Long physicalNetworkId = 1L;
Long networkOfferingId = 1L;
ReflectionTestUtils.setField(cmd, "networkOfferingId", networkOfferingId);
NetworkOffering networkOffering = Mockito.mock(NetworkOffering.class);
ReflectionTestUtils.setField(cmd, "physicalNetworkId", physicalNetworkId);
Mockito.when(_entityMgr.findById(NetworkOffering.class, networkOfferingId)).thenReturn(networkOffering);
Mockito.when(networkOffering.getGuestType()).thenReturn(Network.GuestType.Shared);
try {
Assert.assertEquals(cmd.getPhysicalNetworkId(), physicalNetworkId);
} catch (Exception e) {
Assert.fail("Failed to get physical network id");
}
}
public void testGetZoneId() {
Long physicalNetworkId = 1L;
Long networkOfferingId = 1L;
ReflectionTestUtils.setField(cmd, "networkOfferingId", networkOfferingId);
NetworkOffering networkOffering = Mockito.mock(NetworkOffering.class);
ReflectionTestUtils.setField(cmd, "physicalNetworkId", physicalNetworkId);
Mockito.when(_entityMgr.findById(NetworkOffering.class, networkOfferingId)).thenReturn(networkOffering);
Mockito.when(networkOffering.getGuestType()).thenReturn(Network.GuestType.Shared);
Long zoneId = 1L;
ReflectionTestUtils.setField(cmd, "zoneId", zoneId);
Assert.assertEquals(cmd.getZoneId(), zoneId);
}
public void testGetPublicMtuWhenNotSet() {
Integer publicMtu = null;
ReflectionTestUtils.setField(cmd, "publicMtu", publicMtu);
Assert.assertEquals(NetworkService.DEFAULT_MTU, cmd.getPublicMtu());
}
public void testGetPublicMtuWhenSet() {
Integer publicMtu = 1450;
ReflectionTestUtils.setField(cmd, "publicMtu", publicMtu);
Assert.assertEquals(cmd.getPublicMtu(), publicMtu);
}
public void testGetPrivateMtuWhenNotSet() {
Integer privateMtu = null;
ReflectionTestUtils.setField(cmd, "privateMtu", privateMtu);
Assert.assertEquals(NetworkService.DEFAULT_MTU, cmd.getPrivateMtu());
}
public void testGetPrivateMtuWhenSet() {
Integer privateMtu = 1250;
ReflectionTestUtils.setField(cmd, "privateMtu", privateMtu);
Assert.assertEquals(cmd.getPrivateMtu(), privateMtu);
}
public void testExecute() throws InsufficientCapacityException, ResourceAllocationException {
ReflectionTestUtils.setField(cmd, "displayText", "testNetwork");
ReflectionTestUtils.setField(cmd, "name", "testNetwork");
ReflectionTestUtils.setField(cmd, "networkOfferingId", 1L);
ReflectionTestUtils.setField(cmd, "zoneId", 1L);
Network createdNetwork = Mockito.mock(Network.class);
NetworkResponse response = Mockito.mock(NetworkResponse.class);
responseGenerator = Mockito.mock(ResponseGenerator.class);
Mockito.when(networkService.createGuestNetwork(cmd)).thenReturn(createdNetwork);
Mockito.when(responseGenerator.createNetworkResponse(ResponseObject.ResponseView.Restricted, createdNetwork)).thenReturn(response);
cmd._responseGenerator = responseGenerator;
try {
cmd.execute();
Mockito.verify(networkService, Mockito.times(1)).createGuestNetwork(cmd);
} catch (Exception e) {
System.out.println(e);
Assert.fail("Should successfully create the network");
}
}
}

View File

@ -0,0 +1,176 @@
// 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 org.apache.cloudstack.api.command.user.network;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.network.Network;
import com.cloud.network.NetworkService;
import com.cloud.offering.NetworkOffering;
import com.cloud.utils.db.EntityManager;
import junit.framework.TestCase;
import org.apache.cloudstack.api.ResponseGenerator;
import org.apache.cloudstack.api.ResponseObject;
import org.apache.cloudstack.api.response.NetworkResponse;
import org.junit.Assert;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.powermock.modules.junit4.PowerMockRunner;
import org.springframework.test.util.ReflectionTestUtils;
@RunWith(PowerMockRunner.class)
public class UpdateNetworkCmdTest extends TestCase {
@Mock
NetworkService networkService;
@Mock
public EntityManager _entityMgr;
private ResponseGenerator responseGenerator;
@InjectMocks
UpdateNetworkCmd cmd = new UpdateNetworkCmd();
public void testGetId() {
Long id = 1L;
ReflectionTestUtils.setField(cmd, "id", id);
Assert.assertEquals(cmd.getId(), id);
}
public void testGetNetworkName() {
String name = "testNetwork";
ReflectionTestUtils.setField(cmd, "name", name);
Assert.assertEquals(cmd.getNetworkName(), name);
}
public void testGetDisplayText() {
String displayText = "test network";
ReflectionTestUtils.setField(cmd, "displayText", displayText);
Assert.assertEquals(cmd.getDisplayText(), displayText);
}
public void testGetNetworkDomain() {
String netDomain = "cs1cloud.internal";
ReflectionTestUtils.setField(cmd, "networkDomain", netDomain);
Assert.assertEquals(cmd.getNetworkDomain(), netDomain);
}
public void testGetNetworkOfferingId() {
Long networkOfferingId = 1L;
ReflectionTestUtils.setField(cmd, "networkOfferingId", networkOfferingId);
Assert.assertEquals(cmd.getNetworkOfferingId(), networkOfferingId);
}
public void testGetChangeCidr() {
Boolean changeCidr = true;
ReflectionTestUtils.setField(cmd, "changeCidr", changeCidr);
Assert.assertTrue(cmd.getChangeCidr());
}
public void testGetGuestVmCidr() {
String guestVmCidr = "10.10.0.0/24";
ReflectionTestUtils.setField(cmd, "guestVmCidr", guestVmCidr);
Assert.assertEquals(cmd.getGuestVmCidr(), guestVmCidr);
}
public void testGetDisplayNetwork() {
Boolean displayNetwork = true;
ReflectionTestUtils.setField(cmd, "displayNetwork", displayNetwork);
Assert.assertTrue(cmd.getDisplayNetwork());
}
public void testGetUpdateInSequenceIfNull() {
Boolean updateInSequence = null;
ReflectionTestUtils.setField(cmd, "updateInSequence", updateInSequence);
Assert.assertFalse(cmd.getUpdateInSequence());
}
public void testGetUpdateInSequenceIfValidValuePassed() {
Boolean updateInSequence = true;
ReflectionTestUtils.setField(cmd, "updateInSequence", updateInSequence);
Assert.assertTrue(cmd.getUpdateInSequence());
}
public void testGetForcedIfNull() {
Boolean forced = null;
ReflectionTestUtils.setField(cmd, "forced", forced);
Assert.assertFalse(cmd.getUpdateInSequence());
}
public void testGetForcedIfValidValuePassed() {
Boolean forced = true;
ReflectionTestUtils.setField(cmd, "forced", forced);
Assert.assertTrue(cmd.getForced());
}
public void testGetPublicMtu() {
Integer publicMtu = 1450;
ReflectionTestUtils.setField(cmd, "publicMtu", publicMtu);
Assert.assertEquals(cmd.getPublicMtu(), publicMtu);
}
public void testGetPublicMtuIfNull() {
Integer publicMtu = null;
ReflectionTestUtils.setField(cmd, "publicMtu", publicMtu);
Assert.assertNull(cmd.getPublicMtu());
}
public void testGetPrivateMtu() {
Integer privateMtu = 1450;
ReflectionTestUtils.setField(cmd, "privateMtu", privateMtu);
Assert.assertEquals(cmd.getPrivateMtu(), privateMtu);
}
public void testGetPrivateMtuIfNull() {
Integer privateMtu = null;
ReflectionTestUtils.setField(cmd, "privateMtu", privateMtu);
Assert.assertNull(cmd.getPrivateMtu());
}
public void testEventDescription() {
long networkOfferingId = 1L;
Network network = Mockito.mock(Network.class);
NetworkOffering offering = Mockito.mock(NetworkOffering.class);
ReflectionTestUtils.setField(cmd, "networkOfferingId", networkOfferingId);
ReflectionTestUtils.setField(cmd, "id", 1L);
Mockito.when(networkService.getNetwork(Mockito.any(Long.class))).thenReturn(network);
Mockito.when(network.getNetworkOfferingId()).thenReturn(networkOfferingId);
Mockito.when(_entityMgr.findById(NetworkOffering.class, networkOfferingId)).thenReturn(offering);
String msg = cmd.getEventDescription();
Assert.assertTrue(msg.contains("Updating network"));
}
public void testExecute() throws InsufficientCapacityException {
long networkId = 1L;
Integer publicmtu = 1200;
ReflectionTestUtils.setField(cmd, "id", networkId);
ReflectionTestUtils.setField(cmd, "publicMtu", publicmtu);
Network network = Mockito.mock(Network.class);
responseGenerator = Mockito.mock(ResponseGenerator.class);
NetworkResponse response = Mockito.mock(NetworkResponse.class);
response.setPublicMtu(publicmtu);
Mockito.when(networkService.getNetwork(networkId)).thenReturn(network);
Mockito.when(networkService.updateGuestNetwork(cmd)).thenReturn(network);
cmd._responseGenerator = responseGenerator;
Mockito.when(responseGenerator.createNetworkResponse(ResponseObject.ResponseView.Restricted, network)).thenReturn(response);
cmd.execute();
Mockito.verify(responseGenerator).createNetworkResponse(Mockito.any(ResponseObject.ResponseView.class), Mockito.any(Network.class));
NetworkResponse actualResponse = (NetworkResponse) cmd.getResponseObject();
Assert.assertEquals(response, actualResponse);
}
}

View File

@ -0,0 +1,165 @@
// 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 org.apache.cloudstack.api.command.user.vpc;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.NetworkService;
import com.cloud.network.vpc.Vpc;
import com.cloud.network.vpc.VpcService;
import com.cloud.user.AccountService;
import com.cloud.utils.db.EntityManager;
import junit.framework.TestCase;
import org.apache.cloudstack.api.ResponseGenerator;
import org.apache.cloudstack.api.ResponseObject;
import org.apache.cloudstack.api.response.VpcResponse;
import org.junit.Assert;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.powermock.modules.junit4.PowerMockRunner;
import org.springframework.test.util.ReflectionTestUtils;
@RunWith(PowerMockRunner.class)
public class CreateVPCCmdTest extends TestCase {
@Mock
public VpcService _vpcService;
@Mock
public EntityManager _entityMgr;
@Mock
public AccountService _accountService;
private ResponseGenerator responseGenerator;
@InjectMocks
CreateVPCCmd cmd = new CreateVPCCmd() {
@Override
public Long getEntityId() {
return 2L;
}
};
public void testGetAccountName() {
String accountName = "admin";
ReflectionTestUtils.setField(cmd, "accountName", accountName);
Assert.assertEquals(cmd.getAccountName(), accountName);
}
public void testGetDomainId() {
Long domainId = 1L;
ReflectionTestUtils.setField(cmd, "domainId", domainId);
Assert.assertEquals(cmd.getDomainId(), domainId);
}
public void testGetZoneId() {
Long zoneId = 1L;
ReflectionTestUtils.setField(cmd, "zoneId", zoneId);
Assert.assertEquals(cmd.getZoneId(), zoneId);
}
public void testGetVpcName() {
String vpcName = "vpcNet";
ReflectionTestUtils.setField(cmd, "vpcName", vpcName);
Assert.assertEquals(cmd.getVpcName(), vpcName);
}
public void testGetCidr() {
String cidr = "10.0.0.0/8";
ReflectionTestUtils.setField(cmd, "cidr", cidr);
Assert.assertEquals(cmd.getCidr(), cidr);
}
public void testGetDisplayText() {
String displayText = "VPC Network";
ReflectionTestUtils.setField(cmd, "displayText", displayText);
Assert.assertEquals(cmd.getDisplayText(), displayText);
}
public void testGetVpcOffering() {
Long vpcOffering = 1L;
ReflectionTestUtils.setField(cmd, "vpcOffering", vpcOffering);
Assert.assertEquals(cmd.getVpcOffering(), vpcOffering);
}
public void testGetNetworkDomain() {
String netDomain = "cs1cloud.internal";
ReflectionTestUtils.setField(cmd, "networkDomain", netDomain);
Assert.assertEquals(cmd.getNetworkDomain(), netDomain);
}
public void testGetPublicMtuWhenNotSet() {
Integer publicMtu = null;
ReflectionTestUtils.setField(cmd, "publicMtu", publicMtu);
Assert.assertEquals(NetworkService.DEFAULT_MTU, cmd.getPublicMtu());
}
public void testGetPublicMtuWhenSet() {
Integer publicMtu = 1450;
ReflectionTestUtils.setField(cmd, "publicMtu", publicMtu);
Assert.assertEquals(cmd.getPublicMtu(), publicMtu);
}
public void testIsStartWhenNull() {
Boolean start = null;
ReflectionTestUtils.setField(cmd, "start", start);
Assert.assertTrue(cmd.isStart());
}
public void testIsStartWhenValidValuePassed() {
Boolean start = true;
ReflectionTestUtils.setField(cmd, "start", start);
Assert.assertTrue(cmd.isStart());
}
public void testGetDisplayVpc() {
Boolean display = true;
ReflectionTestUtils.setField(cmd, "display", display);
Assert.assertTrue(cmd.getDisplayVpc());
}
public void testCreate() throws ResourceAllocationException {
Vpc vpc = Mockito.mock(Vpc.class);
ReflectionTestUtils.setField(cmd, "zoneId", 1L);
ReflectionTestUtils.setField(cmd, "vpcOffering", 1L);
ReflectionTestUtils.setField(cmd, "vpcName", "testVpc");
ReflectionTestUtils.setField(cmd, "displayText", "Test Vpc Network");
ReflectionTestUtils.setField(cmd, "cidr", "10.0.0.0/8");
ReflectionTestUtils.setField(cmd, "networkDomain", "cs1cloud.internal");
ReflectionTestUtils.setField(cmd, "display", true);
ReflectionTestUtils.setField(cmd, "publicMtu", 1450);
Mockito.when(_accountService.finalyzeAccountId(Mockito.anyString(), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyBoolean())).thenReturn(1L);
Mockito.when(cmd.getEntityOwnerId()).thenReturn(1L);
Mockito.when(_vpcService.createVpc(Mockito.any(CreateVPCCmd.class))).thenReturn(vpc);
cmd.create();
Mockito.verify(_vpcService, Mockito.times(1)).createVpc(Mockito.any(CreateVPCCmd.class));
}
public void testExecute() throws ResourceUnavailableException, InsufficientCapacityException {
ReflectionTestUtils.setField(cmd, "start", true);
Vpc vpc = Mockito.mock(Vpc.class);
VpcResponse response = Mockito.mock(VpcResponse.class);
responseGenerator = Mockito.mock(ResponseGenerator.class);
Mockito.when(_vpcService.startVpc(1L, true)).thenReturn(true);
Mockito.when(_entityMgr.findById(Mockito.eq(Vpc.class), Mockito.any(Long.class))).thenReturn(vpc);
cmd._responseGenerator = responseGenerator;
Mockito.when(responseGenerator.createVpcResponse(ResponseObject.ResponseView.Restricted, vpc)).thenReturn(response);
cmd.execute();
Mockito.verify(_vpcService, Mockito.times(1)).startVpc(Mockito.anyLong(), Mockito.anyBoolean());
}
}

View File

@ -0,0 +1,94 @@
// 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 org.apache.cloudstack.api.command.user.vpc;
import com.cloud.network.vpc.Vpc;
import com.cloud.network.vpc.VpcService;
import junit.framework.TestCase;
import org.apache.cloudstack.api.ResponseGenerator;
import org.apache.cloudstack.api.ResponseObject;
import org.apache.cloudstack.api.response.VpcResponse;
import org.junit.Assert;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.powermock.modules.junit4.PowerMockRunner;
import org.springframework.test.util.ReflectionTestUtils;
@RunWith(PowerMockRunner.class)
public class UpdateVPCCmdTest extends TestCase {
@Mock
VpcService _vpcService;
private ResponseGenerator responseGenerator;
@InjectMocks
UpdateVPCCmd cmd = new UpdateVPCCmd();
public void testGetVpcName() {
String vpcName = "updatedVpcName";
ReflectionTestUtils.setField(cmd, "vpcName", vpcName);
Assert.assertEquals(cmd.getVpcName(), vpcName);
}
public void testGetDisplayText() {
String displayText = "Updated VPC Name";
ReflectionTestUtils.setField(cmd, "displayText", displayText);
Assert.assertEquals(cmd.getDisplayText(), displayText);
}
public void testGetId() {
Long id = 1L;
ReflectionTestUtils.setField(cmd, "id", id);
Assert.assertEquals(cmd.getId(), id);
}
public void testIsDisplayVpc() {
Boolean display = true;
ReflectionTestUtils.setField(cmd, "display", display);
Assert.assertEquals(cmd.isDisplayVpc(), display);
}
public void testGetPublicMtu() {
Integer publicMtu = 1450;
ReflectionTestUtils.setField(cmd, "publicMtu", publicMtu);
Assert.assertEquals(cmd.getPublicMtu(), publicMtu);
}
public void testExecute() {
ReflectionTestUtils.setField(cmd, "id", 1L);
ReflectionTestUtils.setField(cmd, "vpcName", "updatedVpcName");
ReflectionTestUtils.setField(cmd, "displayText", "Updated VPC Name");
ReflectionTestUtils.setField(cmd, "displayText", "Updated VPC Name");
ReflectionTestUtils.setField(cmd, "customId", null);
ReflectionTestUtils.setField(cmd, "display", true);
ReflectionTestUtils.setField(cmd, "publicMtu", 1450);
Vpc vpc = Mockito.mock(Vpc.class);
VpcResponse response = Mockito.mock(VpcResponse.class);
responseGenerator = Mockito.mock(ResponseGenerator.class);
cmd._responseGenerator = responseGenerator;
Mockito.when(_vpcService.updateVpc(Mockito.anyLong(), Mockito.anyString(), Mockito.anyString(),
Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyInt())).thenReturn(vpc);
Mockito.when(responseGenerator.createVpcResponse(ResponseObject.ResponseView.Full, vpc)).thenReturn(response);
Mockito.verify(_vpcService, Mockito.times(0)).updateVpc(Mockito.anyLong(), Mockito.anyString(), Mockito.anyString(),
Mockito.anyString(), Mockito.anyBoolean(), Mockito.anyInt());
}
}

View File

@ -0,0 +1,59 @@
// 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.agent.api.routing;
import com.cloud.agent.api.to.IpAddressTO;
import java.util.Arrays;
public class UpdateNetworkCommand extends NetworkElementCommand{
IpAddressTO[] ipAddresses;
public UpdateNetworkCommand(IpAddressTO[] ips) {
this.ipAddresses = ips;
}
@Override
public boolean executeInSequence() {
return false;
}
public IpAddressTO[] getIpAddresses() {
return ipAddresses;
}
@Override
public int getAnswersCount() {
return ipAddresses.length;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
UpdateNetworkCommand command = (UpdateNetworkCommand) o;
return Arrays.equals(ipAddresses, command.ipAddresses);
}
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + Arrays.hashCode(ipAddresses);
return result;
}
}

View File

@ -78,5 +78,7 @@ public class VRScripts {
public static final String RETRIEVE_DIAGNOSTICS = "get_diagnostics_files.py";
public static final String VR_FILE_CLEANUP = "cleanup.sh";
public static final String VR_UPDATE_INTERFACE_CONFIG = "update_interface_config.sh";
public static final String ROUTER_FILESYSTEM_WRITABLE_CHECK = "filesystem_writable_check.py";
}

View File

@ -34,7 +34,11 @@ import java.util.concurrent.locks.ReentrantLock;
import javax.naming.ConfigurationException;
import com.cloud.agent.api.routing.UpdateNetworkCommand;
import com.cloud.agent.api.to.IpAddressTO;
import com.cloud.network.router.VirtualRouter;
import com.cloud.utils.PasswordGenerator;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.ca.SetupCertificateAnswer;
import org.apache.cloudstack.ca.SetupCertificateCommand;
import org.apache.cloudstack.ca.SetupKeyStoreCommand;
@ -46,6 +50,7 @@ import org.apache.cloudstack.diagnostics.PrepareFilesAnswer;
import org.apache.cloudstack.diagnostics.PrepareFilesCommand;
import org.apache.cloudstack.utils.security.KeyStoreUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.util.SubnetUtils;
import org.apache.log4j.Logger;
import org.joda.time.Duration;
@ -134,6 +139,10 @@ public class VirtualRoutingResource {
return execute((AggregationControlCommand)cmd);
}
if (cmd instanceof UpdateNetworkCommand) {
return execute((UpdateNetworkCommand) cmd);
}
if (_vrAggregateCommandsSet.containsKey(routerName)) {
_vrAggregateCommandsSet.get(routerName).add(cmd);
aggregated = true;
@ -216,6 +225,51 @@ public class VirtualRoutingResource {
}
}
private static String getRouterSshControlIp(NetworkElementCommand cmd) {
String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
if (s_logger.isDebugEnabled())
s_logger.debug("Use router's private IP for SSH control. IP : " + routerIp);
return routerIp;
}
private Answer execute(UpdateNetworkCommand cmd) {
IpAddressTO[] ipAddresses = cmd.getIpAddresses();
String routerIp = getRouterSshControlIp(cmd);
boolean finalResult = true;
for (IpAddressTO ipAddressTO : ipAddresses) {
try {
SubnetUtils util = new SubnetUtils(ipAddressTO.getPublicIp(), ipAddressTO.getVlanNetmask());
String address = util.getInfo().getCidrSignature();
String subnet = address.split("/")[1];
ExecutionResult result = _vrDeployer.executeInVR(routerIp, VRScripts.VR_UPDATE_INTERFACE_CONFIG,
ipAddressTO.getPublicIp() + " " + subnet + " " + ipAddressTO.getMtu() + " " + 15);
if (s_logger.isDebugEnabled())
s_logger.debug("result: " + result.isSuccess() + ", output: " + result.getDetails());
if (!Boolean.TRUE.equals(result.isSuccess())) {
if (result.getDetails().contains(String.format("Interface with IP %s not found", ipAddressTO.getPublicIp()))) {
s_logger.warn(String.format("Skipping IP: %s as it isn't configured on router interface", ipAddressTO.getPublicIp()));
} else if (ipAddressTO.getDetails().get(ApiConstants.REDUNDANT_STATE).equals(VirtualRouter.RedundantState.PRIMARY.name())) {
s_logger.warn(String.format("Failed to update interface mtu to %s on interface with ip: %s",
ipAddressTO.getMtu(), ipAddressTO.getPublicIp()));
finalResult = false;
}
continue;
}
s_logger.info(String.format("Successfully updated mtu to %s on interface with ip: %s",
ipAddressTO.getMtu(), ipAddressTO.getPublicIp()));
finalResult &= true;
} catch (Exception e) {
String msg = "Prepare UpdateNetwork failed due to " + e.toString();
s_logger.error(msg, e);
return new Answer(cmd, e);
}
}
if (finalResult) {
return new Answer(cmd, true, null);
}
return new Answer(cmd, new CloudRuntimeException("Failed to update interface mtu"));
}
private ExecutionResult applyConfigToVR(String routerAccessIp, ConfigItem c) {
return applyConfigToVR(routerAccessIp, c, VRScripts.VR_SCRIPT_EXEC_TIMEOUT);
}

View File

@ -43,6 +43,7 @@ public class IpAssociationConfigItem extends AbstractConfigItemFacade {
final IpAddress ipAddress = new IpAddress(ip.getPublicIp(), ip.isSourceNat(), ip.isAdd(), ip.isOneToOneNat(), ip.isFirstIP(), ip.getVlanGateway(), ip.getVlanNetmask(),
ip.getVifMacAddress(), ip.getNicDevId(), ip.isNewNic(), ip.getTrafficType().toString());
ipAddress.setPrivateGateway(ip.isPrivateGateway());
ipAddress.setMtu(ip.getMtu());
ips.add(ipAddress);
}

View File

@ -33,11 +33,9 @@ import com.cloud.agent.resource.virtualnetwork.model.GuestNetwork;
import com.cloud.utils.net.NetUtils;
public class SetGuestNetworkConfigItem extends AbstractConfigItemFacade {
@Override
public List<ConfigItem> generateConfig(final NetworkElementCommand cmd) {
final SetupGuestNetworkCommand command = (SetupGuestNetworkCommand) cmd;
final NicTO nic = command.getNic();
final String routerGIP = command.getAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP);
final String gateway = command.getAccessDetail(NetworkElementCommand.GUEST_NETWORK_GATEWAY);
@ -73,7 +71,7 @@ public class SetGuestNetworkConfigItem extends AbstractConfigItemFacade {
if (nic.getIp6Cidr() != null) {
guestNetwork.setCidr6(String.valueOf(NetUtils.getIp6CidrSize(nic.getIp6Cidr())));
}
guestNetwork.setMtu(nic.getMtu());
guestNetwork.setRouterIp6(command.getRouterIpv6());
guestNetwork.setRouterIp6Gateway(command.getRouterIpv6Gateway());
guestNetwork.setRouterIp6Cidr(command.getRouterIpv6Cidr());

View File

@ -38,6 +38,8 @@ public class GuestNetwork extends ConfigBase {
private String routerIp6Gateway;
private String routerIp6Cidr;
private Integer mtu;
public GuestNetwork() {
super(ConfigBase.GUEST_NETWORK);
}
@ -192,4 +194,12 @@ public class GuestNetwork extends ConfigBase {
public void setRouterIp6Cidr(String routerIp6Cidr) {
this.routerIp6Cidr = routerIp6Cidr;
}
public void setMtu(Integer mtu) {
this.mtu = mtu;
}
public Integer getMtu() {
return mtu;
}
}

View File

@ -33,7 +33,7 @@ public class IpAddress {
private boolean newNic;
private String nwType;
private boolean isPrivateGateway;
private Integer mtu;
public IpAddress() {
// Empty constructor for (de)serialization
}
@ -142,4 +142,11 @@ public class IpAddress {
this.isPrivateGateway = isPrivateGateway;
}
public void setMtu(Integer mtu) {
this.mtu = mtu;
}
public Integer getMtu() {
return mtu;
}
}

View File

@ -188,7 +188,7 @@ 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,
String ip4Dns1, String ip4Dns2, String ip6Dns1, String ip6Dns2) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException;
String ip4Dns1, String ip4Dns2, String ip6Dns1, String ip6Dns2, Pair<Integer, Integer> vrIfaceMTUs) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException;
UserDataServiceProvider getPasswordResetProvider(Network network);

View File

@ -20,6 +20,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import com.cloud.utils.Pair;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import com.cloud.exception.ConcurrentOperationException;
@ -109,7 +110,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, String ip4Dns1, String ip4Dns2, String ip6Dns1, String ip6Dns2)
Boolean displayNetworkEnabled, String externalId, String ip6Gateway, String ip6Cidr, String ip4Dns1, String ip4Dns2, String ip6Dns1, String ip6Dns2, Pair<Integer, Integer> vrIfaceMTUs)
throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException;
/**

View File

@ -3510,6 +3510,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
return nicId1.compareTo(nicId2);
}
});
for (final NicVO nic : nics) {
final Network network = _networkModel.getNetwork(nic.getNetworkId());
final NicProfile nicProfile =

View File

@ -77,6 +77,8 @@ import com.cloud.agent.api.routing.NetworkElementCommand;
import com.cloud.agent.api.to.NicTO;
import com.cloud.agent.api.to.deployasis.OVFNetworkTO;
import com.cloud.alert.AlertManager;
import com.cloud.api.query.dao.DomainRouterJoinDao;
import com.cloud.api.query.vo.DomainRouterJoinVO;
import com.cloud.configuration.ConfigurationManager;
import com.cloud.configuration.Resource.ResourceType;
import com.cloud.dc.ClusterVO;
@ -127,6 +129,7 @@ import com.cloud.network.Network.Service;
import com.cloud.network.NetworkMigrationResponder;
import com.cloud.network.NetworkModel;
import com.cloud.network.NetworkProfile;
import com.cloud.network.NetworkService;
import com.cloud.network.NetworkStateListener;
import com.cloud.network.Networks;
import com.cloud.network.Networks.BroadcastDomainType;
@ -187,6 +190,7 @@ import com.cloud.network.rules.dao.PortForwardingRulesDao;
import com.cloud.network.vpc.NetworkACLManager;
import com.cloud.network.vpc.Vpc;
import com.cloud.network.vpc.VpcManager;
import com.cloud.network.vpc.VpcVO;
import com.cloud.network.vpc.dao.PrivateIpDao;
import com.cloud.network.vpn.RemoteAccessVpnService;
import com.cloud.offering.NetworkOffering;
@ -313,6 +317,8 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
@Inject
DomainRouterDao routerDao;
@Inject
DomainRouterJoinDao routerJoinDao;
@Inject
RemoteAccessVpnDao _remoteAccessVpnDao;
@Inject
VpcVirtualNetworkApplianceService _routerService;
@ -769,7 +775,6 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
final NetworkVO networkPersisted = _networksDao.persist(vo, vo.getGuestType() == Network.GuestType.Isolated,
finalizeServicesAndProvidersForNetwork(offering, plan.getPhysicalNetworkId()));
networks.add(networkPersisted);
if (network.getPvlanType() != null) {
NetworkDetailVO detailVO = new NetworkDetailVO(networkPersisted.getId(), ApiConstants.ISOLATED_PVLAN_TYPE, network.getPvlanType().toString(), true);
networkDetailsDao.persist(detailVO);
@ -1026,16 +1031,73 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
}
deviceId = applyProfileToNic(vo, profile, deviceId);
vo = _nicDao.persist(vo);
final Integer networkRate = _networkModel.getNetworkRate(network.getId(), vm.getId());
final NicProfile vmNic = new NicProfile(vo, network, vo.getBroadcastUri(), vo.getIsolationUri(), networkRate, _networkModel.isSecurityGroupSupportedInNetwork(network),
_networkModel.getNetworkTag(vm.getHypervisorType(), network));
if (vm.getType() == Type.DomainRouter) {
Pair<NetworkVO, VpcVO> networks = getGuestNetworkRouterAndVpcDetails(vm.getId());
setMtuDetailsInVRNic(networks, network, vo);
_nicDao.update(vo.getId(), vo);
setMtuInVRNicProfile(networks, network.getTrafficType(), vmNic);
}
return new Pair<NicProfile, Integer>(vmNic, Integer.valueOf(deviceId));
}
private void setMtuDetailsInVRNic(final Pair<NetworkVO, VpcVO> networks, Network network, NicVO vo) {
if (TrafficType.Public == network.getTrafficType()) {
if (networks == null) {
return;
}
NetworkVO networkVO = networks.first();
VpcVO vpcVO = networks.second();
if (vpcVO != null) {
vo.setMtu(vpcVO.getPublicMtu());
} else {
vo.setMtu(networkVO.getPublicMtu());
}
} else if (TrafficType.Guest == network.getTrafficType()) {
vo.setMtu(network.getPrivateMtu());
}
}
private void setMtuInVRNicProfile(final Pair<NetworkVO, VpcVO> networks, TrafficType trafficType, NicProfile vmNic) {
if (networks == null) {
return;
}
NetworkVO networkVO = networks.first();
VpcVO vpcVO = networks.second();
if (networkVO != null) {
if (TrafficType.Public == trafficType) {
if (vpcVO != null) {
vmNic.setMtu(vpcVO.getPublicMtu());
} else {
vmNic.setMtu(networkVO.getPublicMtu());
}
} else if (TrafficType.Guest == trafficType) {
vmNic.setMtu(networkVO.getPrivateMtu());
}
}
}
private Pair<NetworkVO, VpcVO> getGuestNetworkRouterAndVpcDetails(long routerId) {
List<DomainRouterJoinVO> routerVo = routerJoinDao.getRouterByIdAndTrafficType(routerId, TrafficType.Guest);
if (routerVo.isEmpty()) {
routerVo = routerJoinDao.getRouterByIdAndTrafficType(routerId, TrafficType.Public);
if (routerVo.isEmpty()) {
return null;
}
}
DomainRouterJoinVO guestRouterDetails = routerVo.get(0);
VpcVO vpc = null;
if (guestRouterDetails.getVpcId() != 0) {
vpc = _entityMgr.findById(VpcVO.class, guestRouterDetails.getVpcId());
}
long networkId = guestRouterDetails.getNetworkId();
return new Pair<>(_networksDao.findById(networkId), vpc);
}
/**
* If the requested IPv4 address from the NicProfile was configured then it configures the IPv4 address, Netmask and Gateway to deploy the VM with the requested IP.
*/
@ -1887,7 +1949,6 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
public void prepare(final VirtualMachineProfile vmProfile, final DeployDestination dest, final ReservationContext context) throws InsufficientCapacityException, ConcurrentOperationException,
ResourceUnavailableException {
final List<NicVO> nics = _nicDao.listByVmId(vmProfile.getId());
// we have to implement default nics first - to ensure that default network elements start up first in multiple
//nics case
// (need for setting DNS on Dhcp to domR's Ip4 address)
@ -1911,6 +1972,10 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
final NetworkVO network = implemented.second();
final NicProfile profile = prepareNic(vmProfile, dest, context, nic.getId(), network);
if (vmProfile.getType() == Type.DomainRouter) {
Pair<NetworkVO, VpcVO> networks = getGuestNetworkRouterAndVpcDetails(vmProfile.getId());
setMtuInVRNicProfile(networks, network.getTrafficType(), profile);
}
vmProfile.addNic(profile);
}
}
@ -1956,16 +2021,19 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
if (profile.getReservationStrategy() != null) {
nic.setReservationStrategy(profile.getReservationStrategy());
}
updateNic(nic, network.getId(), 1);
} else {
profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), networkRate, _networkModel.isSecurityGroupSupportedInNetwork(network),
_networkModel.getNetworkTag(vmProfile.getHypervisorType(), network));
guru.updateNicProfile(profile, network);
nic.setState(Nic.State.Reserved);
updateNic(nic, network.getId(), 1);
}
if (vmProfile.getType() == Type.DomainRouter) {
Pair<NetworkVO, VpcVO> networks = getGuestNetworkRouterAndVpcDetails(vmProfile.getId());
setMtuDetailsInVRNic(networks, network, nic);
}
updateNic(nic, network.getId(), 1);
final List<Provider> providersToImplement = getNetworkProviders(network.getId());
for (final NetworkElement element : networkElements) {
if (providersToImplement.contains(element.getProvider())) {
@ -2464,7 +2532,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
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,
null, null, null, null);
null, null, null, null, null);
}
@Override
@ -2473,11 +2541,11 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
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, String ip4Dns1, String ip4Dns2, String ip6Dns1, String ip6Dns2) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
String routerIp, String routerIpv6, String ip4Dns1, String ip4Dns2, String ip6Dns1, String ip6Dns2, Pair<Integer, Integer> vrIfaceMTUs) 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, ip4Dns1, ip4Dns2, ip6Dns1, ip6Dns2);
isDisplayNetworkEnabled, isolatedPvlan, isolatedPvlanType, externalId, false, routerIp, routerIpv6, ip4Dns1, ip4Dns2, ip6Dns1, ip6Dns2, vrIfaceMTUs);
}
@DB
@ -2486,7 +2554,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
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, final String ip4Dns1, final String ip4Dns2,
final String ip6Dns1, final String ip6Dns2) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
final String ip6Dns1, final String ip6Dns2, Pair<Integer, Integer> vrIfaceMTUs) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
final NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId);
final DataCenterVO zone = _dcDao.findById(zoneId);
@ -2761,6 +2829,23 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
userNetwork.setRouterIpv6(routerIpv6);
}
if (vrIfaceMTUs != null) {
if (vrIfaceMTUs.first() != null && vrIfaceMTUs.first() > 0) {
userNetwork.setPublicMtu(vrIfaceMTUs.first());
} else {
userNetwork.setPublicMtu(Integer.valueOf(NetworkService.VRPublicInterfaceMtu.defaultValue()));
}
if (vrIfaceMTUs.second() != null && vrIfaceMTUs.second() > 0) {
userNetwork.setPrivateMtu(vrIfaceMTUs.second());
} else {
userNetwork.setPrivateMtu(Integer.valueOf(NetworkService.VRPrivateInterfaceMtu.defaultValue()));
}
} else {
userNetwork.setPublicMtu(Integer.valueOf(NetworkService.VRPublicInterfaceMtu.defaultValue()));
userNetwork.setPrivateMtu(Integer.valueOf(NetworkService.VRPrivateInterfaceMtu.defaultValue()));
}
if (!GuestType.L2.equals(userNetwork.getGuestType())) {
if (StringUtils.isNotBlank(ip4Dns1)) {
userNetwork.setDns1(ip4Dns1);
@ -4498,6 +4583,10 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|| vo.getVmType() == VirtualMachine.Type.DomainRouter && _networksDao.findById(network.getId()).getTrafficType() == TrafficType.Guest) {
_networksDao.setCheckForGc(network.getId());
}
if (vm.getType() == Type.DomainRouter) {
Pair<NetworkVO, VpcVO> networks = getGuestNetworkRouterAndVpcDetails(vm.getId());
setMtuDetailsInVRNic(networks, network, vo);
}
return vo;
}

View File

@ -94,4 +94,6 @@ public interface IPAddressDao extends GenericDao<IPAddressVO, Long> {
IPAddressVO findByVmIdAndNetworkId(long networkId, long vmId);
IPAddressVO findByAccountIdAndZoneIdAndStateAndIpAddress(long accountId, long dcId, State state, String ipAddress);
List<IPAddressVO> listByNetworkId(long networkId);
}

View File

@ -500,4 +500,12 @@ public class IPAddressDaoImpl extends GenericDaoBase<IPAddressVO, Long> implemen
sc.setParameters("ipAddress", ipAddress);
return findOneBy(sc);
}
@Override
public List<IPAddressVO> listByNetworkId(long networkId) {
SearchCriteria<IPAddressVO> sc = AllFieldsSearch.create();
sc.setParameters("network", networkId);
sc.setParameters("state", State.Allocated);
return listBy(sc);
}
}

View File

@ -39,6 +39,7 @@ import com.cloud.network.Networks.TrafficType;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.db.GenericDao;
import com.cloud.utils.net.NetUtils;
import org.apache.log4j.Logger;
/**
* NetworkConfigurationVO contains information about a specific network.
@ -47,6 +48,7 @@ import com.cloud.utils.net.NetUtils;
@Entity
@Table(name = "networks")
public class NetworkVO implements Network {
static final Logger s_logger = Logger.getLogger(NetworkVO.class);
@Id
@TableGenerator(name = "networks_sq", table = "sequence", pkColumnName = "name", valueColumnName = "value", pkColumnValue = "networks_seq", allocationSize = 1)
@Column(name = "id")
@ -197,6 +199,12 @@ public class NetworkVO implements Network {
@Transient
PVlanType pVlanType;
@Column(name = "public_mtu")
Integer publicMtu;
@Column(name = "private_mtu")
Integer privateMtu;
public NetworkVO() {
uuid = UUID.randomUUID().toString();
}
@ -275,6 +283,8 @@ public class NetworkVO implements Network {
this.ip6Dns2 = that.getIp6Dns2();
}
this.externalId = externalId;
this.publicMtu = that.getPublicMtu();
this.privateMtu = that.getPrivateMtu();
}
/**
@ -731,4 +741,20 @@ public class NetworkVO implements Network {
public void setRouterIpv6(String routerIpv6) {
this.routerIpv6 = routerIpv6;
}
public Integer getPublicMtu() {
return publicMtu;
}
public void setPublicMtu(Integer publicMtu) {
this.publicMtu = publicMtu;
}
public Integer getPrivateMtu() {
return privateMtu;
}
public void setPrivateMtu(Integer privateMtu) {
this.privateMtu = privateMtu;
}
}

View File

@ -89,6 +89,9 @@ public class VpcVO implements Vpc {
@Column(name = "region_level_vpc")
boolean regionLevelVpc = false;
@Column(name = "public_mtu")
Integer publicMtu;
@Column(name = "dns1")
String ip4Dns1;
@ -273,6 +276,14 @@ public class VpcVO implements Vpc {
return usesDistributedRouter;
}
public Integer getPublicMtu() {
return publicMtu;
}
public void setPublicMtu(Integer publicMtu) {
this.publicMtu = publicMtu;
}
@Override
public String getIp4Dns1() {
return ip4Dns1;

View File

@ -124,6 +124,9 @@ public class NicVO implements Nic {
@Column(name = "secondary_ip")
boolean secondaryIp;
@Column(name = "mtu")
Integer mtu;
@Transient
transient String nsxLogicalSwitchUuid;
@ -394,4 +397,13 @@ public class NicVO implements Nic {
public void setNsxLogicalSwitchPortUuid(String nsxLogicalSwitchPortUuid) {
this.nsxLogicalSwitchPortUuid = nsxLogicalSwitchPortUuid;
}
@Override
public Integer getMtu() {
return mtu;
}
public void setMtu(Integer mtu) {
this.mtu = mtu;
}
}

View File

@ -90,4 +90,8 @@ public interface NicDao extends GenericDao<NicVO, Long> {
NicVO findByInstanceIdAndMacAddress(long instanceId, String macAddress);
List<NicVO> findNicsByIpv6GatewayIpv6CidrAndReserver(String ipv6Gateway, String ipv6Cidr, String reserverName);
NicVO findByIpAddressAndVmType(String ip, VirtualMachine.Type vmType);
List<NicVO> listByNetworkIdAndType(long networkId, VirtualMachine.Type vmType);
}

View File

@ -383,4 +383,20 @@ public class NicDaoImpl extends GenericDaoBase<NicVO, Long> implements NicDao {
sc.setParameters("reserverName", reserverName);
return listBy(sc);
}
@Override
public NicVO findByIpAddressAndVmType(String ip, VirtualMachine.Type vmType) {
SearchCriteria<NicVO> sc = AllFieldsSearch.create();
sc.setParameters("vmType", vmType);
sc.setParameters("address", ip);
return findOneBy(sc);
}
@Override
public List<NicVO> listByNetworkIdAndType(long networkId, VirtualMachine.Type vmType) {
SearchCriteria<NicVO> sc = AllFieldsSearch.create();
sc.setParameters("network", networkId);
sc.setParameters("vmType", vmType);
return listBy(sc);
}
}

View File

@ -24,6 +24,116 @@ UPDATE `cloud`.`service_offering` so
SET so.limit_cpu_use = 1
WHERE so.default_use = 1 AND so.vm_type IN ('domainrouter', 'secondarystoragevm', 'consoleproxy', 'internalloadbalancervm', 'elasticloadbalancervm');
ALTER TABLE `cloud`.`networks` ADD COLUMN `public_mtu` bigint unsigned comment "MTU for VR public interface" ;
ALTER TABLE `cloud`.`networks` ADD COLUMN `private_mtu` bigint unsigned comment "MTU for VR private interfaces" ;
ALTER TABLE `cloud`.`vpc` ADD COLUMN `public_mtu` bigint unsigned comment "MTU for VPC VR public interface" ;
ALTER TABLE `cloud`.`nics` ADD COLUMN `mtu` bigint unsigned comment "MTU for the VR interface" ;
DROP VIEW IF EXISTS `cloud`.`domain_router_view`;
CREATE VIEW `cloud`.`domain_router_view` AS
select
vm_instance.id id,
vm_instance.name name,
account.id account_id,
account.uuid account_uuid,
account.account_name account_name,
account.type account_type,
domain.id domain_id,
domain.uuid domain_uuid,
domain.name domain_name,
domain.path domain_path,
projects.id project_id,
projects.uuid project_uuid,
projects.name project_name,
vm_instance.uuid uuid,
vm_instance.created created,
vm_instance.state state,
vm_instance.removed removed,
vm_instance.pod_id pod_id,
vm_instance.instance_name instance_name,
host_pod_ref.uuid pod_uuid,
data_center.id data_center_id,
data_center.uuid data_center_uuid,
data_center.name data_center_name,
data_center.networktype data_center_type,
data_center.dns1 dns1,
data_center.dns2 dns2,
data_center.ip6_dns1 ip6_dns1,
data_center.ip6_dns2 ip6_dns2,
host.id host_id,
host.uuid host_uuid,
host.name host_name,
host.hypervisor_type,
host.cluster_id cluster_id,
vm_template.id template_id,
vm_template.uuid template_uuid,
service_offering.id service_offering_id,
service_offering.uuid service_offering_uuid,
service_offering.name service_offering_name,
nics.id nic_id,
nics.uuid nic_uuid,
nics.network_id network_id,
nics.ip4_address ip_address,
nics.ip6_address ip6_address,
nics.ip6_gateway ip6_gateway,
nics.ip6_cidr ip6_cidr,
nics.default_nic is_default_nic,
nics.gateway gateway,
nics.netmask netmask,
nics.mac_address mac_address,
nics.broadcast_uri broadcast_uri,
nics.isolation_uri isolation_uri,
nics.mtu mtu,
vpc.id vpc_id,
vpc.uuid vpc_uuid,
vpc.name vpc_name,
networks.uuid network_uuid,
networks.name network_name,
networks.network_domain network_domain,
networks.traffic_type traffic_type,
networks.guest_type guest_type,
async_job.id job_id,
async_job.uuid job_uuid,
async_job.job_status job_status,
async_job.account_id job_account_id,
domain_router.template_version template_version,
domain_router.scripts_version scripts_version,
domain_router.is_redundant_router is_redundant_router,
domain_router.redundant_state redundant_state,
domain_router.stop_pending stop_pending,
domain_router.role role,
domain_router.software_version software_version
from
`cloud`.`domain_router`
inner join
`cloud`.`vm_instance` ON vm_instance.id = domain_router.id
inner join
`cloud`.`account` ON vm_instance.account_id = account.id
inner join
`cloud`.`domain` ON vm_instance.domain_id = domain.id
left join
`cloud`.`host_pod_ref` ON vm_instance.pod_id = host_pod_ref.id
left join
`cloud`.`projects` ON projects.project_account_id = account.id
left join
`cloud`.`data_center` ON vm_instance.data_center_id = data_center.id
left join
`cloud`.`host` ON vm_instance.host_id = host.id
left join
`cloud`.`vm_template` ON vm_instance.vm_template_id = vm_template.id
left join
`cloud`.`service_offering` ON vm_instance.service_offering_id = service_offering.id
left join
`cloud`.`nics` ON vm_instance.id = nics.instance_id and nics.removed is null
left join
`cloud`.`networks` ON nics.network_id = networks.id
left join
`cloud`.`vpc` ON domain_router.vpc_id = vpc.id and vpc.removed is null
left join
`cloud`.`async_job` ON async_job.instance_id = vm_instance.id
and async_job.instance_type = 'DomainRouter'
and async_job.job_status = 0;
-- Idempotent ADD COLUMN
DROP PROCEDURE IF EXISTS `cloud`.`IDEMPOTENT_ADD_COLUMN`;
CREATE PROCEDURE `cloud`.`IDEMPOTENT_ADD_COLUMN` (

View File

@ -765,7 +765,7 @@ public class KubernetesClusterManagerImpl extends ManagerBase implements Kuberne
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, null);
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

@ -2380,7 +2380,8 @@ public class ApiResponseHelper implements ResponseGenerator {
response.setRelated(nw.getUuid());
}
response.setNetworkDomain(network.getNetworkDomain());
response.setPublicMtu(network.getPublicMtu());
response.setPrivateMtu(network.getPrivateMtu());
response.setDns1(profile.getDns1());
response.setDns2(profile.getDns2());
response.setIpv6Dns1(profile.getIp6Dns1());
@ -3234,6 +3235,7 @@ public class ApiResponseHelper implements ResponseGenerator {
response.setNetworks(networkResponses);
response.setServices(serviceResponses);
response.setPublicMtu(vpc.getPublicMtu());
populateOwner(response, vpc);
// set tag information

View File

@ -20,23 +20,23 @@ import java.util.List;
import javax.inject.Inject;
import com.cloud.resource.icon.ResourceIconVO;
import org.apache.cloudstack.api.response.ResourceIconResponse;
import org.apache.cloudstack.annotation.AnnotationService;
import org.apache.cloudstack.annotation.dao.AnnotationDao;
import org.apache.cloudstack.api.ResponseObject.ResponseView;
import org.apache.cloudstack.api.response.ResourceIconResponse;
import org.apache.cloudstack.api.response.ResourceTagResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import org.apache.cloudstack.api.ResponseObject.ResponseView;
import org.apache.cloudstack.api.response.ResourceTagResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import com.cloud.api.ApiDBUtils;
import com.cloud.api.ApiResponseHelper;
import com.cloud.api.query.vo.DataCenterJoinVO;
import com.cloud.api.query.vo.ResourceTagJoinVO;
import com.cloud.dc.DataCenter;
import com.cloud.network.NetworkService;
import com.cloud.resource.icon.ResourceIconVO;
import com.cloud.server.ResourceTag.ResourceObjectType;
import com.cloud.user.AccountManager;
import com.cloud.utils.db.GenericDaoBase;
@ -120,6 +120,9 @@ public class DataCenterJoinDaoImpl extends GenericDaoBase<DataCenterJoinVO, Long
zoneResponse.setResourceDetails(ApiDBUtils.getResourceDetails(dataCenter.getId(), ResourceObjectType.Zone));
zoneResponse.setHasAnnotation(annotationDao.hasAnnotations(dataCenter.getUuid(), AnnotationService.EntityType.ZONE.name(),
_accountMgr.isRootAdmin(CallContext.current().getCallingAccount().getId())));
zoneResponse.setAllowUserSpecifyVRMtu(NetworkService.AllowUsersToSpecifyVRMtu.valueIn(dataCenter.getId()));
zoneResponse.setRouterPrivateInterfaceMaxMtu(NetworkService.VRPrivateInterfaceMtu.valueIn(dataCenter.getId()));
zoneResponse.setRouterPublicInterfaceMaxMtu(NetworkService.VRPublicInterfaceMtu.valueIn(dataCenter.getId()));
zoneResponse.setObjectName("zone");
return zoneResponse;

View File

@ -18,6 +18,7 @@ package com.cloud.api.query.dao;
import java.util.List;
import com.cloud.network.Networks;
import org.apache.cloudstack.api.response.DomainRouterResponse;
import com.cloud.api.query.vo.DomainRouterJoinVO;
@ -34,4 +35,6 @@ public interface DomainRouterJoinDao extends GenericDao<DomainRouterJoinVO, Long
List<DomainRouterJoinVO> newDomainRouterView(VirtualRouter vr);
List<DomainRouterJoinVO> searchByIds(Long... ids);
List<DomainRouterJoinVO> getRouterByIdAndTrafficType(Long id, Networks.TrafficType... trafficType);
}

View File

@ -62,6 +62,7 @@ public class DomainRouterJoinDaoImpl extends GenericDaoBase<DomainRouterJoinVO,
private final SearchBuilder<DomainRouterJoinVO> vrSearch;
private final SearchBuilder<DomainRouterJoinVO> vrIdSearch;
private final SearchBuilder<DomainRouterJoinVO> vrIdTrafficSearch;
protected DomainRouterJoinDaoImpl() {
@ -73,6 +74,11 @@ public class DomainRouterJoinDaoImpl extends GenericDaoBase<DomainRouterJoinVO,
vrIdSearch.and("id", vrIdSearch.entity().getId(), SearchCriteria.Op.EQ);
vrIdSearch.done();
vrIdTrafficSearch = createSearchBuilder();
vrIdTrafficSearch.and("id", vrIdTrafficSearch.entity().getId(), SearchCriteria.Op.EQ);
vrIdTrafficSearch.and("trafficType", vrIdTrafficSearch.entity().getTrafficType(), SearchCriteria.Op.IN);
vrIdTrafficSearch.done();
_count = "select count(distinct id) from domain_router_view WHERE ";
}
@ -118,7 +124,9 @@ public class DomainRouterJoinDaoImpl extends GenericDaoBase<DomainRouterJoinVO,
routerResponse.setRequiresUpgrade(true);
}
routerResponse.setHypervisor(router.getHypervisorType().toString());
if (router.getHypervisorType() != null) {
routerResponse.setHypervisor(router.getHypervisorType().toString());
}
routerResponse.setHasAnnotation(annotationDao.hasAnnotations(router.getUuid(), AnnotationService.EntityType.VR.name(),
_accountMgr.isRootAdmin(CallContext.current().getCallingAccount().getId())));
@ -183,6 +191,9 @@ public class DomainRouterJoinDaoImpl extends GenericDaoBase<DomainRouterJoinVO,
if (router.getGuestType() != null) {
nicResponse.setType(router.getGuestType().toString());
}
if (router.getMtu() != null){
nicResponse.setMtu(router.getMtu());
}
nicResponse.setIsDefault(router.isDefaultNic());
nicResponse.setObjectName("nic");
routerResponse.addNic(nicResponse);
@ -276,6 +287,9 @@ public class DomainRouterJoinDaoImpl extends GenericDaoBase<DomainRouterJoinVO,
if (vr.getGuestType() != null) {
nicResponse.setType(vr.getGuestType().toString());
}
if (vr.getMtu() != null) {
nicResponse.setMtu(vr.getMtu());
}
nicResponse.setIsDefault(vr.isDefaultNic());
nicResponse.setObjectName("nic");
vrData.addNic(nicResponse);
@ -327,6 +341,14 @@ public class DomainRouterJoinDaoImpl extends GenericDaoBase<DomainRouterJoinVO,
return uvList;
}
@Override
public List<DomainRouterJoinVO> getRouterByIdAndTrafficType(Long id, TrafficType... trafficType) {
SearchCriteria<DomainRouterJoinVO> sc = vrIdTrafficSearch.create();
sc.setParameters("id", id);
sc.setParameters("trafficType", (Object[])trafficType);
return searchIncludingRemoved(sc, null, null, false);
}
@Override
public List<DomainRouterJoinVO> newDomainRouterView(VirtualRouter vr) {

View File

@ -254,6 +254,9 @@ public class DomainRouterJoinVO extends BaseViewVO implements ControlledViewEnti
@Column(name = "software_version")
private String softwareVersion;
@Column(name = "mtu")
private Integer mtu;
public DomainRouterJoinVO() {
}
@ -541,4 +544,8 @@ public class DomainRouterJoinVO extends BaseViewVO implements ControlledViewEnti
public String getSoftwareVersion() {
return softwareVersion;
}
public Integer getMtu() {
return mtu;
}
}

View File

@ -143,6 +143,7 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
to.setIp6Address(profile.getIPv6Address());
to.setIp6Gateway(profile.getIPv6Gateway());
to.setIp6Cidr(profile.getIPv6Cidr());
to.setMtu(profile.getMtu());
to.setIp6Dns1(profile.getIPv6Dns1());
to.setIp6Dns2(profile.getIPv6Dns2());

View File

@ -1801,9 +1801,10 @@ 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,
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 "

View File

@ -299,7 +299,8 @@ public class NetworkMigrationManagerImpl implements NetworkMigrationManager {
try {
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());
vpc.getIp6Dns1(), vpc.getIp6Dns2(), vpc.isDisplay(), vpc.getPublicMtu());
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

@ -2177,6 +2177,12 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel, Confi
NicProfile profile =
new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), networkRate, isSecurityGroupSupportedInNetwork(network), getNetworkTag(
vm.getHypervisorType(), network));
if (network.getTrafficType() == TrafficType.Public && network.getPublicMtu() != null) {
profile.setMtu(network.getPublicMtu());
}
if (network.getTrafficType() == TrafficType.Guest && network.getPrivateMtu() != null) {
profile.setMtu(network.getPrivateMtu());
}
// guru.updateNicProfile(profile, network);
return profile;
}

View File

@ -43,6 +43,7 @@ import javax.naming.ConfigurationException;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
import org.apache.cloudstack.alert.AlertService;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.command.admin.address.ReleasePodIpCmdByAdmin;
import org.apache.cloudstack.api.command.admin.network.CreateNetworkCmdByAdmin;
@ -77,8 +78,18 @@ import org.apache.commons.lang3.EnumUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import com.cloud.agent.AgentManager;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.to.IpAddressTO;
import com.cloud.agent.manager.Commands;
import com.cloud.alert.AlertManager;
import com.cloud.api.ApiDBUtils;
import com.cloud.api.query.dao.DomainRouterJoinDao;
import com.cloud.api.query.vo.DomainRouterJoinVO;
import com.cloud.configuration.Config;
import com.cloud.configuration.ConfigurationManager;
import com.cloud.configuration.Resource;
@ -148,12 +159,16 @@ import com.cloud.network.dao.PhysicalNetworkServiceProviderVO;
import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao;
import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO;
import com.cloud.network.dao.PhysicalNetworkVO;
import com.cloud.network.dao.VirtualRouterProviderDao;
import com.cloud.network.element.NetworkElement;
import com.cloud.network.element.OvsProviderVO;
import com.cloud.network.element.VirtualRouterElement;
import com.cloud.network.element.VpcVirtualRouterElement;
import com.cloud.network.guru.GuestNetworkGuru;
import com.cloud.network.guru.NetworkGuru;
import com.cloud.network.router.CommandSetupHelper;
import com.cloud.network.router.NetworkHelper;
import com.cloud.network.router.VirtualRouter;
import com.cloud.network.rules.FirewallRule.Purpose;
import com.cloud.network.rules.FirewallRuleVO;
import com.cloud.network.rules.RulesManager;
@ -163,6 +178,7 @@ import com.cloud.network.vpc.NetworkACL;
import com.cloud.network.vpc.PrivateIpVO;
import com.cloud.network.vpc.Vpc;
import com.cloud.network.vpc.VpcManager;
import com.cloud.network.vpc.VpcVO;
import com.cloud.network.vpc.dao.NetworkACLDao;
import com.cloud.network.vpc.dao.PrivateIpDao;
import com.cloud.network.vpc.dao.VpcDao;
@ -210,6 +226,7 @@ import com.cloud.utils.db.TransactionStatus;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.exception.ExceptionUtil;
import com.cloud.utils.net.NetUtils;
import com.cloud.vm.DomainRouterVO;
import com.cloud.vm.Nic;
import com.cloud.vm.NicProfile;
import com.cloud.vm.NicSecondaryIp;
@ -223,6 +240,7 @@ import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineManager;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.VirtualMachineProfileImpl;
import com.cloud.vm.dao.DomainRouterDao;
import com.cloud.vm.dao.NicDao;
import com.cloud.vm.dao.NicSecondaryIpDao;
import com.cloud.vm.dao.NicSecondaryIpVO;
@ -236,9 +254,9 @@ import com.googlecode.ipv6.IPv6Address;
public class NetworkServiceImpl extends ManagerBase implements NetworkService, Configurable {
private static final Logger s_logger = Logger.getLogger(NetworkServiceImpl.class);
private static final ConfigKey<Boolean> AllowDuplicateNetworkName = new ConfigKey<Boolean>("Advanced", Boolean.class,
private static final ConfigKey<Boolean> AllowDuplicateNetworkName = new ConfigKey<>("Advanced", Boolean.class,
"allow.duplicate.networkname", "true", "Allow creating networks with same name in account", true, ConfigKey.Scope.Account);
private static final ConfigKey<Boolean> AllowEmptyStartEndIpAddress = new ConfigKey<Boolean>("Advanced", Boolean.class,
private static final ConfigKey<Boolean> AllowEmptyStartEndIpAddress = new ConfigKey<>("Advanced", Boolean.class,
"allow.empty.start.end.ipaddress", "true", "Allow creating network without mentioning start and end IP address",
true, ConfigKey.Scope.Account);
private static final long MIN_VLAN_ID = 0L;
@ -365,6 +383,22 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
Ipv6Service ipv6Service;
@Inject
Ipv6GuestPrefixSubnetNetworkMapDao ipv6GuestPrefixSubnetNetworkMapDao;
@Inject
AlertManager alertManager;
@Inject
VirtualRouterProviderDao vrProviderDao;
@Inject
DomainRouterDao routerDao;
@Inject
DomainRouterJoinDao routerJoinDao;
@Inject
CommandSetupHelper commandSetupHelper;
@Inject
AgentManager agentManager;
@Autowired
@Qualifier("networkHelper")
protected NetworkHelper networkHelper;
int _cidrLimit;
boolean _allowSubdomainNetworkAccess;
@ -1338,6 +1372,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
String externalId = cmd.getExternalId();
String isolatedPvlanType = cmd.getIsolatedPvlanType();
Long associatedNetworkId = cmd.getAssociatedNetworkId();
Integer publicMtu = cmd.getPublicMtu();
Integer privateMtu = cmd.getPrivateMtu();
String ip4Dns1 = cmd.getIp4Dns1();
String ip4Dns2 = cmd.getIp4Dns2();
String ip6Dns1 = cmd.getIp6Dns1();
@ -1664,6 +1700,9 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
throwInvalidIdException("Network offering with specified id doesn't support adding multiple ip ranges", ntwkOff.getUuid(), "networkOfferingId");
}
Pair<Integer, Integer> interfaceMTUs = validateMtuConfig(publicMtu, privateMtu, zoneId);
mtuCheckForVpcNetwork(vpcId, interfaceMTUs, publicMtu, privateMtu);
Network associatedNetwork = null;
if (associatedNetworkId != null) {
if (vlanId != null) {
@ -1682,7 +1721,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,
domainId, isDomainSpecific, subdomainAccess, vpcId, startIPv6, endIPv6, ip6Gateway, ip6Cidr, displayNetwork, aclId, secondaryVlanId, privateVlanType, ntwkOff, pNtwk, aclType, owner, cidr, createVlan,
externalId, routerIp, routerIpv6, associatedNetwork, ip4Dns1, ip4Dns2, ip6Dns1, ip6Dns2);
externalId, routerIp, routerIpv6, associatedNetwork, ip4Dns1, ip4Dns2, ip6Dns1, ip6Dns2, interfaceMTUs);
if (hideIpAddressUsage) {
_networkDetailsDao.persist(new NetworkDetailVO(network.getId(), Network.hideIpAddressUsage, String.valueOf(hideIpAddressUsage), false));
@ -1699,6 +1738,59 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
return network;
}
protected void mtuCheckForVpcNetwork(Long vpcId, Pair<Integer, Integer> interfaceMTUs, Integer publicMtu, Integer privateMtu) {
if (vpcId != null && publicMtu != null) {
VpcVO vpc = _vpcDao.findById(vpcId);
if (vpc == null) {
throw new CloudRuntimeException(String.format("VPC with id %s not found", vpcId));
}
s_logger.warn(String.format("VPC public MTU already set at VPC creation phase to: %s. Ignoring public MTU " +
"passed during VPC network tier creation ", vpc.getPublicMtu()));
interfaceMTUs.set(vpc.getPublicMtu(), privateMtu);
}
}
protected Pair<Integer, Integer> validateMtuConfig(Integer publicMtu, Integer privateMtu, Long zoneId) {
Integer vrMaxMtuForPublicIfaces = VRPublicInterfaceMtu.valueIn(zoneId);
Integer vrMaxMtuForPrivateIfaces = VRPrivateInterfaceMtu.valueIn(zoneId);
if (!AllowUsersToSpecifyVRMtu.valueIn(zoneId)) {
privateMtu = vrMaxMtuForPrivateIfaces;
publicMtu = vrMaxMtuForPublicIfaces;
return new Pair<>(publicMtu, privateMtu);
}
if (publicMtu > vrMaxMtuForPublicIfaces) {
String subject = "Incorrect MTU configured on network for public interfaces of the VR";
String message = String.format("Configured MTU for network VR's public interfaces exceeds the upper limit " +
"enforced by zone level setting: %s. VR's public interfaces can be configured with a maximum MTU of %s", VRPublicInterfaceMtu.key(), VRPublicInterfaceMtu.valueIn(zoneId));
s_logger.warn(message);
alertManager.sendAlert(AlertService.AlertType.ALERT_TYPE_VR_PUBLIC_IFACE_MTU, zoneId, null, subject, message);
publicMtu = vrMaxMtuForPublicIfaces;
} else if (publicMtu < MINIMUM_MTU) {
String subject = "Incorrect MTU configured on network for public interfaces of the VR";
String message = String.format("Configured MTU for network VR's public interfaces is lesser than the supported minimum of %s.", MINIMUM_MTU);
s_logger.warn(message);
alertManager.sendAlert(AlertService.AlertType.ALERT_TYPE_VR_PUBLIC_IFACE_MTU, zoneId, null, subject, message);
publicMtu = MINIMUM_MTU;
}
if (privateMtu > vrMaxMtuForPrivateIfaces) {
String subject = "Incorrect MTU configured on network for private interface of the VR";
String message = String.format("Configured MTU for network VR's public interfaces exceeds the upper limit " +
"enforced by zone level setting: %s. VR's public interfaces can be configured with a maximum MTU of %s", VRPublicInterfaceMtu.key(), VRPublicInterfaceMtu.valueIn(zoneId));
s_logger.warn(message);
alertManager.sendAlert(AlertService.AlertType.ALERT_TYPE_VR_PRIVATE_IFACE_MTU, zoneId, null, subject, message);
privateMtu = vrMaxMtuForPrivateIfaces;
} else if (privateMtu < MINIMUM_MTU) {
String subject = "Incorrect MTU configured on network for private interfaces of the VR";
String message = String.format("Configured MTU for network VR's private interfaces is lesser than the supported minimum of %s.", MINIMUM_MTU);
s_logger.warn(message);
alertManager.sendAlert(AlertService.AlertType.ALERT_TYPE_VR_PRIVATE_IFACE_MTU, zoneId, null, subject, message);
privateMtu = MINIMUM_MTU;
}
return new Pair<>(publicMtu, privateMtu);
}
private Network implementAssociatedNetwork(Long associatedNetworkId, Account caller, Account owner, DataCenter zone, Long domainId, Long accountId,
String cidr, String startIp, String endIp) throws InsufficientCapacityException {
Network associatedNetwork = _networksDao.findById(associatedNetworkId);
@ -1824,7 +1916,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, final String ip4Dns1, final String ip4Dns2, final String ip6Dns1, final String ip6Dns2) throws InsufficientCapacityException, ResourceAllocationException {
final Network associatedNetwork, final String ip4Dns1, final String ip4Dns2, final String ip6Dns1, final String ip6Dns2, Pair<Integer, Integer> vrIfaceMTUs) throws InsufficientCapacityException, ResourceAllocationException {
try {
Network network = Transaction.execute(new TransactionCallbackWithException<Network, Exception>() {
@Override
@ -1883,7 +1975,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, ip4Dns1, ip4Dns2, ip6Dns1, ip6Dns2);
subdomainAccess, vpcId, aclId, caller, displayNetwork, externalId, ip6Gateway, ip6Cidr, ip4Dns1, ip4Dns2, ip6Dns1, ip6Dns2, vrIfaceMTUs);
} else {
if (_configMgr.isOfferingForVpc(ntwkOff)) {
throw new InvalidParameterValueException("Network offering can be used for VPC networks only");
@ -1891,9 +1983,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
if (ntwkOff.isInternalLb()) {
throw new InvalidParameterValueException("Internal Lb can be enabled on vpc networks only");
}
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, ip4Dns1, ip4Dns2, ip6Dns1, ip6Dns2);
zoneId, aclType, subdomainAccess, vpcId, ip6Gateway, ip6Cidr, displayNetwork, isolatedPvlan, isolatedPvlanType, externalId, routerIp, routerIpv6, ip4Dns1, ip4Dns2, ip6Dns1, ip6Dns2, vrIfaceMTUs);
}
if (createVlan && network != null) {
@ -2657,6 +2748,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
Boolean displayNetwork = cmd.getDisplayNetwork();
String customId = cmd.getCustomId();
boolean updateInSequence = cmd.getUpdateInSequence();
Integer publicMtu = cmd.getPublicMtu();
Integer privateMtu = cmd.getPrivateMtu();
boolean forced = cmd.getForced();
String ip4Dns1 = cmd.getIp4Dns1();
String ip4Dns2 = cmd.getIp4Dns2();
@ -2797,7 +2890,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
final Map<String, String> newSvcProviders = networkOfferingChanged
? _networkMgr.finalizeServicesAndProvidersForNetwork(_entityMgr.findById(NetworkOffering.class, networkOfferingId), network.getPhysicalNetworkId())
: new HashMap<String, String>();
: new HashMap<String, String>();
// don't allow to modify network domain if the service is not supported
if (domainSuffix != null) {
@ -2918,6 +3011,53 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
s_logger.info("IP Reservation has been applied. The new CIDR for Guests Vms is " + guestVmCidr);
}
Pair<Integer, Integer> mtus = validateMtuOnUpdate(network, dc.getId(), publicMtu, privateMtu);
publicMtu = mtus.first();
privateMtu = mtus.second();
// List all routers for the given network:
List<DomainRouterVO> routers = routerDao.findByNetwork(networkId);
// Create Map to store the IPAddress List for each router
Map<Long, Set<IpAddressTO>> routersToIpList = new HashMap<>();
for (DomainRouterVO routerVO : routers) {
Set<IpAddressTO> ips = new HashSet<>();
List<DomainRouterJoinVO> routerJoinVOS = routerJoinDao.getRouterByIdAndTrafficType(routerVO.getId(), TrafficType.Guest, TrafficType.Public);
for (DomainRouterJoinVO router : routerJoinVOS) {
IpAddressTO ip = null;
if (router.getTrafficType() == TrafficType.Guest && privateMtu != null) {
ip = new IpAddressTO(router.getIpAddress(), privateMtu, router.getNetmask());
ip.setTrafficType(TrafficType.Guest);
} else if (router.getTrafficType() == TrafficType.Public && publicMtu != null) {
ip = new IpAddressTO(router.getIpAddress(), publicMtu, router.getNetmask());
ip.setTrafficType(TrafficType.Public);
}
if (ip != null) {
ips.add(ip);
}
}
if (network.getGuestType() == GuestType.Isolated && network.getVpcId() == null && publicMtu != null) {
List<IPAddressVO> addrs = _ipAddressDao.listByNetworkId(networkId);
for(IPAddressVO addr : addrs) {
VlanVO vlan = _vlanDao.findById(addr.getVlanId());
IpAddressTO to = new IpAddressTO(addr.getAddress().addr(), publicMtu, vlan.getVlanNetmask());
ips.add(to);
}
}
if (!ips.isEmpty()) {
routersToIpList.put(routerVO.getId(), ips);
}
}
if (!routersToIpList.isEmpty() && !restartNetwork) {
boolean success = updateMtuOnVr(routersToIpList);
if (success) {
updateNetworkDetails(routersToIpList, network, publicMtu, privateMtu);
} else {
throw new CloudRuntimeException("Failed to update MTU on the network");
}
}
ReservationContext context = new ReservationContextImpl(null, null, callerUser, callerAccount);
// 1) Shutdown all the elements and cleanup all the rules. Don't allow to shutdown network in intermediate
// states - Shutdown and Implementing
@ -3097,6 +3237,98 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
return getNetwork(network.getId());
}
protected Pair<Integer, Integer> validateMtuOnUpdate(NetworkVO network, Long zoneId, Integer publicMtu, Integer privateMtu) {
if (!AllowUsersToSpecifyVRMtu.valueIn(zoneId)) {
return new Pair<>(null, null);
}
if (publicMtu != null) {
if (publicMtu > VRPublicInterfaceMtu.valueIn(zoneId)) {
publicMtu = VRPublicInterfaceMtu.valueIn(zoneId);
} else if (publicMtu < MINIMUM_MTU) {
String subject = "Incorrect MTU configured on network for public interfaces of the VR";
String message = String.format("Configured MTU for network VR's public interfaces is lesser than the supported minimum of %s.", MINIMUM_MTU);
s_logger.warn(message);
alertManager.sendAlert(AlertService.AlertType.ALERT_TYPE_VR_PUBLIC_IFACE_MTU, zoneId, null, subject, message);
publicMtu = MINIMUM_MTU;
}
}
if (privateMtu != null) {
if (privateMtu > VRPrivateInterfaceMtu.valueIn(zoneId)) {
privateMtu = VRPrivateInterfaceMtu.valueIn(zoneId);
} else if (privateMtu < MINIMUM_MTU) {
String subject = "Incorrect MTU configured on network for private interfaces of the VR";
String message = String.format("Configured MTU for network VR's private interfaces is lesser than the supported minimum of %s.", MINIMUM_MTU);
s_logger.warn(message);
alertManager.sendAlert(AlertService.AlertType.ALERT_TYPE_VR_PRIVATE_IFACE_MTU, zoneId, null, subject, message);
privateMtu = MINIMUM_MTU;
}
}
if (publicMtu != null && network.getVpcId() != null) {
s_logger.warn("Cannot update VPC public interface MTU via network tiers. " +
"Please update the public interface MTU via the VPC. Skipping.. ");
publicMtu = null;
}
return new Pair<>(publicMtu, privateMtu);
}
private void updateNetworkDetails(Map<Long, Set<IpAddressTO>> routerToIpList, NetworkVO network, Integer publicMtu, Integer privateMtu) {
for (Map.Entry<Long, Set<IpAddressTO>> routerEntrySet : routerToIpList.entrySet()) {
for (IpAddressTO ipAddress : routerEntrySet.getValue()) {
NicVO nicVO = _nicDao.findByInstanceIdAndIpAddressAndVmtype(routerEntrySet.getKey(), ipAddress.getPublicIp(), VirtualMachine.Type.DomainRouter);
if (nicVO != null) {
if (ipAddress.getTrafficType() == TrafficType.Guest) {
nicVO.setMtu(privateMtu);
} else {
nicVO.setMtu(publicMtu);
}
_nicDao.update(nicVO.getId(), nicVO);
}
}
}
if (publicMtu != null) {
network.setPublicMtu(publicMtu);
}
if (privateMtu != null) {
network.setPrivateMtu(privateMtu);
}
_networksDao.update(network.getId(), network);
}
protected boolean updateMtuOnVr(Map<Long, Set<IpAddressTO>> routersToIpList) {
boolean success = false;
for (Map.Entry<Long, Set<IpAddressTO>> routerEntrySet : routersToIpList.entrySet()) {
Long routerId = routerEntrySet.getKey();
DomainRouterVO router = routerDao.findById(routerId);
if (router == null) {
s_logger.error(String.format("Failed to find router with id: %s", routerId));
continue;
}
Commands cmds = new Commands(Command.OnError.Stop);
Map<String, String> state = new HashMap<>();
Set<IpAddressTO> ips = routerEntrySet.getValue();
state.put(ApiConstants.REDUNDANT_STATE, router.getRedundantState() != null ? router.getRedundantState().name() : VirtualRouter.RedundantState.UNKNOWN.name());
ips.forEach(ip -> ip.setDetails(state));
commandSetupHelper.setupUpdateNetworkCommands(router, ips, cmds);
try {
networkHelper.sendCommandsToRouter(router, cmds);
Answer updateNetworkAnswer = cmds.getAnswer("updateNetwork");
if (!(updateNetworkAnswer != null && updateNetworkAnswer.getResult())) {
s_logger.warn("Unable to update guest network on router " + router);
throw new CloudRuntimeException("Failed to update guest network with new MTU");
}
success = true;
} catch (ResourceUnavailableException e) {
s_logger.error(String.format("Failed to update network MTU for router %s due to %s", router, e.getMessage()));
success = false;
}
}
return success;
}
private void updateNetworkIpv6(NetworkVO network, Long networkOfferingId) {
boolean isIpv6Supported = _networkOfferingDao.isIpv6Supported(network.getNetworkOfferingId());
boolean isIpv6SupportedNew = _networkOfferingDao.isIpv6Supported(networkOfferingId);
@ -5472,6 +5704,6 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
@Override
public ConfigKey<?>[] getConfigKeys() {
return new ConfigKey<?>[] {AllowDuplicateNetworkName, AllowEmptyStartEndIpAddress};
return new ConfigKey<?>[] {AllowDuplicateNetworkName, AllowEmptyStartEndIpAddress, VRPrivateInterfaceMtu, VRPublicInterfaceMtu, AllowUsersToSpecifyVRMtu};
}
}

View File

@ -220,6 +220,14 @@ public class DirectNetworkGuru extends AdapterBase implements NetworkGuru {
config.setRouterIpv6(userSpecified.getRouterIpv6());
}
if (userSpecified.getPublicMtu() != null) {
config.setPublicMtu(userSpecified.getPublicMtu());
}
if (userSpecified.getPrivateMtu() != null) {
config.setPrivateMtu(userSpecified.getPrivateMtu());
}
if (StringUtils.isNotBlank(userSpecified.getDns1())) {
config.setDns1(userSpecified.getDns1());
}

View File

@ -259,6 +259,8 @@ public abstract class GuestNetworkGuru extends AdapterBase implements NetworkGur
network.setPvlanType(userSpecified.getPvlanType());
}
}
network.setPublicMtu(userSpecified.getPublicMtu());
network.setPrivateMtu(userSpecified.getPrivateMtu());
if (StringUtils.isNotBlank(userSpecified.getDns1())) {
network.setDns1(userSpecified.getDns1());

View File

@ -23,9 +23,13 @@ import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
import com.cloud.agent.api.routing.UpdateNetworkCommand;
import com.cloud.network.dao.VirtualRouterProviderDao;
import com.cloud.network.vpc.VpcVO;
import com.cloud.domain.Domain;
import com.cloud.domain.dao.DomainDao;
import org.apache.cloudstack.api.ApiConstants;
@ -201,6 +205,8 @@ public class CommandSetupHelper {
private NetworkDetailsDao networkDetailsDao;
@Inject
Ipv6Service ipv6Service;
@Inject
VirtualRouterProviderDao vrProviderDao;
@Autowired
@Qualifier("networkHelper")
@ -834,8 +840,16 @@ public class CommandSetupHelper {
final IpAddressTO ip = new IpAddressTO(ipAddr.getAccountId(), ipAddr.getAddress().addr(), add, firstIP, ipAddr.isSourceNat(), BroadcastDomainType.fromString(ipAddr.getVlanTag()).toString(), ipAddr.getGateway(),
ipAddr.getNetmask(), macAddress, networkRate, ipAddr.isOneToOneNat());
setIpAddressNetworkParams(ip, network, router);
if (network.getPublicMtu() != null) {
ip.setMtu(network.getPublicMtu());
}
if (router.getVpcId() != null) {
VpcVO vpc = _vpcDao.findById(router.getVpcId());
if (vpc != null) {
ip.setMtu(vpc.getPublicMtu());
}
}
ipsToSend[i++] = ip;
if (ipAddr.isSourceNat()) {
sourceNatIpAdd = new Pair<IpAddressTO, Long>(ip, ipAddr.getNetworkId());
@ -958,6 +972,15 @@ public class CommandSetupHelper {
final IpAddressTO ip = new IpAddressTO(ipAddr.getAccountId(), ipAddr.getAddress().addr(), add, firstIP, sourceNat, vlanId, vlanGateway, vlanNetmask,
vifMacAddress, networkRate, ipAddr.isOneToOneNat());
NetworkVO networkVO = _networkDao.findById(ipAddr.getAssociatedWithNetworkId());
if (networkVO != null && networkVO.getPublicMtu() != null) {
ip.setMtu(networkVO.getPublicMtu());
} else if (router.getVpcId() != null) {
VpcVO vpc = _vpcDao.findById(router.getVpcId());
if (vpc != null) {
ip.setMtu(vpc.getPublicMtu());
}
}
setIpAddressNetworkParams(ip, network, router);
if (router.getHypervisorType() == Hypervisor.HypervisorType.VMware) {
@ -1096,7 +1119,9 @@ public class CommandSetupHelper {
final Network network = _networkModel.getNetwork(ipAddr.getNetworkId());
final IpAddressTO ip = new IpAddressTO(Account.ACCOUNT_ID_SYSTEM, ipAddr.getIpAddress(), add, false, ipAddr.getSourceNat(), ipAddr.getBroadcastUri(),
ipAddr.getGateway(), ipAddr.getNetmask(), ipAddr.getMacAddress(), null, false);
if (network.getPrivateMtu() != null) {
ip.setMtu(network.getPublicMtu());
}
setIpAddressNetworkParams(ip, network, router);
ipsToSend[i++] = ip;
@ -1148,7 +1173,6 @@ public class CommandSetupHelper {
final String dhcpRange = getGuestDhcpRange(guestNic, network, _entityMgr.findById(DataCenter.class, network.getDataCenterId()));
final NicProfile nicProfile = _networkModel.getNicProfile(router, nic.getNetworkId(), null);
final SetupGuestNetworkCommand setupCmd = new SetupGuestNetworkCommand(dhcpRange, networkDomain, router.getIsRedundantRouter(), defaultDns1, defaultDns2, add, _itMgr.toNicTO(nicProfile,
router.getHypervisorType()));
@ -1165,7 +1189,7 @@ public class CommandSetupHelper {
setupCmd.setAccessDetail(NetworkElementCommand.GUEST_BRIDGE, brd);
setupCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
if (network.getBroadcastDomainType() == BroadcastDomainType.Vlan) {
if (network.getBroadcastDomainType() == BroadcastDomainType.Vlan && network.getBroadcastUri() != null) {
final long guestVlanTag = Long.parseLong(BroadcastDomainType.Vlan.getValueFrom(network.getBroadcastUri()));
setupCmd.setAccessDetail(NetworkElementCommand.GUEST_VLAN_TAG, String.valueOf(guestVlanTag));
}
@ -1312,7 +1336,6 @@ public class CommandSetupHelper {
ipAddress.setPrivateGateway(false);
}
ipAddress.setNetworkName(_networkModel.getNetworkTag(router.getHypervisorType(), network));
final NetworkOfferingVO networkOfferingVO = _networkOfferingDao.findById(network.getNetworkOfferingId());
NicTO nicTO = new NicTO();
nicTO.setMac(ipAddress.getVifMacAddress());
@ -1349,4 +1372,15 @@ public class CommandSetupHelper {
return details;
}
public void setupUpdateNetworkCommands(final VirtualRouter router, final Set<IpAddressTO> ips, Commands cmds) {
IpAddressTO[] ipsToSend = ips.toArray(new IpAddressTO[0]);
if (!ips.isEmpty()) {
UpdateNetworkCommand cmd = new UpdateNetworkCommand(ipsToSend);
cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId()));
cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
cmds.addCommand("updateNetwork", cmd);
}
}
}

View File

@ -2033,12 +2033,16 @@ Configurable, StateListener<VirtualMachine.State, VirtualMachine.Event, VirtualM
}
} else if (nic.getTrafficType() == TrafficType.Guest) {
s_logger.info("Guest IP : " + nic.getIPv4Address());
dnsProvided = _networkModel.isProviderSupportServiceInNetwork(nic.getNetworkId(), Service.Dns, Provider.VirtualRouter);
dhcpProvided = _networkModel.isProviderSupportServiceInNetwork(nic.getNetworkId(), Service.Dhcp, Provider.VirtualRouter);
buf.append(" privateMtu=").append(nic.getMtu());
// build bootloader parameter for the guest
buf.append(createGuestBootLoadArgs(nic, defaultDns1, defaultDns2, router));
} else if (nic.getTrafficType() == TrafficType.Public) {
s_logger.info("Public IP : " + nic.getIPv4Address());
publicNetwork = true;
buf.append(" publicMtu=").append(nic.getMtu());
}
}
@ -2304,6 +2308,18 @@ Configurable, StateListener<VirtualMachine.State, VirtualMachine.Event, VirtualM
return true;
}
private Provider getVrProvider(DomainRouterVO router) {
final VirtualRouterProvider vrProvider = _vrProviderDao.findById(router.getElementId());
if (vrProvider == null) {
throw new CloudRuntimeException("Cannot find related virtual router provider of router: " + router.getHostName());
}
final Provider provider = Network.Provider.getProvider(vrProvider.getType().toString());
if (provider == null) {
throw new CloudRuntimeException("Cannot find related provider of virtual router provider: " + vrProvider.getType().toString());
}
return provider;
}
@Override
public boolean finalizeCommandsOnStart(final Commands cmds, final VirtualMachineProfile profile) {
final DomainRouterVO router = _routerDao.findById(profile.getId());
@ -2323,14 +2339,7 @@ Configurable, StateListener<VirtualMachine.State, VirtualMachine.Event, VirtualM
reprogramGuestNtwks = false;
}
final VirtualRouterProvider vrProvider = _vrProviderDao.findById(router.getElementId());
if (vrProvider == null) {
throw new CloudRuntimeException("Cannot find related virtual router provider of router: " + router.getHostName());
}
final Provider provider = Network.Provider.getProvider(vrProvider.getType().toString());
if (provider == null) {
throw new CloudRuntimeException("Cannot find related provider of virtual router provider: " + vrProvider.getType().toString());
}
final Provider provider = getVrProvider(router);
final List<Long> routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId());
for (final Long guestNetworkId : routerGuestNtwkIds) {

View File

@ -151,6 +151,11 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian
_routerDao.addRouterToGuestNetwork(router, network);
final NicProfile guestNic = _itMgr.addVmToNetwork(router, network, null);
if (network.getVpcId() != null) {
VpcVO vpc = _vpcDao.findById(network.getVpcId());
guestNic.setMtu(vpc.getPublicMtu());
}
// 2) setup guest network
if (guestNic != null) {
result = setupVpcGuestNetwork(network, router, true, guestNic);
@ -275,7 +280,7 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian
final StringBuilder buf = profile.getBootArgsBuilder();
final Vpc vpc = _entityMgr.findById(Vpc.class, vpcId);
buf.append(" vpccidr=" + vpc.getCidr() + " domain=" + vpc.getNetworkDomain());
buf.append(" publicMtu=").append(vpc.getPublicMtu());
buf.append(" dns1=").append(defaultDns1);
if (defaultDns2 != null) {
buf.append(" dns2=").append(defaultDns2);

View File

@ -27,6 +27,7 @@ import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
@ -40,6 +41,7 @@ import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.alert.AlertService;
import org.apache.cloudstack.annotation.AnnotationService;
import org.apache.cloudstack.annotation.dao.AnnotationDao;
import org.apache.cloudstack.api.ApiConstants;
@ -60,7 +62,14 @@ import org.apache.cloudstack.query.QueryService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.to.IpAddressTO;
import com.cloud.agent.manager.Commands;
import com.cloud.alert.AlertManager;
import com.cloud.api.query.dao.VpcOfferingJoinDao;
import com.cloud.api.query.vo.VpcOfferingJoinVO;
import com.cloud.configuration.Config;
@ -106,6 +115,8 @@ import com.cloud.network.dao.NetworkVO;
import com.cloud.network.element.NetworkElement;
import com.cloud.network.element.StaticNatServiceProvider;
import com.cloud.network.element.VpcProvider;
import com.cloud.network.router.CommandSetupHelper;
import com.cloud.network.router.NetworkHelper;
import com.cloud.network.router.VpcVirtualNetworkApplianceManager;
import com.cloud.network.vpc.VpcOffering.State;
import com.cloud.network.vpc.dao.NetworkACLDao;
@ -155,9 +166,12 @@ import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.exception.ExceptionUtil;
import com.cloud.utils.net.NetUtils;
import com.cloud.vm.DomainRouterVO;
import com.cloud.vm.NicVO;
import com.cloud.vm.ReservationContext;
import com.cloud.vm.ReservationContextImpl;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.dao.DomainRouterDao;
import com.cloud.vm.dao.NicDao;
public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvisioningService, VpcService {
private static final Logger s_logger = Logger.getLogger(VpcManagerImpl.class);
@ -179,7 +193,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
@Inject
VpcOfferingServiceMapDao _vpcOffSvcMapDao;
@Inject
VpcDao _vpcDao;
VpcDao vpcDao;
@Inject
ConfigurationDao _configDao;
@Inject
@ -229,13 +243,22 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
@Inject
VpcVirtualNetworkApplianceManager _routerService;
@Inject
DomainRouterDao _routerDao;
DomainRouterDao routerDao;
@Inject
DomainDao domainDao;
@Inject
private AnnotationDao annotationDao;
@Inject
NetworkOfferingDao _networkOfferingDao;
@Inject
NicDao nicDao;
@Inject
AlertManager alertManager;
@Inject
CommandSetupHelper commandSetupHelper;
@Autowired
@Qualifier("networkHelper")
protected NetworkHelper networkHelper;
@Inject
private VpcPrivateGatewayTransactionCallable vpcTxCallable;
@ -357,7 +380,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
final SearchBuilder<VlanVO> virtualNetworkVlanSB = _vlanDao.createSearchBuilder();
virtualNetworkVlanSB.and("vlanType", virtualNetworkVlanSB.entity().getVlanType(), Op.EQ);
IpAddressSearch
.join("virtualNetworkVlanSB", virtualNetworkVlanSB, IpAddressSearch.entity().getVlanId(), virtualNetworkVlanSB.entity().getId(), JoinBuilder.JoinType.INNER);
.join("virtualNetworkVlanSB", virtualNetworkVlanSB, IpAddressSearch.entity().getVlanId(), virtualNetworkVlanSB.entity().getId(), JoinBuilder.JoinType.INNER);
IpAddressSearch.done();
return true;
@ -422,7 +445,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
@Override
@ActionEvent(eventType = EventTypes.EVENT_VPC_OFFERING_CREATE, eventDescription = "creating vpc offering", create = true)
public VpcOffering createVpcOffering(final String name, final String displayText, final List<String> supportedServices, final Map<String, List<String>> serviceProviders,
final Map serviceCapabilityList, final NetUtils.InternetProtocol internetProtocol, final Long serviceOfferingId, List<Long> domainIds, List<Long> zoneIds, State state) {
final Map serviceCapabilityList, final NetUtils.InternetProtocol internetProtocol, final Long serviceOfferingId, List<Long> domainIds, List<Long> zoneIds, State state) {
if (!Ipv6Service.Ipv6OfferingCreationEnabled.value() && !(internetProtocol == null || NetUtils.InternetProtocol.IPv4.equals(internetProtocol))) {
throw new InvalidParameterValueException(String.format("Configuration %s needs to be enabled for creating IPv6 supported VPC offering", Ipv6Service.Ipv6OfferingCreationEnabled.key()));
@ -534,8 +557,8 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
@DB
protected VpcOfferingVO createVpcOffering(final String name, final String displayText, final Map<Network.Service, Set<Network.Provider>> svcProviderMap,
final boolean isDefault, final State state, final Long serviceOfferingId, final boolean supportsDistributedRouter, final boolean offersRegionLevelVPC,
final boolean redundantRouter) {
final boolean isDefault, final State state, final Long serviceOfferingId, final boolean supportsDistributedRouter, final boolean offersRegionLevelVPC,
final boolean redundantRouter) {
return Transaction.execute(new TransactionCallback<VpcOfferingVO>() {
@Override
@ -658,7 +681,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
@Override
public Vpc getActiveVpc(final long vpcId) {
return _vpcDao.getActiveVpcById(vpcId);
return vpcDao.getActiveVpcById(vpcId);
}
@Override
@ -822,7 +845,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
// don't allow to delete vpc offering if it's in use by existing vpcs
// (the offering can be disabled though)
final int vpcCount = _vpcDao.getVpcCountByOfferingId(offId);
final int vpcCount = vpcDao.getVpcCountByOfferingId(offId);
if (vpcCount > 0) {
throw new InvalidParameterValueException("Can't delete vpc offering " + offId + " as its used by " + vpcCount + " vpcs. "
+ "To make the network offering unavailable, disable it");
@ -982,7 +1005,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 String ip4Dns1, final String ip4Dns2, final String ip6Dns1, final String ip6Dns2, final Boolean displayVpc) throws ResourceAllocationException {
final String ip4Dns1, final String ip4Dns2, final String ip6Dns1, final String ip6Dns2, final Boolean displayVpc, Integer publicMtu) throws ResourceAllocationException {
final Account caller = CallContext.current().getCallingAccount();
final Account owner = _accountMgr.getAccount(vpcOwnerId);
@ -1034,11 +1057,28 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
}
}
if (publicMtu > NetworkService.VRPublicInterfaceMtu.valueIn(zoneId)) {
String subject = "Incorrect MTU configured on network for public interfaces of the VPC VR";
String message = String.format("Configured MTU for network VR's public interfaces exceeds the upper limit " +
"enforced by zone level setting: %s. VR's public interfaces can be configured with a maximum MTU of %s", NetworkService.VRPublicInterfaceMtu.key(),
NetworkService.VRPublicInterfaceMtu.valueIn(zoneId));
s_logger.warn(message);
alertManager.sendAlert(AlertService.AlertType.ALERT_TYPE_VR_PUBLIC_IFACE_MTU, zoneId, null, subject, message);
publicMtu = NetworkService.VRPublicInterfaceMtu.valueIn(zoneId);
} else if (publicMtu < NetworkService.MINIMUM_MTU) {
String subject = "Incorrect MTU configured on network for public interfaces of the VPC VR";
String message = String.format("Configured MTU for network VR's public interfaces is lesser than the supported minim MTU of %s", NetworkService.MINIMUM_MTU);
s_logger.warn(message);
alertManager.sendAlert(AlertService.AlertType.ALERT_TYPE_VR_PUBLIC_IFACE_MTU, zoneId, null, subject, message);
publicMtu = NetworkService.MINIMUM_MTU;
}
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(), ip4Dns1, ip4Dns2, ip6Dns1, ip6Dns2);
vpc.setPublicMtu(publicMtu);
return createVpc(displayVpc, vpc);
}
@ -1048,7 +1088,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
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());
cmd.getIp6Dns2(), cmd.isDisplay(), cmd.getPublicMtu());
}
@DB
@ -1078,7 +1118,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
vpc.setDisplay(displayVpc);
}
final VpcVO persistedVpc = _vpcDao.persist(vpc, finalizeServicesAndProvidersForVpc(vpc.getZoneId(), vpc.getVpcOfferingId()));
final VpcVO persistedVpc = vpcDao.persist(vpc, finalizeServicesAndProvidersForVpc(vpc.getZoneId(), vpc.getVpcOfferingId()));
_resourceLimitMgr.incrementResourceCount(vpc.getAccountId(), ResourceType.vpc);
s_logger.debug("Created VPC " + persistedVpc);
CallContext.current().putContextParameter(Vpc.class, persistedVpc.getUuid());
@ -1124,7 +1164,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
final CallContext ctx = CallContext.current();
// Verify vpc id
final Vpc vpc = _vpcDao.findById(vpcId);
final Vpc vpc = vpcDao.findById(vpcId);
if (vpc == null) {
throw new InvalidParameterValueException("unable to find VPC id=" + vpcId);
}
@ -1153,13 +1193,13 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
// mark VPC as inactive
if (vpc.getState() != Vpc.State.Inactive) {
s_logger.debug("Updating VPC " + vpc + " with state " + Vpc.State.Inactive + " as a part of vpc delete");
final VpcVO vpcVO = _vpcDao.findById(vpc.getId());
final VpcVO vpcVO = vpcDao.findById(vpc.getId());
vpcVO.setState(Vpc.State.Inactive);
Transaction.execute(new TransactionCallbackNoReturn() {
@Override
public void doInTransactionWithoutResult(final TransactionStatus status) {
_vpcDao.update(vpc.getId(), vpcVO);
vpcDao.update(vpc.getId(), vpcVO);
// decrement resource count
_resourceLimitMgr.decrementResourceCount(vpc.getAccountId(), ResourceType.vpc);
@ -1181,7 +1221,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
// update the instance with removed flag only when the cleanup is
// executed successfully
if (_vpcDao.remove(vpc.getId())) {
if (vpcDao.remove(vpc.getId())) {
s_logger.debug("Vpc " + vpc + " is destroyed successfully");
return true;
} else {
@ -1192,19 +1232,19 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
@Override
@ActionEvent(eventType = EventTypes.EVENT_VPC_UPDATE, eventDescription = "updating vpc")
public Vpc updateVpc(final long vpcId, final String vpcName, final String displayText, final String customId, final Boolean displayVpc) {
public Vpc updateVpc(final long vpcId, final String vpcName, final String displayText, final String customId, final Boolean displayVpc, Integer mtu) {
CallContext.current().setEventDetails(" Id: " + vpcId);
final Account caller = CallContext.current().getCallingAccount();
// Verify input parameters
final VpcVO vpcToUpdate = _vpcDao.findById(vpcId);
final VpcVO vpcToUpdate = vpcDao.findById(vpcId);
if (vpcToUpdate == null) {
throw new InvalidParameterValueException("Unable to find vpc by id " + vpcId);
}
_accountMgr.checkAccess(caller, null, false, vpcToUpdate);
final VpcVO vpc = _vpcDao.createForUpdate(vpcId);
final VpcVO vpc = vpcDao.createForUpdate(vpcId);
if (vpcName != null) {
vpc.setName(vpcName);
@ -1222,19 +1262,110 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
vpc.setDisplay(displayVpc);
}
if (_vpcDao.update(vpcId, vpc)) {
mtu = validateMtu(vpcToUpdate, mtu);
if (mtu != null) {
updateMtuOfVpcNetwork(vpcToUpdate, vpc, mtu);
}
if (vpcDao.update(vpcId, vpc)) {
s_logger.debug("Updated VPC id=" + vpcId);
return _vpcDao.findById(vpcId);
return vpcDao.findById(vpcId);
} else {
return null;
}
}
protected Integer validateMtu(VpcVO vpcToUpdate, Integer mtu) {
Long zoneId = vpcToUpdate.getZoneId();
if (mtu == null || NetworkService.AllowUsersToSpecifyVRMtu.valueIn(zoneId)) {
return null;
}
if (mtu > NetworkService.VRPublicInterfaceMtu.valueIn(zoneId)) {
String subject = "Incorrect MTU configured on network for public interfaces of the VPC VR";
String message = String.format("Configured MTU for network VR's public interfaces exceeds the upper limit " +
"enforced by zone level setting: %s. VR's public interfaces can be configured with a maximum MTU of %s", NetworkService.VRPublicInterfaceMtu.key(),
NetworkService.VRPublicInterfaceMtu.valueIn(zoneId));
s_logger.warn(message);
alertManager.sendAlert(AlertService.AlertType.ALERT_TYPE_VR_PUBLIC_IFACE_MTU, zoneId, null, subject, message);
mtu = NetworkService.VRPublicInterfaceMtu.valueIn(zoneId);
} else if (mtu < NetworkService.MINIMUM_MTU) {
String subject = "Incorrect MTU configured on network for public interfaces of the VPC VR";
String message = String.format("Configured MTU for network VR's public interfaces is lesser than the minimum MTU of %s", NetworkService.MINIMUM_MTU );
s_logger.warn(message);
alertManager.sendAlert(AlertService.AlertType.ALERT_TYPE_VR_PUBLIC_IFACE_MTU, zoneId, null, subject, message);
mtu = NetworkService.MINIMUM_MTU;
}
if (Objects.equals(mtu, vpcToUpdate.getPublicMtu())) {
s_logger.info(String.format("Desired MTU of %s already configured on the VPC public interfaces", mtu));
mtu = null;
}
return mtu;
}
protected void updateMtuOfVpcNetwork(VpcVO vpcToUpdate, VpcVO vpc, Integer mtu) {
List<IPAddressVO> ipAddresses = _ipAddressDao.listByAssociatedVpc(vpcToUpdate.getId(), null);
long vpcId = vpcToUpdate.getId();
Set<IpAddressTO> ips = new HashSet<>(ipAddresses.size());
for (IPAddressVO ip : ipAddresses) {
VlanVO vlan = _vlanDao.findById(ip.getVlanId());
String vlanNetmask = vlan.getVlanNetmask();
IpAddressTO to = new IpAddressTO(ip.getAddress().addr(), mtu, vlanNetmask);
ips.add(to);
}
if (!ips.isEmpty()) {
boolean success = updateMtuOnVpcVr(vpcId, ips);
if (success) {
updateVpcMtu(ips, mtu);
vpc.setPublicMtu(mtu);
List<NetworkVO> vpcTierNetworks = _ntwkDao.listByVpc(vpcId);
for (NetworkVO network : vpcTierNetworks) {
network.setPublicMtu(mtu);
_ntwkDao.update(network.getId(), network);
}
s_logger.info("Successfully update MTU of VPC network");
} else {
throw new CloudRuntimeException("Failed to update MTU on the network");
}
}
}
private void updateVpcMtu(Set<IpAddressTO> ips, Integer publicMtu) {
for (IpAddressTO ipAddress : ips) {
NicVO nicVO = nicDao.findByIpAddressAndVmType(ipAddress.getPublicIp(), VirtualMachine.Type.DomainRouter);
if (nicVO != null) {
nicVO.setMtu(publicMtu);
nicDao.update(nicVO.getId(), nicVO);
}
}
}
protected boolean updateMtuOnVpcVr(Long vpcId, Set<IpAddressTO> ips) {
boolean success = false;
List<DomainRouterVO> routers = routerDao.listByVpcId(vpcId);
for (DomainRouterVO router : routers) {
Commands cmds = new Commands(Command.OnError.Stop);
commandSetupHelper.setupUpdateNetworkCommands(router, ips, cmds);
try {
networkHelper.sendCommandsToRouter(router, cmds);
final Answer updateNetworkAnswer = cmds.getAnswer("updateNetwork");
if (!(updateNetworkAnswer != null && updateNetworkAnswer.getResult())) {
s_logger.warn("Unable to update guest network on router " + router);
throw new CloudRuntimeException("Failed to update guest network with new MTU");
}
success = true;
} catch (ResourceUnavailableException e) {
s_logger.error(String.format("Failed to update network MTU for router %s due to %s", router, e.getMessage()));
}
}
return success;
}
@Override
public Pair<List<? extends Vpc>, Integer> listVpcs(final Long id, final String vpcName, final String displayText, final List<String> supportedServicesStr, final String cidr,
final Long vpcOffId, final String state, final String accountName, Long domainId, final String keyword, final Long startIndex, final Long pageSizeVal,
final Long zoneId, Boolean isRecursive, final Boolean listAll, final Boolean restartRequired, final Map<String, String> tags, final Long projectId,
final Boolean display) {
final Long vpcOffId, final String state, final String accountName, Long domainId, final String keyword, final Long startIndex, final Long pageSizeVal,
final Long zoneId, Boolean isRecursive, final Boolean listAll, final Boolean restartRequired, final Map<String, String> tags, final Long projectId,
final Boolean display) {
final Account caller = CallContext.current().getCallingAccount();
final List<Long> permittedAccounts = new ArrayList<Long>();
final Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(domainId, isRecursive,
@ -1245,7 +1376,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
final ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
final Filter searchFilter = new Filter(VpcVO.class, "created", false, null, null);
final SearchBuilder<VpcVO> sb = _vpcDao.createSearchBuilder();
final SearchBuilder<VpcVO> sb = vpcDao.createSearchBuilder();
_accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE);
@ -1275,7 +1406,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
_accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
if (keyword != null) {
final SearchCriteria<VpcVO> ssc = _vpcDao.createSearchCriteria();
final SearchCriteria<VpcVO> ssc = vpcDao.createSearchCriteria();
ssc.addOr("displayText", SearchCriteria.Op.LIKE, "%" + keyword + "%");
ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
sc.addAnd("name", SearchCriteria.Op.SC, ssc);
@ -1327,7 +1458,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
sc.addAnd("restartRequired", SearchCriteria.Op.EQ, restartRequired);
}
final List<VpcVO> vpcs = _vpcDao.search(sc, searchFilter);
final List<VpcVO> vpcs = vpcDao.search(sc, searchFilter);
// filter by supported services
final boolean listBySupportedServices = supportedServicesStr != null && !supportedServicesStr.isEmpty() && !vpcs.isEmpty();
@ -1433,7 +1564,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
}
protected boolean startVpc(final Vpc vpc, final DeployDestination dest, final ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException,
InsufficientCapacityException {
InsufficientCapacityException {
// deploy provider
boolean success = true;
final List<Provider> providersToImplement = getVpcProviders(vpc.getId());
@ -1456,7 +1587,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
final Account caller = ctx.getCallingAccount();
// check if vpc exists
final Vpc vpc = _vpcDao.findById(vpcId);
final Vpc vpc = vpcDao.findById(vpcId);
if (vpc == null) {
throw new InvalidParameterValueException("Unable to find vpc by id " + vpcId);
}
@ -1488,7 +1619,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
@DB
@Override
public void validateNtwkOffForNtwkInVpc(final Long networkId, final long newNtwkOffId, final String newCidr, final String newNetworkDomain, final Vpc vpc,
final String gateway, final Account networkOwner, final Long aclId) {
final String gateway, final Account networkOwner, final Long aclId) {
final NetworkOffering guestNtwkOff = _entityMgr.findById(NetworkOffering.class, newNtwkOffId);
@ -1588,7 +1719,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
Transaction.execute(new TransactionCallbackNoReturn() {
@Override
public void doInTransactionWithoutResult(final TransactionStatus status) {
final Vpc locked = _vpcDao.acquireInLockTable(vpc.getId());
final Vpc locked = vpcDao.acquireInLockTable(vpc.getId());
if (locked == null) {
throw new CloudRuntimeException("Unable to acquire lock on " + vpc);
}
@ -1637,7 +1768,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
}
} finally {
s_logger.debug("Releasing lock for " + locked);
_vpcDao.releaseFromLockTable(locked.getId());
vpcDao.releaseFromLockTable(locked.getId());
}
}
});
@ -1660,7 +1791,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
@Override
public List<? extends Vpc> getVpcsForAccount(final long accountId) {
final List<Vpc> vpcs = new ArrayList<Vpc>();
vpcs.addAll(_vpcDao.listByAccountId(accountId));
vpcs.addAll(vpcDao.listByAccountId(accountId));
return vpcs;
}
@ -1741,7 +1872,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
}
}
VpcVO vpc = _vpcDao.findById(vpcId);
VpcVO vpc = vpcDao.findById(vpcId);
annotationDao.removeByEntityType(AnnotationService.EntityType.VPC.name(), vpc.getUuid());
return success;
}
@ -1750,7 +1881,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
@Override
@ActionEvent(eventType = EventTypes.EVENT_VPC_RESTART, eventDescription = "restarting vpc")
public boolean restartVpc(final RestartVPCCmd cmd) throws ConcurrentOperationException, ResourceUnavailableException,
InsufficientCapacityException {
InsufficientCapacityException {
final long vpcId = cmd.getId();
final boolean cleanUp = cmd.getCleanup();
final boolean makeRedundant = cmd.getMakeredundant();
@ -1780,13 +1911,13 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
if (!vpc.isRedundant() && makeRedundant) {
final VpcOfferingVO redundantOffering = _vpcOffDao.findByUniqueName(VpcOffering.redundantVPCOfferingName);
final VpcVO entity = _vpcDao.findById(vpcId);
final VpcVO entity = vpcDao.findById(vpcId);
entity.setRedundant(true);
entity.setVpcOfferingId(redundantOffering.getId());
// Change the VPC in order to get it updated after the end of
// the restart procedure.
if (_vpcDao.update(vpc.getId(), entity)) {
if (vpcDao.update(vpc.getId(), entity)) {
vpc = entity;
}
@ -1820,9 +1951,9 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
return true;
} finally {
s_logger.debug("Updating VPC " + vpc + " with restartRequired=" + restartRequired);
final VpcVO vo = _vpcDao.findById(vpcId);
final VpcVO vo = vpcDao.findById(vpcId);
vo.setRestartRequired(restartRequired);
_vpcDao.update(vpc.getId(), vo);
vpcDao.update(vpc.getId(), vo);
}
}
@ -1890,7 +2021,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
}
private PrivateGateway createVpcPrivateGateway(final long vpcId, Long physicalNetworkId, final String broadcastUri, final String ipAddress, final String gateway,
final String netmask, final long gatewayOwnerId, final Long networkOfferingIdPassed, final Boolean isSourceNat, final Long aclId, final Boolean bypassVlanOverlapCheck, final Long associatedNetworkId) throws ResourceAllocationException,
final String netmask, final long gatewayOwnerId, final Long networkOfferingIdPassed, final Boolean isSourceNat, final Long aclId, final Boolean bypassVlanOverlapCheck, final Long associatedNetworkId) throws ResourceAllocationException,
ConcurrentOperationException, InsufficientCapacityException {
// Validate parameters
@ -2337,7 +2468,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
s_logger.debug("No static routes to apply");
return true;
}
final Vpc vpc = _vpcDao.findById(routes.get(0).getVpcId());
final Vpc vpc = vpcDao.findById(routes.get(0).getVpcId());
s_logger.debug("Applying static routes for vpc " + vpc);
final String staticNatProvider = _vpcSrvcDao.getProviderForServiceInVpc(vpc.getId(), Service.StaticNat);
@ -2603,7 +2734,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
try {
// Cleanup inactive VPCs
final List<VpcVO> inactiveVpcs = _vpcDao.listInactiveVpcs();
final List<VpcVO> inactiveVpcs = vpcDao.listInactiveVpcs();
if (inactiveVpcs != null) {
s_logger.info("Found " + inactiveVpcs.size() + " removed VPCs to cleanup");
for (final VpcVO vpc : inactiveVpcs) {
@ -2626,7 +2757,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
@Override
@ActionEvent(eventType = EventTypes.EVENT_NET_IP_ASSIGN, eventDescription = "associating Ip", async = true)
public IpAddress associateIPToVpc(final long ipId, final long vpcId) throws ResourceAllocationException, ResourceUnavailableException, InsufficientAddressCapacityException,
ConcurrentOperationException {
ConcurrentOperationException {
final Account caller = CallContext.current().getCallingAccount();
Account owner = null;
@ -2639,7 +2770,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
return null;
}
final Vpc vpc = _vpcDao.findById(vpcId);
final Vpc vpc = vpcDao.findById(vpcId);
if (vpc == null) {
throw new InvalidParameterValueException("Invalid VPC id provided");
}
@ -2711,7 +2842,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, final String ip4Dns1, final String ip4Dns2, final String ip6Dns1, final String ip6Dns2) 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, Pair<Integer, Integer> vrIfaceMTUs) throws ConcurrentOperationException, InsufficientCapacityException,
ResourceAllocationException {
final Vpc vpc = getActiveVpc(vpcId);
@ -2736,7 +2867,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, ip4Dns1, ip4Dns2, ip6Dns1, ip6Dns2);
subdomainAccess, vpcId, ip6Gateway, ip6Cidr, isDisplayNetworkEnabled, null, null, externalId, null, null, ip4Dns1, ip4Dns2, ip6Dns1, ip6Dns2, vrIfaceMTUs);
if (guestNetwork != null) {
guestNetwork.setNetworkACLId(aclId);
@ -2853,10 +2984,10 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
return false;
}
s_logger.debug("Performing rolling restart of routers of VPC " + vpc);
_ntwkMgr.destroyExpendableRouters(_routerDao.listByVpcId(vpc.getId()), context);
_ntwkMgr.destroyExpendableRouters(routerDao.listByVpcId(vpc.getId()), context);
final DeployDestination dest = new DeployDestination(_dcDao.findById(vpc.getZoneId()), null, null, null);
final List<DomainRouterVO> oldRouters = _routerDao.listByVpcId(vpc.getId());
final List<DomainRouterVO> oldRouters = routerDao.listByVpcId(vpc.getId());
// Create a new router
if (oldRouters.size() > 0) {
@ -2887,7 +3018,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
return false;
}
return _ntwkMgr.areRoutersRunning(_routerDao.listByVpcId(vpc.getId()));
return _ntwkMgr.areRoutersRunning(routerDao.listByVpcId(vpc.getId()));
}
private List<Long> filterChildSubDomains(final List<Long> domainIds) {

View File

@ -3859,7 +3859,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, null, null, null, null, null);
if (newNetwork != null) {
defaultNetwork = _networkDao.findById(newNetwork.getId());
}
@ -7498,7 +7498,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, null, null);
null, null, true, null, 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

@ -29,6 +29,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import com.cloud.utils.Pair;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
@ -129,7 +130,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), nullable(String.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), nullable(Pair.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

@ -16,46 +16,91 @@
// under the License.
package com.cloud.network;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.when;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.apache.cloudstack.alert.AlertService;
import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd;
import org.apache.cloudstack.api.command.user.network.UpdateNetworkCmd;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentMatchers;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.springframework.test.util.ReflectionTestUtils;
import com.cloud.agent.api.to.IpAddressTO;
import com.cloud.alert.AlertManager;
import com.cloud.configuration.ConfigurationManager;
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.IPAddressDao;
import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.dao.PhysicalNetworkDao;
import com.cloud.network.dao.PhysicalNetworkVO;
import com.cloud.network.router.CommandSetupHelper;
import com.cloud.network.router.NetworkHelper;
import com.cloud.network.vpc.VpcManager;
import com.cloud.network.vpc.VpcVO;
import com.cloud.network.vpc.dao.VpcDao;
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.org.Grouping;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.AccountManagerImpl;
import com.cloud.user.AccountService;
import com.cloud.user.AccountVO;
import com.cloud.user.User;
import com.cloud.user.UserVO;
import com.cloud.user.dao.UserDao;
import com.cloud.utils.Pair;
import com.cloud.utils.component.ComponentContext;
import com.cloud.utils.db.EntityManager;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.DomainRouterVO;
import com.cloud.vm.NicVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.dao.DomainRouterDao;
import com.cloud.vm.dao.NicDao;
@PowerMockIgnore("javax.management.*")
@RunWith(PowerMockRunner.class)
@PrepareForTest(ComponentContext.class)
@PrepareForTest({ComponentContext.class, CallContext.class})
public class NetworkServiceImplTest {
@Mock
AccountManager accountManager;
@ -73,10 +118,60 @@ public class NetworkServiceImplTest {
NetworkModel networkModel;
@Mock
NetworkOfferingServiceMapDao networkOfferingServiceMapDao;
@Mock
AccountManager accountMgr;
@Mock
EntityManager entityMgr;
@Mock
NetworkService networkService;
@Mock
VpcManager vpcMgr;
@Mock
NetworkOrchestrationService networkManager;
@Mock
AlertManager alertManager;
@Mock
DataCenterDao dcDao;
@Mock
UserDao userDao;
@Mock
NetworkDao networkDao;
@Mock
NicDao nicDao;
@Mock
IPAddressDao ipAddressDao;
@Mock
ConfigurationManager configMgr;
@Mock
ConfigKey<Integer> publicMtuKey;
@Mock
ConfigKey<Boolean> userChangeMtuKey;
@Mock
VpcDao vpcDao;
@Mock
DomainRouterDao routerDao;
@Mock
AccountService accountService;
@Mock
NetworkHelper networkHelper;
@InjectMocks
private NetworkServiceImpl service = new NetworkServiceImpl();
AccountManagerImpl accountManagerImpl;
@Mock
ConfigKey<Integer> privateMtuKey;
@Mock
private CallContext callContextMock;
@InjectMocks
CreateNetworkCmd createNetworkCmd = new CreateNetworkCmd();
@InjectMocks
UpdateNetworkCmd updateNetworkCmd = new UpdateNetworkCmd();
@Mock
CommandSetupHelper commandSetupHelper;
@Mock
private Account accountMock;
@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";
@ -91,6 +186,11 @@ public class NetworkServiceImplTest {
private AccountVO account;
private UserVO user;
private NetworkOfferingVO offering;
private DataCenterVO dc;
private Network network;
private PhysicalNetworkVO phyNet;
private VpcVO vpc;
private void registerCallContext() {
account = new AccountVO("testaccount", 1L, "networkdomain", Account.Type.NORMAL, "uuid");
@ -100,6 +200,47 @@ public class NetworkServiceImplTest {
CallContext.register(user, account);
}
@Before
public void setup() throws Exception {
MockitoAnnotations.initMocks(this);
replaceUserChangeMtuField();
Mockito.when(userChangeMtuKey.valueIn(anyLong())).thenReturn(Boolean.TRUE);
offering = Mockito.mock(NetworkOfferingVO.class);
network = Mockito.mock(Network.class);
dc = Mockito.mock(DataCenterVO.class);
phyNet = Mockito.mock(PhysicalNetworkVO.class);
vpc = Mockito.mock(VpcVO.class);
service._networkOfferingDao = networkOfferingDao;
service._physicalNetworkDao = physicalNetworkDao;
service._dcDao = dcDao;
service._accountMgr = accountMgr;
service._networkMgr = networkManager;
service.alertManager = alertManager;
service._configMgr = configMgr;
service._vpcDao = vpcDao;
service._vpcMgr = vpcMgr;
service._accountService = accountService;
service._networksDao = networkDao;
service._nicDao = nicDao;
service._ipAddressDao = ipAddressDao;
service.routerDao = routerDao;
service.commandSetupHelper = commandSetupHelper;
service.networkHelper = networkHelper;
PowerMockito.mockStatic(CallContext.class);
CallContext callContextMock = PowerMockito.mock(CallContext.class);
PowerMockito.when(CallContext.current()).thenReturn(callContextMock);
accountMock = PowerMockito.mock(Account.class);
Mockito.when(service._accountMgr.finalizeOwner(any(Account.class), nullable(String.class), nullable(Long.class), nullable(Long.class))).thenReturn(accountMock);
PowerMockito.when(callContextMock.getCallingAccount()).thenReturn(accountMock);
NetworkOffering networkOffering = Mockito.mock(NetworkOffering.class);
Mockito.when(entityMgr.findById(NetworkOffering.class, 1L)).thenReturn(networkOffering);
Mockito.when(networkService.findPhysicalNetworkId(Mockito.anyLong(), ArgumentMatchers.nullable(String.class), Mockito.any(Networks.TrafficType.class))).thenReturn(1L);
Mockito.when(networkOfferingDao.findById(1L)).thenReturn(offering);
Mockito.when(physicalNetworkDao.findById(Mockito.anyLong())).thenReturn(phyNet);
Mockito.when(dcDao.findById(Mockito.anyLong())).thenReturn(dc);
Mockito.lenient().doNothing().when(accountMgr).checkAccess(accountMock, networkOffering, dc);
Mockito.when(accountMgr.isRootAdmin(accountMock.getId())).thenReturn(true);
}
@Test
public void testGetPrivateVlanPairNoVlans() {
Pair<String, Network.PVlanType> pair = service.getPrivateVlanPair(null, null, null);
@ -188,6 +329,164 @@ public class NetworkServiceImplTest {
service.performBasicPrivateVlanChecks(VLAN_ID_900, VLAN_ID_901, Network.PVlanType.Promiscuous);
}
@Test
public void testCreateGuestNetwork() throws InsufficientCapacityException, ResourceAllocationException {
Integer publicMtu = 2450;
Integer privateMtu = 1200;
ReflectionTestUtils.setField(createNetworkCmd, "name", "testNetwork");
ReflectionTestUtils.setField(createNetworkCmd, "displayText", "Test Network");
ReflectionTestUtils.setField(createNetworkCmd, "networkOfferingId", 1L);
ReflectionTestUtils.setField(createNetworkCmd, "zoneId", 1L);
ReflectionTestUtils.setField(createNetworkCmd, "publicMtu", publicMtu);
ReflectionTestUtils.setField(createNetworkCmd, "privateMtu", privateMtu);
ReflectionTestUtils.setField(createNetworkCmd, "physicalNetworkId", null);
Mockito.when(offering.isSystemOnly()).thenReturn(false);
Mockito.when(dc.getAllocationState()).thenReturn(Grouping.AllocationState.Enabled);
Map<String, String> networkProvidersMap = new HashMap<String, String>();
Mockito.when(networkManager.finalizeServicesAndProvidersForNetwork(ArgumentMatchers.any(NetworkOffering.class), anyLong())).thenReturn(networkProvidersMap);
lenient().doNothing().when(alertManager).sendAlert(any(AlertService.AlertType.class), anyLong(), anyLong(), anyString(), anyString());
Mockito.when(configMgr.isOfferingForVpc(offering)).thenReturn(false);
Mockito.when(offering.isInternalLb()).thenReturn(false);
service.createGuestNetwork(createNetworkCmd);
Mockito.verify(networkManager, times(1)).createGuestNetwork(1L, "testNetwork", "Test Network", null,
null, null, false, null, accountMock, null, phyNet,
1L, null, null, null, null, null,
true, null, null, null, null, null,
null, null, null, null, new Pair<>(1500, privateMtu));
}
@Test
public void testValidateMtuConfigWhenMtusExceedThreshold() {
Integer publicMtu = 2450;
Integer privateMtu = 1500;
Long zoneId = 1L;
when(publicMtuKey.valueIn(zoneId)).thenReturn(NetworkService.DEFAULT_MTU);
when(privateMtuKey.valueIn(zoneId)).thenReturn(NetworkService.DEFAULT_MTU);
Pair<Integer, Integer> interfaceMtus = service.validateMtuConfig(publicMtu, privateMtu, zoneId);
Assert.assertNotNull(interfaceMtus);
Assert.assertEquals(NetworkService.DEFAULT_MTU, interfaceMtus.first());
Assert.assertEquals(NetworkService.DEFAULT_MTU, interfaceMtus.second());
Mockito.verify(alertManager, Mockito.times(1)).sendAlert(Mockito.any(AlertService.AlertType.class),
Mockito.anyLong(), nullable(Long.class), Mockito.anyString(), Mockito.anyString());
}
@Test
public void testValidatePrivateMtuExceedingThreshold() {
Integer publicMtu = 1500;
Integer privateMtu = 2500;
Long zoneId = 1L;
when(publicMtuKey.valueIn(zoneId)).thenReturn(NetworkService.DEFAULT_MTU);
when(privateMtuKey.valueIn(zoneId)).thenReturn(NetworkService.DEFAULT_MTU);
Pair<Integer, Integer> interfaceMtus = service.validateMtuConfig(publicMtu, privateMtu, zoneId);
Assert.assertNotNull(interfaceMtus);
Assert.assertEquals(NetworkService.DEFAULT_MTU, interfaceMtus.first());
Assert.assertEquals(NetworkService.DEFAULT_MTU, interfaceMtus.second());
Mockito.verify(alertManager, Mockito.times(1)).sendAlert(Mockito.any(AlertService.AlertType.class),
Mockito.anyLong(), nullable(Long.class), Mockito.anyString(), Mockito.anyString());
}
@Test
public void testValidateBypassingPublicMtuPassedDuringNetworkTierCreationForVpcs() throws InsufficientCapacityException, ResourceAllocationException {
Integer publicMtu = 1250;
Integer privateMtu = 1000;
Long zoneId = 1L;
ReflectionTestUtils.setField(createNetworkCmd, "name", "testNetwork");
ReflectionTestUtils.setField(createNetworkCmd, "displayText", "Test Network");
ReflectionTestUtils.setField(createNetworkCmd, "networkOfferingId", 1L);
ReflectionTestUtils.setField(createNetworkCmd, "zoneId", zoneId);
ReflectionTestUtils.setField(createNetworkCmd, "publicMtu", publicMtu);
ReflectionTestUtils.setField(createNetworkCmd, "privateMtu", privateMtu);
ReflectionTestUtils.setField(createNetworkCmd, "physicalNetworkId", null);
ReflectionTestUtils.setField(createNetworkCmd, "vpcId", 1L);
Mockito.when(configMgr.isOfferingForVpc(offering)).thenReturn(true);
Mockito.when(vpcDao.findById(anyLong())).thenReturn(vpc);
service.createGuestNetwork(createNetworkCmd);
Mockito.verify(vpcMgr, times(1)).createVpcGuestNetwork(1L, "testNetwork", "Test Network", null,
null, null, null, accountMock, null, phyNet,
1L, null, null, 1L, null, accountMock,
true, null, null, null, null, null, null, null, new Pair<>(0, 1000));
}
@Test
public void testUpdateSharedNetworkMtus() throws Exception {
Integer publicMtu = 1250;
Integer privateMtu = 1000;
Long networkId = 1L;
Long zoneId = 1L;
ReflectionTestUtils.setField(updateNetworkCmd, "id", networkId);
ReflectionTestUtils.setField(updateNetworkCmd, "publicMtu", publicMtu);
ReflectionTestUtils.setField(updateNetworkCmd, "privateMtu", privateMtu);
User callingUser = mock(User.class);
UserVO userVO = mock(UserVO.class);
Account callingAccount = mock(Account.class);
NetworkVO networkVO = mock(NetworkVO.class);
NicVO nicVO = mock(NicVO.class);
List<IPAddressVO> addresses = new ArrayList<>();
List<IpAddressTO> ips = new ArrayList<>();
List<DomainRouterVO> routers = new ArrayList<>();
DomainRouterVO routerPrimary = Mockito.mock(DomainRouterVO.class);
routers.add(routerPrimary);
CallContext.register(callingUser, callingAccount);
PowerMockito.when(CallContext.current()).thenReturn(callContextMock);
Mockito.doReturn(1L).when(callContextMock).getCallingUserId();
Mockito.when(userDao.findById(anyLong())).thenReturn(userVO);
Mockito.when(accountService.getActiveUser(1L)).thenReturn(callingUser);
Mockito.when(callingUser.getAccountId()).thenReturn(1L);
Mockito.when(accountService.getActiveAccountById(anyLong())).thenReturn(callingAccount);
Mockito.when(networkDao.findById(anyLong())).thenReturn(networkVO);
Mockito.when(networkOfferingDao.findByIdIncludingRemoved(anyLong())).thenReturn(offering);
Mockito.when(offering.isSystemOnly()).thenReturn(false);
Mockito.when(networkVO.getTrafficType()).thenReturn(Networks.TrafficType.Guest);
Mockito.when(networkVO.getGuestType()).thenReturn(Network.GuestType.Shared);
Mockito.when(nicDao.listByNetworkIdAndType(anyLong(), any(VirtualMachine.Type.class))).thenReturn(List.of(Mockito.mock(NicVO.class)));
Mockito.when(networkVO.getVpcId()).thenReturn(null);
Mockito.when(ipAddressDao.listByNetworkId(anyLong())).thenReturn(addresses);
Pair<Integer, Integer> updatedMtus = service.validateMtuOnUpdate(networkVO, zoneId, publicMtu, privateMtu);
Assert.assertEquals(publicMtu, updatedMtus.first());
Assert.assertEquals(privateMtu, updatedMtus.second());
}
@Test
public void testUpdatePublicInterfaceMtuViaNetworkTiersForVpcNetworks() {
Integer vpcMtu = 1450;
Integer publicMtu = 1250;
Integer privateMtu = 1000;
Long vpcId = 1L;
Long zoneId = 1L;
ReflectionTestUtils.setField(createNetworkCmd, "name", "testNetwork");
ReflectionTestUtils.setField(createNetworkCmd, "displayText", "Test Network");
ReflectionTestUtils.setField(createNetworkCmd, "networkOfferingId", 1L);
ReflectionTestUtils.setField(createNetworkCmd, "zoneId", zoneId);
ReflectionTestUtils.setField(createNetworkCmd, "publicMtu", publicMtu);
ReflectionTestUtils.setField(createNetworkCmd, "privateMtu", privateMtu);
ReflectionTestUtils.setField(createNetworkCmd, "physicalNetworkId", null);
ReflectionTestUtils.setField(createNetworkCmd, "vpcId", vpcId);
VpcVO vpcVO = Mockito.mock(VpcVO.class);
Mockito.when(vpcDao.findById(anyLong())).thenReturn(vpcVO);
Mockito.when(vpcVO.getPublicMtu()).thenReturn(vpcMtu);
Pair<Integer, Integer> updatedMtus = service.validateMtuConfig(publicMtu, privateMtu, zoneId);
service.mtuCheckForVpcNetwork(vpcId, updatedMtus, publicMtu, privateMtu);
Assert.assertEquals(vpcMtu, updatedMtus.first());
Assert.assertEquals(privateMtu, updatedMtus.second());
}
private void replaceUserChangeMtuField() throws Exception {
Field field = NetworkService.class.getDeclaredField("AllowUsersToSpecifyVRMtu");
field.setAccessible(true);
// remove final modifier from field
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, userChangeMtuKey);
}
private void prepareCreateNetworkDnsMocks(CreateNetworkCmd cmd, Network.GuestType guestType, boolean ipv6, boolean isVpc, boolean dnsServiceSupported) {
long networkOfferingId = 1L;
Mockito.when(cmd.getNetworkOfferingId()).thenReturn(networkOfferingId);
@ -197,7 +496,6 @@ public class NetworkServiceImplTest {
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);
@ -240,11 +538,11 @@ public class NetworkServiceImplTest {
}
}
@Test(expected = InvalidParameterValueException.class)
@Test
public void testCreateNetworkDnsVpcFailure() {
registerCallContext();
CreateNetworkCmd cmd = Mockito.mock(CreateNetworkCmd.class);
prepareCreateNetworkDnsMocks(cmd, Network.GuestType.Isolated, false, true, true);
prepareCreateNetworkDnsMocks(cmd, Network.GuestType.Isolated, false, false, true);
Mockito.when(cmd.getIp4Dns1()).thenReturn(ip4Dns[0]);
try {
service.createGuestNetwork(cmd);
@ -257,6 +555,8 @@ public class NetworkServiceImplTest {
public void testCreateNetworkDnsOfferingServiceFailure() {
registerCallContext();
CreateNetworkCmd cmd = Mockito.mock(CreateNetworkCmd.class);
Mockito.when(cmd.getDomainId()).thenReturn(null);
Mockito.when(cmd.getProjectId()).thenReturn(null);
prepareCreateNetworkDnsMocks(cmd, Network.GuestType.Isolated, false, false, false);
Mockito.when(cmd.getIp4Dns1()).thenReturn(ip4Dns[0]);
try {

View File

@ -20,7 +20,15 @@ package com.cloud.network.vpc;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.powermock.api.mockito.PowerMockito.when;
import java.util.ArrayList;
@ -31,9 +39,15 @@ import java.util.Map;
import java.util.Set;
import java.util.UUID;
import org.apache.cloudstack.api.command.admin.vpc.CreateVPCOfferingCmd;
import com.cloud.alert.AlertManager;
import org.apache.cloudstack.acl.SecurityChecker;
import org.apache.cloudstack.alert.AlertService;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
import org.junit.After;
import org.junit.Assert;
import org.apache.cloudstack.api.command.admin.vpc.CreateVPCOfferingCmd;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
@ -41,30 +55,62 @@ import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.powermock.reflect.Whitebox;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.routing.UpdateNetworkCommand;
import com.cloud.agent.api.to.IpAddressTO;
import com.cloud.agent.manager.Commands;
import com.cloud.dc.VlanVO;
import com.cloud.dc.dao.VlanDao;
import com.cloud.configuration.Resource;
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.exception.ResourceUnavailableException;
import com.cloud.network.Network;
import com.cloud.network.Network.Capability;
import com.cloud.network.Network.Provider;
import com.cloud.network.Network.Service;
import com.cloud.network.NetworkModel;
import com.cloud.network.PhysicalNetwork;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.element.NetworkElement;
import com.cloud.network.vpc.dao.VpcOfferingDao;
import com.cloud.network.router.CommandSetupHelper;
import com.cloud.network.router.NetworkHelper;
import com.cloud.network.router.VirtualRouter;
import com.cloud.network.vpc.dao.VpcDao;
import com.cloud.network.vpc.dao.VpcOfferingServiceMapDao;
import com.cloud.offering.NetworkOffering;
import com.cloud.offerings.NetworkOfferingServiceMapVO;
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.ResourceLimitService;
import com.cloud.user.User;
import com.cloud.utils.Pair;
import com.cloud.utils.db.EntityManager;
import com.cloud.utils.net.Ip;
import com.cloud.vm.DomainRouterVO;
import com.cloud.vm.NicVO;
import com.cloud.vm.dao.DomainRouterDao;
import com.cloud.vm.dao.NicDao;
import com.cloud.network.vpc.dao.VpcOfferingDao;
import com.cloud.user.ResourceLimitService;
import com.cloud.user.UserVO;
import com.cloud.utils.net.NetUtils;
public class VpcManagerImplTest {
@Mock
VpcOfferingServiceMapDao vpcOffSvcMapDao;
@Mock
VpcDao vpcDao;
@Mock
NetworkOrchestrationService networkMgr;
@Mock
AccountManager accountManager;
@Mock
@ -76,6 +122,30 @@ public class VpcManagerImplTest {
@Mock
VpcOfferingServiceMapDao vpcOfferingServiceMapDao;
VpcManagerImpl manager;
@Mock
EntityManager entityMgr;
@Mock
NetworkDao networkDao;
@Mock
NetworkModel networkModel;
@Mock
NetworkOfferingServiceMapDao networkOfferingServiceMapDao;
@Mock
private CallContext callContextMock;
@Mock
IPAddressDao ipAddressDao;
@Mock
DomainRouterDao routerDao;
@Mock
CommandSetupHelper commandSetupHelper;
@Mock
NetworkHelper networkHelper;
@Mock
VlanDao vlanDao;
@Mock
NicDao nicDao;
@Mock
AlertManager alertManager;
public static final long ACCOUNT_ID = 1;
private AccountVO account;
@ -108,14 +178,32 @@ public class VpcManagerImplTest {
{
MockitoAnnotations.initMocks(this);
manager = new VpcManagerImpl();
manager._vpcOffSvcMapDao = vpcOfferingServiceMapDao;
manager.vpcDao = vpcDao;
manager._ntwkMgr = networkMgr;
manager._accountMgr = accountManager;
manager._entityMgr = entityMgr;
manager._ntwkDao = networkDao;
manager._ntwkModel = networkModel;
manager._ntwkOffServiceDao = networkOfferingServiceMapDao;
manager._ipAddressDao = ipAddressDao;
manager.routerDao = routerDao;
manager.commandSetupHelper = commandSetupHelper;
manager.networkHelper = networkHelper;
manager._vlanDao = vlanDao;
manager.nicDao = nicDao;
manager.alertManager = alertManager;
manager._resourceLimitMgr = resourceLimitService;
manager._vpcOffDao = vpcOfferingDao;
manager._dcDao = dataCenterDao;
manager._vpcOffSvcMapDao = vpcOfferingServiceMapDao;
CallContext.register(Mockito.mock(User.class), Mockito.mock(Account.class));
registerCallContext();
}
@After
public void tearDown() {
CallContext.unregister();
}
@Test
public void getVpcOffSvcProvidersMapForEmptyServiceTest() {
long vpcOffId = 1L;
@ -219,6 +307,113 @@ public class VpcManagerImplTest {
return providers;
}
@Test
public void testCreateVpcNetwork() throws InsufficientCapacityException, ResourceAllocationException {
final long VPC_ID = 201L;
manager._maxNetworks = 3;
VpcVO vpcMockVO = Mockito.mock(VpcVO.class);
Vpc vpcMock = Mockito.mock(Vpc.class);
Account accountMock = Mockito.mock(Account.class);
PhysicalNetwork physicalNetwork = Mockito.mock(PhysicalNetwork.class);
NetworkOffering offering = Mockito.mock(NetworkOffering.class);
List<Network.Service> services = new ArrayList<>();
services.add(Service.SourceNat);
List<NetworkOfferingServiceMapVO> serviceMap = new ArrayList<>();
Mockito.when(vpcDao.findById(anyLong())).thenReturn(vpcMockVO);
Mockito.when(manager.getActiveVpc(anyLong())).thenReturn(vpcMock);
lenient().doNothing().when(accountManager).checkAccess(any(Account.class), nullable(SecurityChecker.AccessType.class), anyBoolean(), any(Vpc.class));
Mockito.when(vpcMock.isRegionLevelVpc()).thenReturn(true);
Mockito.when(entityMgr.findById(NetworkOffering.class, 1L)).thenReturn(offering);
Mockito.when(vpcMock.getId()).thenReturn(VPC_ID);
Mockito.when(vpcDao.acquireInLockTable(VPC_ID)).thenReturn(vpcMockVO);
Mockito.when(networkDao.countVpcNetworks(anyLong())).thenReturn(1L);
Mockito.when(offering.getGuestType()).thenReturn(Network.GuestType.Isolated);
Mockito.when(networkModel.listNetworkOfferingServices(anyLong())).thenReturn(services);
Mockito.when(networkOfferingServiceMapDao.listByNetworkOfferingId(anyLong())).thenReturn(serviceMap);
Mockito.when(vpcMock.getCidr()).thenReturn("10.0.0.0/8");
Mockito.when(vpcMock.getNetworkDomain()).thenReturn("cs1cloud.internal");
manager.validateNewVpcGuestNetwork("10.10.10.0/24", "10.10.10.1", accountMock, vpcMock, "cs1cloud.internal");
manager.validateNtwkOffForNtwkInVpc(2L, 1, "10.10.10.0/24", "111-", vpcMock, "10.1.1.1", new AccountVO(), null);
manager.validateNtwkOffForVpc(offering, services);
manager.createVpcGuestNetwork(1L, "vpcNet1", "vpc tier 1", null,
"10.10.10.0/24", null, null, accountMock, null, physicalNetwork,
1L, null, null, 1L, null, accountMock,
true, null, null, null, null, null, null, null, new Pair<>(1000, 1000));
Mockito.verify(networkMgr, times(1)).createGuestNetwork(1L, "vpcNet1", "vpc tier 1", null,
"10.10.10.0/24", null, false, "cs1cloud.internal", accountMock, null,
physicalNetwork, zoneId, null, null, 1L, null, null,
true, null, null, null, null,
null, null, null, null, null, new Pair<>(1000, 1000));
}
@Test
public void testUpdateVpcNetwork() throws ResourceUnavailableException {
long vpcId = 1L;
Integer publicMtu = 1450;
Account accountMock = Mockito.mock(Account.class);
VpcVO vpcVO = new VpcVO();
Answer answer = Mockito.mock(Answer.class);
Mockito.when(answer.getResult()).thenReturn(true);
VirtualRouter routerMock = Mockito.mock(VirtualRouter.class);
List<IPAddressVO> ipAddresses = new ArrayList<>();
IPAddressVO ipAddressVO = Mockito.mock(IPAddressVO.class);
Mockito.when(ipAddressVO.getAddress()).thenReturn(Mockito.mock(Ip.class));
ipAddresses.add(ipAddressVO);
List<IpAddressTO> ips = new ArrayList<>();
List<DomainRouterVO> routers = new ArrayList<>();
DomainRouterVO router = Mockito.mock(DomainRouterVO.class);
routers.add(router);
IpAddressTO[] ipsToSend = ips.toArray(new IpAddressTO[0]);
Mockito.when(callContextMock.getCallingAccount()).thenReturn(accountMock);
Mockito.when(vpcDao.findById(vpcId)).thenReturn(vpcVO);
Mockito.when(vpcDao.createForUpdate(anyLong())).thenReturn(vpcVO);
Mockito.when(ipAddressDao.listByAssociatedVpc(anyLong(), nullable(Boolean.class))).thenReturn(ipAddresses);
Mockito.when(routerDao.listByVpcId(anyLong())).thenReturn(routers);
VlanVO vlanVO = Mockito.mock(VlanVO.class);
Mockito.when(vlanVO.getVlanNetmask()).thenReturn("netmask");
Mockito.when(vlanDao.findById(anyLong())).thenReturn(vlanVO);
Mockito.doAnswer((org.mockito.stubbing.Answer<Void>) invocation -> {
Commands commands = (Commands)invocation.getArguments()[2];
commands.addCommand("updateNetwork", new UpdateNetworkCommand(ipsToSend));
return null;
}).when(commandSetupHelper).setupUpdateNetworkCommands(Mockito.any(), Mockito.any(), Mockito.any());
Mockito.doAnswer((org.mockito.stubbing.Answer<Boolean>) invocation -> {
Commands commands = (Commands)invocation.getArguments()[1];
commands.setAnswers(new Answer[]{answer});
return true;
}).when(networkHelper).sendCommandsToRouter(Mockito.any(), Mockito.any());
Mockito.when(nicDao.findByIpAddressAndVmType(anyString(), any())).thenReturn(Mockito.mock(NicVO.class));
Mockito.when(nicDao.update(anyLong(), any())).thenReturn(true);
Mockito.when(networkDao.listByVpc(vpcId)).thenReturn(List.of(Mockito.mock(NetworkVO.class)));
Mockito.when(networkDao.update(anyLong(), any())).thenReturn(true);
Mockito.when(vpcDao.update(vpcId, vpcVO)).thenReturn(true);
manager.updateVpc(vpcId, null, null, null, true, publicMtu);
Assert.assertEquals(publicMtu, vpcVO.getPublicMtu());
}
@Test
public void testUpdatePublicMtuToGreaterThanThreshold() {
Integer publicMtu = 2500;
Integer expectedMtu = 1500;
Long vpcId = 1L;
VpcVO vpcVO = new VpcVO();
Mockito.when(vpcDao.findById(vpcId)).thenReturn(vpcVO);
Mockito.when(vpcDao.createForUpdate(anyLong())).thenReturn(vpcVO);
lenient().doNothing().when(alertManager).sendAlert(any(AlertService.AlertType.class), anyLong(), anyLong(), anyString(), anyString());
Integer mtu = manager.validateMtu(vpcVO, publicMtu);
Assert.assertEquals(expectedMtu, mtu);
}
@Test(expected = InvalidParameterValueException.class)
public void testDisabledConfigCreateIpv6VpcOffering() {
CreateVPCOfferingCmd cmd = Mockito.mock(CreateVPCOfferingCmd.class);
@ -251,7 +446,7 @@ public class VpcManagerImplTest {
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);
ip4Dns[0], null, null, null, true, 1500);
} catch (ResourceAllocationException e) {
Assert.fail(String.format("failure with exception: %s", e.getMessage()));
}
@ -263,7 +458,7 @@ public class VpcManagerImplTest {
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);
ip4Dns[0], ip4Dns[1], ip6Dns[0], null, true, 1500);
} catch (ResourceAllocationException e) {
Assert.fail(String.format("failure with exception: %s", e.getMessage()));
}

View File

@ -664,7 +664,7 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkOrches
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,
String ip4Dns1, String ip4Dns2, String ip6Dns1, String ip6Dns2) throws ConcurrentOperationException, ResourceAllocationException {
String ip4Dns1, String ip4Dns2, String ip6Dns1, String ip6Dns2, Pair<Integer, Integer> vrIfaceMTUs) throws ConcurrentOperationException, ResourceAllocationException {
// TODO Auto-generated method stub
return null;
}

View File

@ -296,6 +296,7 @@ class CsDevice:
class CsIP:
DEFAULT_MTU = '1500'
def __init__(self, dev, config):
self.dev = dev
@ -320,6 +321,8 @@ class CsIP:
logging.info("Configuring address %s on device %s", self.ip(), self.dev)
cmd = "ip addr add dev %s %s brd +" % (self.dev, self.ip())
CsHelper.execute(cmd)
cmd = "ifconfig %s mtu %s" % (self.dev, self.mtu())
CsHelper.execute(cmd)
except Exception as e:
logging.info("Exception occurred ==> %s" % e)
@ -390,6 +393,12 @@ class CsIP:
return self.address['public_ip']
return "unknown"
def mtu(self):
logging.info(self.address)
if "mtu" in self.address:
return self.address['mtu']
return CsIP.DEFAULT_MTU
def setup_router_control(self):
if self.config.is_vpc():
return

View File

@ -19,9 +19,11 @@ import logging
import os
from netaddr import *
from random import randint
import json
from CsGuestNetwork import CsGuestNetwork
from cs.CsDatabag import CsDataBag
from cs.CsFile import CsFile
from cs.CsAddress import CsIP
LEASES = "/var/lib/misc/dnsmasq.leases"
DHCP_HOSTS = "/etc/dhcphosts.txt"
@ -120,7 +122,12 @@ class CsDhcp(CsDataBag):
sline = "dhcp-option=tag:interface-%s-%s,3," % (device, idx)
line = "dhcp-option=tag:interface-%s-%s,3,%s" % (device, idx, gateway)
self.conf.search(sline, line)
# Netmask
sline = "dhcp-option=%s,26" % device
line = "dhcp-option=%s,26,%s" % (device, i['mtu'])
self.conf.search(sline, line)
# Netmask
netmask = ''
if self.config.is_vpc():
netmask = gn.get_netmask()

View File

@ -115,8 +115,16 @@ def get_device_info():
list = []
for i in execute("ip addr show |grep -v secondary"):
vals = i.strip().lstrip().rstrip().split()
if re.search('[0-9]:',vals[0]):
to={}
to['mtu'] = vals[4]
list.append(to)
if vals[0] == "inet":
to = {}
if len(list) > 0:
to = list.pop(len(list)-1)
else:
to={}
to['ip'] = vals[1]
to['dev'] = vals[-1]
to['network'] = IPNetwork(to['ip'])

View File

@ -55,6 +55,8 @@ def merge(dbag, ip):
ip['cidr'] = str(ipo.ip) + '/' + str(ipo.prefixlen)
ip['size'] = str(ipo.prefixlen)
ip['network'] = str(ipo.network) + '/' + str(ipo.prefixlen)
if 'mtu' in ip:
ip['mtu'] = str(ip['mtu'])
if 'nw_type' not in ip.keys():
ip['nw_type'] = 'public'
else:

View File

@ -155,6 +155,7 @@ class updateDataBag:
dp['gateway'] = d['router_guest_gateway']
dp['nic_dev_id'] = d['device'][3:]
dp['nw_type'] = 'guest'
dp['mtu'] = str(d['mtu'])
qf = QueueFile()
qf.load({'ip_address': [dp], 'type': 'ips'})
if 'domain_name' not in d.keys() or d['domain_name'] == '':

View File

@ -93,6 +93,14 @@ setup_interface() {
echo " address $ip " >> /etc/network/interfaces
echo " netmask $mask" >> /etc/network/interfaces
fi
if [ ! -z "$PRIVATEMTU" ] && [ $intf == "eth0" ]; then
echo " mtu $PRIVATEMTU" >> /etc/network/interfaces
fi
if [ ! -z "$PUBLICMTU" ] && [ $intf == "eth2" ]; then
echo " mtu $PUBLICMTU" >> /etc/network/interfaces
fi
fi
if [ "$ip" == "0.0.0.0" -o "$ip" == "" ]
@ -904,6 +912,12 @@ parse_cmd_line() {
logrotatefrequency)
export LOGROTATE_FREQUENCY=$VALUE
;;
publicMtu)
export PUBLICMTU=$VALUE
;;
privateMtu)
export PRIVATEMTU=$VALUE
;;
useHttpsToUpload)
export USEHTTPS=$VALUE
;;

View File

@ -19,8 +19,6 @@
import sys
from merge import QueueFile
import logging
import subprocess
from subprocess import PIPE, STDOUT
import os
import os.path
import configure

View File

@ -0,0 +1,63 @@
#!/bin/bash
# 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.
# used as a proxy to call script inside virtual router
#set -x
ip=$1
netmask=$2
mtu=$3
timeout=$4
i=0
get_interface() {
for i in `seq 1 $(($timeout))`
do
#inf=$(ip route list ${1}/${2} | awk '{print $3}')
inf=$(ip addr show|egrep '^ *inet'|grep ${1}/${2} |grep brd|awk -- '{ print $NF; }')
if [ ! -z $inf ]; then
echo $inf
break
fi
sleep 0.1
done
}
interfaceName=$(get_interface $ip $netmask)
echo $interfaceName
if [ ! -z $interfaceName ]; then
state=$(cat /sys/class/net/${interfaceName}/operstate)
if [[ "$state" == "up" ]]; then
ifconfig $interfaceName mtu $mtu up
else
ifconfig $interfaceName mtu $mtu
fi
if grep "dhcp-option=$interfaceName,26" /etc/dnsmasq.d/cloud.conf; then
sed -i "/dhcp-option=$interfaceName,26/c\dhcp-option=$interfaceName,26,$mtu" /etc/dnsmasq.d/cloud.conf
else
echo "dhcp-option=$interfaceName,26,$mtu" >> /etc/dnsmasq.d/cloud.conf
fi
systemctl restart dnsmasq
exit $?
fi
echo "Interface with IP ${ip} not found"
exit 1

View File

@ -0,0 +1,395 @@
# Licensed to the Apache Software Foundation (ASF) under one
# 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 tests for Network Life Cycle
"""
# Import Local Modules
from marvin.cloudstackTestCase import cloudstackTestCase
from marvin.lib.utils import cleanup_resources, get_process_status, get_host_credentials
from marvin.lib.base import (Account,
VirtualMachine,
ServiceOffering,
NATRule,
PublicIPAddress,
StaticNATRule,
FireWallRule,
Network,
NetworkOffering,
LoadBalancerRule,
Router,
NIC,
Cluster)
from marvin.lib.common import (get_domain,
get_free_vlan,
get_zone,
get_template,
get_test_template,
list_hosts,
list_publicIP,
list_nat_rules,
list_routers,
list_virtual_machines,
list_lb_rules,
list_configurations,
verifyGuestTrafficPortGroups,
verifyNetworkState)
from nose.plugins.attrib import attr
import logging
_multiprocess_shared_ = True
logger = logging.getLogger('TestNetworkWithMtuConfiguration')
stream_handler = logging.StreamHandler()
logger.setLevel(logging.DEBUG)
logger.addHandler(stream_handler)
class TestNetworkWithMtuConfiguration(cloudstackTestCase):
@classmethod
def setUpClass(cls):
cls.testClient = super(TestNetworkWithMtuConfiguration, cls).getClsTestClient()
cls.api_client = cls.testClient.getApiClient()
cls.dbclient = cls.testClient.getDbConnection()
cls.hypervisor = cls.testClient.getHypervisorInfo()
cls.domain = get_domain(cls.api_client)
cls.skip = False
if cls.hypervisor.lower() == 'simulator':
cls.skip = True
cls.services = cls.testClient.getParsedTestDataConfig()
cls.hostConfig = cls.config.__dict__["zones"][0].__dict__["pods"][0].__dict__["clusters"][0].__dict__["hosts"][
0].__dict__
# Get Zone and templates
cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
logger.debug("Creating Admin Account for domain %s on zone %s" % (cls.domain.id, cls.zone.id))
cls.account = Account.create(
cls.api_client,
cls.services["account"],
admin=True,
domainid=cls.domain.id
)
cls.template = get_template(
cls.api_client,
cls.zone.id,
cls.services["ostype"]
)
cls.services["virtual_machine"]["zoneid"] = cls.zone.id
cls.services["virtual_machine"]["template"] = cls.template.id
cls.service_offering = ServiceOffering.create(
cls.api_client,
cls.services["service_offering"]
)
cls.isolated_network_offering = NetworkOffering.create(
cls.api_client,
cls.services["network_offering"]
)
cls.isolated_network_offering.update(cls.api_client, state='Enabled')
cls._cleanup = [
cls.service_offering,
cls.isolated_network_offering,
cls.account
]
return
@classmethod
def tearDownClass(cls):
try:
# Cleanup resources used
cleanup_resources(cls.api_client, cls._cleanup)
except Exception as e:
raise Exception("Warning: Exception during cleanup : %s" % e)
return
def setUp(self):
if self.skip:
self.skipTest("Skip test for simulator hypervisor")
self.apiclient = self.testClient.getApiClient()
self.dbclient = self.testClient.getDbConnection()
self.hypervisor = self.testClient.getHypervisorInfo()
self.cleanup = []
return
def tearDown(self):
try:
# Clean up, terminate the resources created
cleanup_resources(self.apiclient, self.cleanup)
self.cleanup[:] = []
except Exception as e:
raise Exception("Warning: Exception during cleanup : %s" % e)
return
'''
This test performs the following:
1. creates an Isolated network with Public and Private MTUs being configured on the respective interfaces
a. Set one of the MTUs to a value greater that the configured max - 1500 and observe that it gets set
to the maximum configurable value
2. Check router nic MTUs
3. Validates that the network has the right MTU set in the DB
'''
@attr(tags=["advanced", "isolated", "network", "xx"], required_hardware="false")
def test_01_create_isolated_network_with_mtu(self):
public_mtu = 1450
private_mtu = 2000
logger.debug("Creating an isolated network with MTU defined for both public and private interfaces")
self.isolated_network = Network.create(
self.apiclient,
self.services["isolated_network"],
networkofferingid=self.isolated_network_offering.id,
zoneid=self.zone.id,
publicmtu=public_mtu,
privatemtu=private_mtu)
logger.debug("Deploying VM")
virtual_machine = VirtualMachine.create(
self.apiclient,
self.services["virtual_machine"],
templateid=self.template.id,
serviceofferingid=self.service_offering.id,
networkids=[str(self.isolated_network.id)])
self.cleanup.append(virtual_machine)
self.cleanup.append(self.isolated_network)
# Validate network is in the Implemented state
response = verifyNetworkState(
self.apiclient,
virtual_machine.nic[0].networkid,
"implemented")
exceptionOccurred = response[0]
isNetworkInDesiredState = response[1]
exceptionMessage = response[2]
if (exceptionOccurred or (not isNetworkInDesiredState)):
self.fail(exceptionMessage)
public_ips = list_publicIP(
self.apiclient,
associatednetworkid=self.isolated_network.id
)
self.assertEqual(
isinstance(public_ips, list),
True,
"Check for list public IPs response return valid data"
)
public_ip = public_ips[0]
logger.debug("Creating Firewall rule for VM ID: %s" % virtual_machine.id)
FireWallRule.create(
self.apiclient,
ipaddressid=public_ip.id,
protocol=self.services["natrule"]["protocol"],
cidrlist=['0.0.0.0/0'],
startport=self.services["natrule"]["publicport"],
endport=self.services["natrule"]["publicport"]
)
logger.debug("Creating NAT rule for VM ID: %s" % virtual_machine.id)
nat_rule = NATRule.create(
self.apiclient,
virtual_machine,
self.services["natrule"],
public_ip.id
)
logger.debug("Ping the external network with packet size greater than configured mtu %s : %s", public_mtu, 1500)
expected = 1
check_string = "Frag needed and DF set"
cmd = "ping -M do -s {mtu} 8.8.8.8 -c1"
result = self.check_router_command(virtual_machine, nat_rule.ipaddress, cmd.format(mtu="1500"), check_string, self)
self.assertEqual(
result,
expected,
"Ping to outside world from VM should be successful!"
)
logger.debug("Ping the external network with packet size lesser than configured mtu %s : %s", public_mtu, 1200)
expected = 1
check_string = "0% packet loss"
cmd = "ping -M do -s {mtu} 8.8.8.8 -c1"
result = self.check_router_command(virtual_machine, nat_rule.ipaddress, cmd.format(mtu="1200"), check_string, self)
self.assertEqual(
result,
expected,
"Ping to outside world from VM should be successful!"
)
# Verify network mtu set
self.verify_network_mtu(self.isolated_network, public_mtu, 1500)
self.checkRouterNicMtus(self.isolated_network, public_mtu, 1500)
self.checkNetworkMtu(self.isolated_network, public_mtu, 1500)
@attr(tags=["advanced", "isolated", "network", "xx"], required_hardware="false")
def test_02_update_isolated_network_with_mtu(self):
public_mtu = 1200
private_mtu = 1100
logger.debug("Creating an isolated network with MTU defined for both public and private interfaces")
isolated_network1 = Network.create(
self.apiclient,
self.services["isolated_network"],
networkofferingid=self.isolated_network_offering.id,
zoneid=self.zone.id,
publicmtu=public_mtu,
privatemtu=private_mtu)
logger.debug("Deploying VM")
virtual_machine = VirtualMachine.create(
self.apiclient,
self.services["virtual_machine"],
templateid=self.template.id,
serviceofferingid=self.service_offering.id,
networkids=[str(isolated_network1.id)])
self.cleanup.append(virtual_machine)
self.cleanup.append(isolated_network1)
# Validate network is in the Implemented state
response = verifyNetworkState(
self.apiclient,
virtual_machine.nic[0].networkid,
"implemented")
exceptionOccurred = response[0]
isNetworkInDesiredState = response[1]
exceptionMessage = response[2]
if (exceptionOccurred or (not isNetworkInDesiredState)):
self.fail(exceptionMessage)
public_ips = list_publicIP(
self.apiclient,
associatednetworkid=isolated_network1.id
)
self.assertEqual(
isinstance(public_ips, list),
True,
"Check for list public IPs response return valid data"
)
public_ip = public_ips[0]
logger.debug("Creating Firewall rule for VM ID: %s" % virtual_machine.id)
FireWallRule.create(
self.apiclient,
ipaddressid=public_ip.id,
protocol=self.services["natrule"]["protocol"],
cidrlist=['0.0.0.0/0'],
startport=self.services["natrule"]["publicport"],
endport=self.services["natrule"]["publicport"]
)
logger.debug("Creating NAT rule for VM ID: %s" % virtual_machine.id)
nat_rule = NATRule.create(
self.apiclient,
virtual_machine,
self.services["natrule"],
public_ip.id
)
# Verify network mtu set
self.verify_network_mtu(isolated_network1, public_mtu, private_mtu)
self.checkRouterNicMtus(isolated_network1, public_mtu, private_mtu)
self.checkNetworkMtu(isolated_network1, public_mtu, private_mtu)
logger.debug("Update the network's MTU")
updated_network = isolated_network1.update(self.apiclient, id=isolated_network1.id, public_mtu=1450)
logger.debug("Ping the external network with packet size greater than configured mtu %s : %s", public_mtu, 1500)
expected = 1
check_string = "Frag needed and DF set"
cmd = "ping -M do -s {mtu} 8.8.8.8 -c1"
result = self.check_router_command(virtual_machine, nat_rule.ipaddress, cmd.format(mtu="1500"), check_string, self)
self.assertEqual(
result,
expected,
"Ping to outside world from VM should be successful!"
)
logger.debug("Ping the external network with packet size lesser than configured mtu %s : %s", public_mtu, 1100)
expected = 1
check_string = "0% packet loss"
cmd = "ping -M do -s {mtu} 8.8.8.8 -c1"
result = self.check_router_command(virtual_machine, nat_rule.ipaddress, cmd.format(mtu="1200"), check_string, self)
self.assertEqual(
result,
expected,
"Ping to outside world from VM should be successful!"
)
self.checkRouterNicMtus(updated_network, public_mtu, private_mtu)
self.checkNetworkMtu(updated_network, public_mtu, private_mtu)
def verify_network_mtu(self, network, public_mtu, private_mtu):
# Verify network mtu set
result = self.dbclient.execute("select public_mtu, private_mtu from networks where uuid='%s'"
% str(network.id))
self.assertEqual(isinstance(result, list),
True,
"Check DB query result set for valid data")
self.assertNotEqual(len(result),
0,
"Check DB Query result set")
self.assertEqual(result[0][0],
public_mtu if public_mtu < 1500 else 1500,
"DB results not matching, expected: %s found: %s " % (public_mtu, result[0][0]))
self.assertEqual(result[0][1],
private_mtu if private_mtu < 1500 else 1500,
"DB results not matching, expected: %s found: %s " % (private_mtu, result[0][1]))
def check_router_command(self, virtual_machine, public_ip, ssh_command, check_string, test_case, retries=5):
result = 'failed'
try:
ssh = virtual_machine.get_ssh_client(ipaddress=public_ip, retries=retries)
result = str(ssh.execute(ssh_command))
except Exception as e:
test_case.fail("Failed to SSH into the Virtual Machine: %s" % e)
logging.debug("Result from SSH into the Virtual Machine: %s" % result)
return result.count(check_string)
def checkRouterNicMtus(self, network, public_mtu, private_mtu):
self.debug("Listing routers for network: %s" % network.name)
self.routers = Router.list(
self.apiclient,
networkid=network.id,
listall=True
)
self.assertTrue(
isinstance(self.routers, list),
"Check listRouters response returns a valid list"
)
self.assertTrue(
len(self.routers) > 0,
"Router for the network isn't found"
)
for router in self.routers:
nics = router.nic
for nic in nics:
if nic.traffictype == 'Guest':
self.assertEqual(private_mtu, nic.mtu, "MTU not properly configured on private interface of VR")
if nic.traffictype == 'Public':
self.assertEqual(public_mtu, nic.mtu, "MTU not properly configured on public interface of VR")
def checkNetworkMtu(self, network, expected_public_mtu, expected_private_mtu):
self.assertEqual(expected_public_mtu, network.publicmtu)
self.assertEqual(expected_private_mtu, network.privatemtu)

View File

@ -1,4 +1,5 @@
# Licensed to the Apache Software Foundation (ASF) under one
# 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
@ -49,10 +50,13 @@ from marvin.lib.common import (get_domain,
list_virtual_machines,
list_lb_rules,
list_configurations,
verifyGuestTrafficPortGroups)
verifyGuestTrafficPortGroups,
verifyNetworkState)
from nose.plugins.attrib import attr
from marvin.lib.decoratorGenerators import skipTestIf
from ddt import ddt, data
import unittest
# Import System modules
import time
import logging
@ -65,6 +69,7 @@ stream_handler = logging.StreamHandler()
logger.setLevel(logging.DEBUG)
logger.addHandler(stream_handler)
class TestPublicIP(cloudstackTestCase):
def setUp(self):
@ -233,9 +238,9 @@ class TestPublicIP(cloudstackTestCase):
if list_pub_ip_addr_resp is None:
return
if (list_pub_ip_addr_resp) and (
isinstance(
list_pub_ip_addr_resp,
list)) and (
isinstance(
list_pub_ip_addr_resp,
list)) and (
len(list_pub_ip_addr_resp) > 0):
self.fail("list public ip response is not empty")
return
@ -441,10 +446,10 @@ class TestPortForwarding(cloudstackTestCase):
# SSH virtual machine to test port forwarding
try:
logger.debug("SSHing into VM with IP address %s with NAT IP %s" %
(
self.virtual_machine.ipaddress,
src_nat_ip_addr.ipaddress
))
(
self.virtual_machine.ipaddress,
src_nat_ip_addr.ipaddress
))
self.virtual_machine.get_ssh_client(src_nat_ip_addr.ipaddress)
vm_response = VirtualMachine.list(
@ -569,10 +574,10 @@ class TestPortForwarding(cloudstackTestCase):
try:
logger.debug("SSHing into VM with IP address %s with NAT IP %s" %
(
self.virtual_machine.ipaddress,
ip_address.ipaddress.ipaddress
))
(
self.virtual_machine.ipaddress,
ip_address.ipaddress.ipaddress
))
self.virtual_machine.get_ssh_client(ip_address.ipaddress.ipaddress)
except Exception as e:
self.fail(
@ -1087,7 +1092,8 @@ class TestRouterRules(cloudstackTestCase):
cls.domain = get_domain(cls.apiclient)
cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests())
cls.hypervisor = testClient.getHypervisorInfo()
cls.hostConfig = cls.config.__dict__["zones"][0].__dict__["pods"][0].__dict__["clusters"][0].__dict__["hosts"][0].__dict__
cls.hostConfig = cls.config.__dict__["zones"][0].__dict__["pods"][0].__dict__["clusters"][0].__dict__["hosts"][
0].__dict__
template = get_test_template(
cls.apiclient,
cls.zone.id,
@ -1279,10 +1285,10 @@ class TestRouterRules(cloudstackTestCase):
try:
logger.debug("SSHing into VM with IP address %s with NAT IP %s" %
(
self.virtual_machine.ipaddress,
self.ipaddress.ipaddress.ipaddress
))
(
self.virtual_machine.ipaddress,
self.ipaddress.ipaddress.ipaddress
))
self.virtual_machine.get_ssh_client(
self.ipaddress.ipaddress.ipaddress)
except Exception as e:
@ -1319,6 +1325,7 @@ class TestRouterRules(cloudstackTestCase):
)
return
class TestL2Networks(cloudstackTestCase):
def setUp(self):
@ -1411,7 +1418,7 @@ class TestL2Networks(cloudstackTestCase):
list_vm = list_virtual_machines(
self.apiclient,
id = self.virtual_machine.id
id=self.virtual_machine.id
)
self.assertEqual(
isinstance(list_vm, list),
@ -1456,7 +1463,7 @@ class TestL2Networks(cloudstackTestCase):
list_vm = list_virtual_machines(
self.apiclient,
id = self.virtual_machine.id
id=self.virtual_machine.id
)
self.assertEqual(
isinstance(list_vm, list),
@ -1512,7 +1519,7 @@ class TestL2Networks(cloudstackTestCase):
list_vm = list_virtual_machines(
self.apiclient,
id = self.virtual_machine.id
id=self.virtual_machine.id
)
self.assertEqual(
isinstance(list_vm, list),
@ -1542,6 +1549,7 @@ class TestL2Networks(cloudstackTestCase):
return
class TestPrivateVlansL2Networks(cloudstackTestCase):
def setUp(self):
@ -1580,16 +1588,17 @@ class TestPrivateVlansL2Networks(cloudstackTestCase):
# Supported hypervisor = KVM using OVS
isKVM = cls.hypervisor.lower() in ["kvm"]
isOVSEnabled = False
hostConfig = cls.config.__dict__["zones"][0].__dict__["pods"][0].__dict__["clusters"][0].__dict__["hosts"][0].__dict__
if isKVM :
hostConfig = cls.config.__dict__["zones"][0].__dict__["pods"][0].__dict__["clusters"][0].__dict__["hosts"][
0].__dict__
if isKVM:
# Test only if all the hosts use OVS
grepCmd = 'grep "network.bridge.type=openvswitch" /etc/cloudstack/agent/agent.properties'
hosts = list_hosts(cls.apiclient, type='Routing', hypervisor='kvm')
if len(hosts) > 0 :
if len(hosts) > 0:
isOVSEnabled = True
for host in hosts :
for host in hosts:
isOVSEnabled = isOVSEnabled and len(SshClient(host.ipaddress, port=22, user=hostConfig["username"],
passwd=hostConfig["password"]).execute(grepCmd)) != 0
passwd=hostConfig["password"]).execute(grepCmd)) != 0
supported = isVmware and isDvSwitch or isKVM and isOVSEnabled
cls.unsupportedHardware = not supported
@ -1597,7 +1606,6 @@ class TestPrivateVlansL2Networks(cloudstackTestCase):
cls._cleanup = []
if supported:
cls.account = Account.create(
cls.apiclient,
cls.services["account"],
@ -1635,16 +1643,16 @@ class TestPrivateVlansL2Networks(cloudstackTestCase):
"name": "Test Network L2 PVLAN Promiscuous",
"displaytext": "Test Network L2 PVLAN Promiscuous",
"vlan": 900,
"isolatedpvlan" : "900",
"isolatedpvlan": "900",
"isolatedpvlantype": "promiscuous"
}
cls.services["l2-network-pvlan-isolated"] = {
"name": "Test Network L2 PVLAN Isolated",
"displaytext": "Test Network L2 PVLAN Isolated",
"vlan": 900,
"isolatedpvlan": "903",
"isolatedpvlantype": "isolated"
}
"name": "Test Network L2 PVLAN Isolated",
"displaytext": "Test Network L2 PVLAN Isolated",
"vlan": 900,
"isolatedpvlan": "903",
"isolatedpvlantype": "isolated"
}
cls.l2_network_offering = NetworkOffering.create(
cls.apiclient,
@ -1780,10 +1788,15 @@ class TestPrivateVlansL2Networks(cloudstackTestCase):
vm_promiscuous2_ip, vm_promiscuous2_eth = self.enable_l2_nic(vm_promiscuous2)
# Community PVLAN checks
different_community_isolated = self.is_vm_l2_isolated_from_dest(vm_community1_one, vm_community1_one_eth, vm_community2_ip)
same_community_isolated = self.is_vm_l2_isolated_from_dest(vm_community1_one, vm_community1_one_eth, vm_community1_two_ip)
community_to_promiscuous_isolated = self.is_vm_l2_isolated_from_dest(vm_community1_one, vm_community1_one_eth, vm_promiscuous1_ip)
community_to_isolated = self.is_vm_l2_isolated_from_dest(vm_community1_one, vm_community1_one_eth, vm_isolated1_ip)
different_community_isolated = self.is_vm_l2_isolated_from_dest(vm_community1_one, vm_community1_one_eth,
vm_community2_ip)
same_community_isolated = self.is_vm_l2_isolated_from_dest(vm_community1_one, vm_community1_one_eth,
vm_community1_two_ip)
community_to_promiscuous_isolated = self.is_vm_l2_isolated_from_dest(vm_community1_one,
vm_community1_one_eth,
vm_promiscuous1_ip)
community_to_isolated = self.is_vm_l2_isolated_from_dest(vm_community1_one, vm_community1_one_eth,
vm_isolated1_ip)
self.assertTrue(
different_community_isolated,
@ -1807,8 +1820,10 @@ class TestPrivateVlansL2Networks(cloudstackTestCase):
# Isolated PVLAN checks
same_isolated = self.is_vm_l2_isolated_from_dest(vm_isolated1, vm_isolated1_eth, vm_isolated2_ip)
isolated_to_community_isolated = self.is_vm_l2_isolated_from_dest(vm_isolated1, vm_isolated1_eth, vm_community1_one_ip)
isolated_to_promiscuous_isolated = self.is_vm_l2_isolated_from_dest(vm_isolated1, vm_isolated1_eth, vm_promiscuous1_ip)
isolated_to_community_isolated = self.is_vm_l2_isolated_from_dest(vm_isolated1, vm_isolated1_eth,
vm_community1_one_ip)
isolated_to_promiscuous_isolated = self.is_vm_l2_isolated_from_dest(vm_isolated1, vm_isolated1_eth,
vm_promiscuous1_ip)
self.assertTrue(
same_isolated,
@ -1824,8 +1839,10 @@ class TestPrivateVlansL2Networks(cloudstackTestCase):
)
# Promiscuous PVLAN checks
same_promiscuous = self.is_vm_l2_isolated_from_dest(vm_promiscuous1, vm_promiscuous1_eth, vm_promiscuous2_ip)
prom_to_community_isolated = self.is_vm_l2_isolated_from_dest(vm_promiscuous1, vm_promiscuous1_eth, vm_community1_one_ip)
same_promiscuous = self.is_vm_l2_isolated_from_dest(vm_promiscuous1, vm_promiscuous1_eth,
vm_promiscuous2_ip)
prom_to_community_isolated = self.is_vm_l2_isolated_from_dest(vm_promiscuous1, vm_promiscuous1_eth,
vm_community1_one_ip)
prom_to_isolated = self.is_vm_l2_isolated_from_dest(vm_promiscuous1, vm_promiscuous1_eth, vm_isolated1_ip)
self.assertFalse(

View File

@ -3472,7 +3472,7 @@ class Network:
networkofferingid=None, projectid=None,
subdomainaccess=None, zoneid=None,
gateway=None, netmask=None, vpcid=None, aclid=None, vlan=None,
externalid=None, bypassvlanoverlapcheck=None, associatednetworkid=None):
externalid=None, bypassvlanoverlapcheck=None, associatednetworkid=None, publicmtu=None, privatemtu=None):
"""Create Network for account"""
cmd = createNetwork.createNetworkCmd()
cmd.name = services["name"]
@ -3550,6 +3550,10 @@ class Network:
cmd.bypassvlanoverlapcheck = bypassvlanoverlapcheck
if associatednetworkid:
cmd.associatednetworkid = associatednetworkid
if publicmtu:
cmd.publicmtu = publicmtu
if privatemtu:
cmd.privatemtu = privatemtu
return Network(apiclient.createNetwork(cmd).__dict__)
def delete(self, apiclient):
@ -5042,7 +5046,7 @@ class VPC:
[setattr(cmd, k, v) for k, v in list(kwargs.items())]
return VPC(apiclient.createVPC(cmd).__dict__)
def update(self, apiclient, name=None, displaytext=None):
def update(self, apiclient, name=None, displaytext=None, **kwargs):
"""Updates VPC configurations"""
cmd = updateVPC.updateVPCCmd()
@ -5051,7 +5055,8 @@ class VPC:
cmd.name = name
if displaytext:
cmd.displaytext = displaytext
return (apiclient.updateVPC(cmd))
[setattr(cmd, k, v) for k, v in list(kwargs.items())]
return apiclient.updateVPC(cmd)
def migrate(self, apiclient, vpc_offering_id, vpc_network_offering_ids, resume=False):
cmd = migrateVPC.migrateVPCCmd()

View File

@ -1329,6 +1329,8 @@
"label.primary.storage.allocated": "Primary storage allocated",
"label.primary.storage.used": "Primary storage used",
"label.primarystoragelimit": "Primary storage limits (GiB)",
"label.primarystoragetotal": "Primary storage",
"label.privatemtu": "Private Interface MTU",
"label.private.gateway": "Private gateway",
"label.private.interface": "Private interface",
"label.private.registry": "Private registry",
@ -1363,6 +1365,7 @@
"label.provisioningtype.fat": "Fat provisioning",
"label.provisioningtype.sparse": "Sparse provisioning",
"label.provisioningtype.thin": "Thin provisioning",
"label.publicmtu": "Public Interface MTU",
"label.public.interface": "Public interface",
"label.public.ip": "Public IP address",
"label.public.ip.addresses": "Public IP addresses",
@ -2333,6 +2336,9 @@
"message.error.lun": "Please enter LUN #.",
"message.error.macaddress": "Please enter a valid MAC Address.",
"message.error.max.members.less.than.min.members": "The value of Max members must be larger than the value of Min members",
"message.error.mtu.below.min": "MTU is below the minimum supported value of %x",
"message.error.mtu.public.max.exceed": "The value entered exceeds the maximum allowed public MTU for this Zone, your value will be automatically lowered to match it.",
"message.error.mtu.private.max.exceed": "The value entered exceeds the maximum allowed private MTU for this Zone, your value will be automatically lowered to match it.",
"message.error.name": "Please enter name.",
"message.error.netmask": "Please enter Netmask.",
"message.error.network.offering": "Please select network offering.",
@ -2744,6 +2750,7 @@
"message.vr.alert.upon.network.offering.creation.l2": "As virtual routers are not created for L2 networks, the compute offering will not be used.",
"message.vr.alert.upon.network.offering.creation.others": "As none of the obligatory services for creating a virtual router (VPN, DHCP, DNS, Firewall, LB, UserData, SourceNat, StaticNat, PortForwarding) are enabled, the virtual router will not be created and the compute offering will not be used.",
"message.warn.filetype": "jpg, jpeg, png, bmp and svg are the only supported image formats.",
"message.warn.zone.mtu.update": "Please note that this limit won't affect pre-existing networks MTU settings",
"message.zone.creation.complete": "Zone creation complete.",
"message.zone.detail.description": "Populate zone details.",
"message.zone.detail.hint": "A zone is the largest organizational unit in CloudStack, and it typically corresponds to a single datacenter. Zones provide physical isolation and redundancy. A zone consists of one or more pods (each of which contains hosts and primary storage servers) and a secondary storage server which is shared by all pods in the zone.",

View File

@ -74,6 +74,13 @@
<div>{{ ipV6Address }}</div>
</div>
</a-list-item>
<a-list-item v-else-if="(item === 'privatemtu' && !['L2', 'Shared'].includes(dataResource['type'])) || (item === 'publicmtu' && dataResource['type'] !== 'L2')">
<div>
<strong>{{ $t('label.' + String(item).toLowerCase()) }}</strong>
<br/>
<div>{{ dataResource[item] }}</div>
</div>
</a-list-item>
</template>
<HostInfo :resource="dataResource" v-if="$route.meta.name === 'host' && 'listHosts' in $store.getters.apis" />
<DedicateData :resource="dataResource" v-if="dedicatedSectionActive" />
@ -128,7 +135,7 @@ export default {
},
computed: {
customDisplayItems () {
return ['ip6routes']
return ['ip6routes', 'privatemtu', 'publicmtu']
},
ipV6Address () {
if (this.dataResource.nic && this.dataResource.nic.length > 0) {

View File

@ -102,7 +102,17 @@ export default {
editableValueKey: null,
editableValue: '',
tabLoading: false,
filter: ''
filter: '',
warningMessages: {
'vr.private.interface.max.mtu': {
scope: 'zone',
warning: this.$t('message.warn.zone.mtu.update')
},
'vr.public.interface.max.mtu': {
scope: 'zone',
warning: this.$t('message.warn.zone.mtu.update')
}
}
}
},
created () {
@ -165,7 +175,7 @@ export default {
value: this.editableValue
}).then(() => {
const message = `${this.$t('label.setting')} ${item.name} ${this.$t('label.update.to')} ${this.editableValue}`
this.$message.success(message)
this.handleSuccessMessage(item.name, this.$route.meta.name, message)
}).catch(error => {
console.error(error)
this.$message.error(this.$t('message.error.save.setting'))
@ -195,7 +205,7 @@ export default {
name: item.name
}).then(() => {
const message = `${this.$t('label.setting')} ${item.name} ${this.$t('label.reset.config.value')}`
this.$message.success(message)
this.handleSuccessMessage(item.name, this.$route.meta.name, message)
}).catch(error => {
console.error(error)
this.$message.error(this.$t('message.error.reset.config'))
@ -209,6 +219,14 @@ export default {
this.editableValueKey = null
})
})
},
handleSuccessMessage (name, scope, message) {
var obj = this.warningMessages[name]
if (obj && obj.scope === scope) {
this.$warning({ title: message, content: obj.warning })
} else {
this.$message.success(message)
}
}
}
}

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', 'dns1', 'dns2', 'ip6dns1', 'ip6dns2']
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', 'publicmtu', 'privatemtu']
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', 'dns1', 'dns2', 'ip6dns1', 'ip6dns2'],
details: ['name', 'id', 'displaytext', 'cidr', 'networkdomain', 'ip6routes', 'ispersistent', 'redundantvpcrouter', 'restartrequired', 'zonename', 'account', 'domain', 'dns1', 'dns2', 'ip6dns1', 'ip6dns2', 'publicmtu'],
searchFilters: ['name', 'zoneid', 'domainid', 'account', 'tags'],
related: [{
name: 'vm',
@ -200,7 +200,7 @@ export default {
icon: 'edit-outlined',
label: 'label.edit',
dataView: true,
args: ['name', 'displaytext']
args: ['name', 'displaytext', 'publicmtu']
},
{
api: 'restartVPC',

View File

@ -1687,6 +1687,7 @@ export default {
this.rules[field.name].push(rule)
break
case (this.currentAction.mapping && field.name in this.currentAction.mapping && 'options' in this.currentAction.mapping[field.name]):
console.log('op: ' + field)
rule.required = field.required
rule.message = this.$t('message.error.select')
this.rules[field.name].push(rule)
@ -1697,17 +1698,20 @@ export default {
this.rules[field.name].push(rule)
break
case (field.type === 'uuid'):
console.log('uuid: ' + field)
rule.required = field.required
rule.message = this.$t('message.error.select')
this.rules[field.name].push(rule)
break
case (field.type === 'list'):
console.log('list: ' + field)
rule.type = 'array'
rule.required = field.required
rule.message = this.$t('message.error.select')
this.rules[field.name].push(rule)
break
case (field.type === 'long'):
console.log(field)
rule.type = 'number'
rule.required = field.required
rule.message = this.$t('message.validate.number')
@ -1728,6 +1732,7 @@ export default {
this.rules[field.name].push(rule)
break
default:
console.log('hererere')
rule.required = field.required
rule.message = this.$t('message.error.required.input')
this.rules[field.name].push(rule)

View File

@ -104,6 +104,38 @@
</a-select-option>
</a-select>
</a-form-item>
<a-row :gutter="12" v-if="setMTU">
<a-col :md="12" :lg="12">
<a-form-item
ref="publicmtu"
name="publicmtu">
<template #label>
<tooltip-label :title="$t('label.publicmtu')" :tooltip="apiParams.publicmtu.description"/>
</template>
<a-input-number
style="width: 100%;"
v-model:value="form.publicmtu"
:placeholder="apiParams.publicmtu.description"
@change="updateMtu(true)"/>
<div style="color: red" v-if="errorPublicMtu" v-html="errorPublicMtu"></div>
</a-form-item>
</a-col>
<a-col :md="12" :lg="12">
<a-form-item
ref="privatemtu"
name="privatemtu">
<template #label>
<tooltip-label :title="$t('label.privatemtu')" :tooltip="apiParams.privatemtu.description"/>
</template>
<a-input-number
style="width: 100%;"
v-model:value="form.privatemtu"
:placeholder="apiParams.privatemtu.description"
@change="updateMtu(false)"/>
<div style="color: red" v-if="errorPrivateMtu" v-html="errorPrivateMtu"></div>
</a-form-item>
</a-col>
</a-row>
<a-form-item
ref="vlan"
name="vlan"
@ -316,7 +348,13 @@ export default {
vpcs: [],
vpcLoading: false,
selectedVpc: {},
accountVisible: isAdminOrDomainAdmin()
accountVisible: isAdminOrDomainAdmin(),
privateMtuMax: 1500,
publicMtuMax: 1500,
minMTU: 68,
errorPublicMtu: '',
errorPrivateMtu: '',
setMTU: false
}
},
watch: {
@ -365,6 +403,9 @@ export default {
fetchData () {
this.fetchDomainData()
this.fetchZoneData()
this.allowSettingMTU()
},
allowSettingMTU () {
},
isAdminOrDomainAdmin () {
return isAdminOrDomainAdmin()
@ -402,6 +443,9 @@ export default {
},
handleZoneChange (zone) {
this.selectedZone = zone
this.setMTU = zone?.allowuserspecifyvrmtu || false
this.privateMtuMax = zone?.routerprivateinterfacemaxmtu || 1500
this.publicMtuMax = zone?.routerpublicinterfacemaxmtu || 1500
this.updateVPCCheckAndFetchNetworkOfferingData()
},
fetchDomainData () {
@ -519,6 +563,12 @@ export default {
params[field] = values[field]
}
}
if (this.isValidTextValueForKey(values, 'publicmtu')) {
params.publicmtu = values.publicmtu
}
if (this.isValidTextValueForKey(values, 'privatemtu')) {
params.privatemtu = values.privatemtu
}
if ('domainid' in values && values.domainid > 0) {
params.domainid = this.selectedDomain.id
if (this.isValidTextValueForKey(values, 'account')) {
@ -541,6 +591,29 @@ export default {
this.formRef.value.scrollToField(error.errorFields[0].name)
})
},
updateMtu (isPublic) {
if (isPublic) {
if (this.form.publicmtu > this.publicMtuMax) {
this.errorPublicMtu = this.$t('message.error.mtu.public.max.exceed')
this.form.publicmtu = this.publicMtuMax
} else if (this.form.publicmtu < this.minMTU) {
this.errorPublicMtu = `${this.$t('message.error.mtu.below.min').replace('%x', this.minMTU)}`
this.form.publicmtu = this.minMTU
} else {
this.errorPublicMtu = ''
}
} else {
if (this.form.privatemtu > this.privateMtuMax) {
this.errorPrivateMtu = this.$t('message.error.mtu.private.max.exceed')
this.form.privatemtu = this.privateMtuMax
} else if (this.form.privatemtu < this.minMTU) {
this.errorPrivateMtu = `${this.$t('message.error.mtu.below.min').replace('%x', this.minMTU)}`
this.form.privatemtu = this.minMTU
} else {
this.errorPrivateMtu = ''
}
}
},
showInput () {
this.inputVisible = true
this.$nextTick(function () {

View File

@ -243,6 +243,38 @@
<template #message>{{ $t('message.shared.network.offering.warning') }}</template>
</a-alert>
</a-form-item>
<a-row :gutter="12" v-if="setMTU">
<a-col :md="12" :lg="12">
<a-form-item
ref="publicmtu"
name="publicmtu">
<template #label>
<tooltip-label :title="$t('label.publicmtu')" :tooltip="apiParams.publicmtu.description"/>
</template>
<a-input-number
style="width: 100%;"
v-model:value="form.publicmtu"
:placeholder="apiParams.publicmtu.description"
@change="updateMtu(true)"/>
<div style="color: red" v-if="errorPublicMtu" v-html="errorPublicMtu"></div>
</a-form-item>
</a-col>
<a-col :md="12" :lg="12">
<a-form-item
ref="privatemtu"
name="privatemtu">
<template #label>
<tooltip-label :title="$t('label.privatemtu')" :tooltip="apiParams.privatemtu.description"/>
</template>
<a-input-number
style="width: 100%;"
v-model:value="form.privatemtu"
:placeholder="apiParams.privatemtu.description"
@change="updateMtu(false)"/>
<div style="color: red" v-if="errorPrivateMtu" v-html="errorPrivateMtu"></div>
</a-form-item>
</a-col>
</a-row>
<a-form-item v-if="!isObjectEmpty(selectedNetworkOffering) && !selectedNetworkOffering.specifyvlan" name="associatednetworkid" ref="associatednetworkid">
<template #label>
<tooltip-label :title="$t('label.associatednetwork')" :tooltip="apiParams.associatednetworkid.description"/>
@ -497,6 +529,7 @@ export default {
networkOfferingLoading: false,
networkOfferingWarning: false,
selectedNetworkOffering: {},
isRedundant: false,
networks: [],
networkLoading: false,
selectedNetwork: {},
@ -507,7 +540,13 @@ export default {
projectLoading: false,
selectedProject: {},
isVirtualRouterForAtLeastOneService: false,
selectedServiceProviderMap: {}
selectedServiceProviderMap: {},
privateMtuMax: 1500,
publicMtuMax: 1500,
minMTU: 68,
setMTU: false,
errorPublicMtu: '',
errorPrivateMtu: ''
}
},
watch: {
@ -624,6 +663,9 @@ export default {
},
handleZoneChange (zone) {
this.selectedZone = zone
this.setMTU = zone?.allowuserspecifyvrmtu || false
this.privateMtuMax = zone?.routerprivateinterfacemaxmtu || 1500
this.publicMtuMax = zone?.routerpublicinterfacemaxmtu || 1500
if (isAdmin()) {
this.fetchPhysicalNetworkData()
} else {
@ -1027,6 +1069,12 @@ export default {
if (hideipaddressusage) {
params.hideipaddressusage = true
}
if (this.isValidTextValueForKey(values, 'publicmtu')) {
params.publicmtu = values.publicmtu
}
if (this.isValidTextValueForKey(values, 'privatemtu')) {
params.privatemtu = values.privatemtu
}
api('createNetwork', params).then(json => {
this.$notification.success({
message: this.$t('label.network'),
@ -1056,6 +1104,29 @@ export default {
},
closeAction () {
this.$emit('close-action')
},
updateMtu (isPublic) {
if (isPublic) {
if (this.form.publicmtu > this.publicMtuMax) {
this.errorPublicMtu = `${this.$t('message.error.mtu.public.max.exceed').replace('%x', this.publicMtuMax)}`
this.form.publicmtu = this.publicMtuMax
} else if (this.form.publicmtu < this.minMTU) {
this.errorPublicMtu = `${this.$t('message.error.mtu.below.min').replace('%x', this.minMTU)}`
this.form.publicmtu = this.minMTU
} else {
this.errorPublicMtu = ''
}
} else {
if (this.form.privatemtu > this.privateMtuMax) {
this.errorPrivateMtu = `${this.$t('message.error.mtu.private.max.exceed').replace('%x', this.privateMtuMax)}`
this.form.privatemtu = this.privateMtuMax
} else if (this.form.privatemtu < this.minMTU) {
this.errorPrivateMtu = `${this.$t('message.error.mtu.below.min').replace('%x', this.minMTU)}`
this.form.privatemtu = this.minMTU
} else {
this.errorPrivateMtu = ''
}
}
}
}
}

View File

@ -96,6 +96,21 @@
</a-select-option>
</a-select>
</a-form-item>
<div v-if="setMTU">
<a-form-item
ref="publicmtu"
name="publicmtu">
<template #label>
<tooltip-label :title="$t('label.publicmtu')" :tooltip="apiParams.publicmtu.description"/>
</template>
<a-input-number
style="width: 100%;"
v-model:value="form.publicmtu"
:placeholder="apiParams.publicmtu.description"
@change="updateMtu()"/>
<div style="color: red" v-if="errorPublicMtu" v-html="errorPublicMtu"></div>
</a-form-item>
</div>
<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">
@ -171,8 +186,13 @@ export default {
loading: false,
loadingZone: false,
loadingOffering: false,
setMTU: false,
zoneid: '',
zones: [],
vpcOfferings: [],
publicMtuMax: 1500,
minMTU: 68,
errorPublicMtu: '',
selectedVpcOffering: {}
}
},
@ -182,6 +202,7 @@ export default {
created () {
this.initForm()
this.fetchData()
console.log(this.setMTU)
},
computed: {
selectedVpcOfferingSupportsDns () {
@ -207,9 +228,17 @@ export default {
vpcofferingid: [{ required: true, message: this.$t('label.required') }]
})
},
fetchData () {
async fetchData () {
this.fetchZones()
},
fetchPublicMtuForZone () {
api('listConfigurations', {
name: 'vr.public.interface.mtu',
zoneid: this.form.zoneid
}).then(json => {
this.publicMtuMax = json?.listconfigurationsresponse?.configuration[0]?.value || 1500
})
},
fetchZones () {
this.loadingZone = true
api('listZones', { showicon: true }).then((response) => {
@ -230,6 +259,12 @@ export default {
this.form.vpcofferingid = ''
return
}
for (var zone of this.zones) {
if (zone.id === value) {
this.setMTU = zone?.allowuserspecifyvrmtu || false
this.publicMtuMax = zone?.routerpublicinterfacemaxmtu || 1500
}
}
this.fetchOfferings()
},
fetchOfferings () {
@ -257,6 +292,17 @@ export default {
closeAction () {
this.$emit('close-action')
},
updateMtu () {
if (this.form.publicmtu > this.publicMtuMax) {
this.errorPublicMtu = `${this.$t('message.error.mtu.public.max.exceed').replace('%x', this.publicMtuMax)}`
this.form.publicmtu = this.publicMtuMax
} else if (this.form.publicmtu < this.minMTU) {
this.errorPublicMtu = `${this.$t('message.error.mtu.below.min').replace('%x', this.minMTU)}`
this.form.publicmtu = this.minMTU
} else {
this.errorPublicMtu = ''
}
},
handleSubmit (e) {
e.preventDefault()
if (this.loading) return

View File

@ -43,6 +43,43 @@
:placeholder="apiParams.displaytext.description"
autoFocus />
</a-form-item>
<div v-if="setMTU">
<a-row :gutter="12" v-if="resource.type !== 'L2'">
<a-col :md="12" :lg="12">
<a-form-item
v-if="!resource.vpcid"
ref="publicmtu"
name="publicmtu">
<template #label>
<tooltip-label :title="$t('label.publicmtu')" :tooltip="apiParams.publicmtu.description"/>
</template>
<a-input-number
style="width: 100%;"
v-model:value="form.publicmtu"
:defaultValue="resource.publicmtu"
:placeholder="apiParams.publicmtu.description"
@change="updateMtu(true)"/>
<div style="color: red" v-if="errorPublicMtu" v-html="errorPublicMtu"></div>
</a-form-item>
</a-col>
<a-col :md="12" :lg="12">
<a-form-item
ref="privatemtu"
name="privatemtu">
<template #label>
<tooltip-label :title="$t('label.privatemtu')" :tooltip="apiParams.privatemtu.description"/>
</template>
<a-input-number
v-model:value="form.privatemtu"
style="width: 100%;"
:defaultValue="resource.privatemtu"
:placeholder="apiParams.privatemtu.description"
@change="updateMtu(false)"/>
<div style="color: red" v-if="errorPrivateMtu" v-html="errorPrivateMtu"></div>
</a-form-item>
</a-col>
</a-row>
</div>
<a-form-item name="networkofferingid" ref="networkofferingid" v-if="isUpdatingIsolatedNetwork">
<template #label>
<tooltip-label :title="$t('label.networkofferingid')" :tooltip="apiParams.networkofferingid.description"/>
@ -195,7 +232,13 @@ export default {
networkOfferingLoading: false,
networkOffering: {},
cidrChanged: false,
loading: false
loading: false,
privateMtuMax: 1500,
publicMtuMax: 1500,
minMTU: 68,
errorPrivateMtu: '',
errorPublicMtu: '',
setMTU: false
}
},
beforeCreate () {
@ -240,7 +283,9 @@ export default {
initForm () {
this.formRef = ref()
this.form = reactive({
displaynetwork: this.resource.displaynetwork
displaynetwork: this.resource.displaynetwork,
privatemtu: this.resource.privatemtu,
publicmtu: this.resource.publicmtu
})
this.rules = reactive({
name: [{ required: true, message: this.$t('message.error.required.input') }],
@ -249,6 +294,7 @@ export default {
},
fetchData () {
this.fetchNetworkOfferingData()
this.fetchMtuForZone()
},
isAdmin () {
return isAdmin()
@ -256,6 +302,15 @@ export default {
arrayHasItems (array) {
return array !== null && array !== undefined && Array.isArray(array) && array.length > 0
},
fetchMtuForZone () {
api('listZones', {
id: this.resource.zoneid
}).then(json => {
this.setMTU = json?.listzonesresponse?.zone?.[0]?.allowuserspecifyvrmtu || false
this.privateMtuMax = json?.listzonesresponse?.zone?.[0]?.routerprivateinterfacemaxmtu || 1500
this.publicMtuMax = json?.listzonesresponse?.zone?.[0]?.routerpublicinterfacemaxmtu || 1500
})
},
fetchNetworkOfferingData () {
this.networkOfferings = []
const params = {
@ -283,6 +338,29 @@ export default {
}
})
},
updateMtu (isPublic) {
if (isPublic) {
if (this.form.publicmtu > this.publicMtuMax) {
this.errorPublicMtu = `${this.$t('message.error.mtu.public.max.exceed').replace('%x', this.publicMtuMax)}`
this.form.publicmtu = this.publicMtuMax
} else if (this.form.publicmtu < this.minMTU) {
this.errorPublicMtu = `${this.$t('message.error.mtu.below.min').replace('%x', this.minMTU)}`
this.form.publicmtu = this.minMTU
} else {
this.errorPublicMtu = ''
}
} else {
if (this.form.privatemtu > this.privateMtuMax) {
this.errorPrivateMtu = `${this.$t('message.error.mtu.private.max.exceed').replace('%x', this.privateMtuMax)}`
this.form.privatemtu = this.privateMtuMax
} else if (this.form.privatemtu < this.minMTU) {
this.errorPrivateMtu = `${this.$t('message.error.mtu.below.min').replace('%x', this.minMTU)}`
this.form.privatemtu = this.minMTU
} else {
this.errorPrivateMtu = ''
}
}
},
handleSubmit (e) {
e.preventDefault()
if (this.loading) return

View File

@ -195,6 +195,20 @@
</a-select-option>
</a-select>
</a-form-item>
<a-form-item
v-if="setMTU"
ref="privatemtu"
name="privatemtu">
<template #label>
<tooltip-label :title="$t('label.privatemtu')" :tooltip="$t('label.privatemtu')"/>
</template>
<a-input-number
style="width: 100%;"
v-model:value="form.privatemtu"
:placeholder="$t('label.privatemtu')"
@change="updateMtu()"/>
<div style="color: red" v-if="errorPrivateMtu" v-html="errorPrivateMtu.replace('%x', privateMtuMax)"></div>
</a-form-item>
<a-form-item v-if="!isObjectEmpty(selectedNetworkOffering) && selectedNetworkOffering.specifyvlan">
<template #label>
<tooltip-label :title="$t('label.vlan')" :tooltip="$t('label.vlan')"/>
@ -361,6 +375,8 @@ export default {
staticNats: {},
vms: {},
selectedNetworkOffering: {},
privateMtuMax: 1500,
errorPrivateMtu: '',
algorithms: {
Source: 'source',
'Round-robin': 'roundrobin',
@ -453,7 +469,8 @@ export default {
vpc: ['Netscaler']
}
},
publicLBExists: false
publicLBExists: false,
setMTU: false
}
},
created () {
@ -479,8 +496,17 @@ export default {
showIlb (network) {
return network.service.filter(s => (s.name === 'Lb') && (s.capability.filter(c => c.name === 'LbSchemes' && c.value === 'Internal').length > 0)).length > 0 || false
},
updateMtu () {
if (this.form.privatemtu > this.privateMtuMax) {
this.errorPrivateMtu = `${this.$t('message.error.mtu.private.max.exceed')}`
this.form.privatemtu = this.privateMtuMax
} else {
this.errorPrivateMtu = ''
}
},
fetchData () {
this.networks = this.resource.network
this.fetchMtuForZone()
if (!this.networks || this.networks.length === 0) {
return
}
@ -490,6 +516,14 @@ export default {
}
this.publicLBNetworkExists()
},
fetchMtuForZone () {
api('listZones', {
id: this.resource.zoneid
}).then(json => {
this.setMTU = json?.listzonesresponse?.zone?.[0]?.allowuserspecifyvrmtu || false
this.privateMtuMax = json?.listzonesresponse?.zone?.[0]?.routerprivateinterfacemaxmtu || 1500
})
},
fetchNetworkAclList () {
this.fetchLoading = true
this.modalLoading = true
@ -660,6 +694,10 @@ export default {
params.vlan = values.vlan
}
if (values.privatemtu) {
params.privatemtu = values.privatemtu
}
api('createNetwork', params).then(() => {
this.$notification.success({
message: this.$t('message.success.add.vpc.network')