mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Add option to select DNS or VR IP as resolver on VPC creation
* Add API param and UI to select option * Add column on vpc and pass the value on the databags for CsDhcp.py to fix accordingly
This commit is contained in:
parent
e4e9e470ae
commit
ac53e4b322
@ -105,4 +105,6 @@ public interface Vpc extends ControlledEntity, Identity, InternalIdentity {
|
||||
String getIp6Dns1();
|
||||
|
||||
String getIp6Dns2();
|
||||
|
||||
boolean useRouterIpAsResolver();
|
||||
}
|
||||
|
||||
@ -48,17 +48,17 @@ public interface VpcService {
|
||||
* @param vpcName
|
||||
* @param displayText
|
||||
* @param cidr
|
||||
* @param networkDomain TODO
|
||||
* @param networkDomain TODO
|
||||
* @param ip4Dns1
|
||||
* @param ip4Dns2
|
||||
* @param displayVpc TODO
|
||||
* @param displayVpc TODO
|
||||
* @param useVrIpResolver
|
||||
* @return
|
||||
* @throws ResourceAllocationException TODO
|
||||
*/
|
||||
Vpc createVpc(long zoneId, long vpcOffId, long vpcOwnerId, String vpcName, String displayText, String cidr, String networkDomain,
|
||||
String ip4Dns1, String ip4Dns2, String ip6Dns1, String ip6Dns2, Boolean displayVpc, Integer publicMtu, Integer cidrSize,
|
||||
Long asNumber, List<Long> bgpPeerIds)
|
||||
throws ResourceAllocationException;
|
||||
Long asNumber, List<Long> bgpPeerIds, Boolean useVrIpResolver) throws ResourceAllocationException;
|
||||
|
||||
/**
|
||||
* Persists VPC record in the database
|
||||
|
||||
@ -548,6 +548,7 @@ public class ApiConstants {
|
||||
public static final String USER_SECURITY_GROUP_LIST = "usersecuritygrouplist";
|
||||
public static final String USER_SECRET_KEY = "usersecretkey";
|
||||
public static final String USE_VIRTUAL_NETWORK = "usevirtualnetwork";
|
||||
public static final String USE_VIRTUAL_ROUTER_IP_RESOLVER = "userouteripresolver";
|
||||
public static final String UPDATE_IN_SEQUENCE = "updateinsequence";
|
||||
public static final String VALUE = "value";
|
||||
public static final String VIRTUAL_MACHINE_ID = "virtualmachineid";
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.user.vpc;
|
||||
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
@ -125,6 +126,10 @@ public class CreateVPCCmd extends BaseAsyncCreateCmd implements UserCmd {
|
||||
@Parameter(name=ApiConstants.AS_NUMBER, type=CommandType.LONG, since = "4.20.0", description="the AS Number of the VPC tiers")
|
||||
private Long asNumber;
|
||||
|
||||
@Parameter(name=ApiConstants.USE_VIRTUAL_ROUTER_IP_RESOLVER, type=CommandType.BOOLEAN,
|
||||
description="(optional) for NSX based VPCs: when set to true, use the VR IP as nameserver, otherwise use DNS1 and DNS2")
|
||||
private Boolean useVrIpResolver;
|
||||
|
||||
// ///////////////////////////////////////////////////
|
||||
// ///////////////// Accessors ///////////////////////
|
||||
// ///////////////////////////////////////////////////
|
||||
@ -205,6 +210,10 @@ public class CreateVPCCmd extends BaseAsyncCreateCmd implements UserCmd {
|
||||
return asNumber;
|
||||
}
|
||||
|
||||
public boolean getUseVrIpResolver() {
|
||||
return BooleanUtils.toBoolean(useVrIpResolver);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@ -105,6 +105,9 @@ public class VpcVO implements Vpc {
|
||||
@Column(name = "ip6Dns2")
|
||||
String ip6Dns2;
|
||||
|
||||
@Column(name = "use_router_ip_resolver")
|
||||
boolean useRouterIpResolver = false;
|
||||
|
||||
@Transient
|
||||
boolean rollingRestart = false;
|
||||
|
||||
@ -309,4 +312,13 @@ public class VpcVO implements Vpc {
|
||||
public String getIp6Dns2() {
|
||||
return ip6Dns2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useRouterIpAsResolver() {
|
||||
return useRouterIpResolver;
|
||||
}
|
||||
|
||||
public void setUseRouterIpResolver(boolean useRouterIpResolver) {
|
||||
this.useRouterIpResolver = useRouterIpResolver;
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,6 +68,9 @@ ALTER TABLE `cloud`.`kubernetes_cluster` ADD CONSTRAINT `fk_cluster__etcd_templa
|
||||
|
||||
-- Add for_cks column to the user_data table to represent CNI Configuration stored as userdata
|
||||
CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.user_data','for_cks', 'int(1) unsigned DEFAULT "0" COMMENT "if true, the userdata represent CNI configuration meant for CKS use only"');
|
||||
|
||||
-- Add use VR IP as resolver option on VPC
|
||||
CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.vpc','use_router_ip_resolver', 'tinyint(1) DEFAULT 0 COMMENT "use router ip as resolver instead of dns options"');
|
||||
-----------------------------------------------------------
|
||||
-- END - CKS Enhancements
|
||||
-----------------------------------------------------------
|
||||
|
||||
@ -301,7 +301,7 @@ public class NetworkMigrationManagerImpl implements NetworkMigrationManager {
|
||||
|
||||
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.getPublicMtu(), null, null, null);
|
||||
vpc.getIp6Dns1(), vpc.getIp6Dns2(), vpc.isDisplay(), vpc.getPublicMtu(), null, null, null, vpc.useRouterIpAsResolver());
|
||||
|
||||
copyOfVpcId = copyOfVpc.getId();
|
||||
//on resume of migration the uuid will be swapped already. So the copy will have the value of the original vpcid.
|
||||
|
||||
@ -2072,6 +2072,7 @@ Configurable, StateListener<VirtualMachine.State, VirtualMachine.Event, VirtualM
|
||||
* service, we need to override the DHCP response to return DNS server
|
||||
* rather than virtual router itself.
|
||||
*/
|
||||
boolean useRouterIpResolver = getUseRouterIpAsResolver(router);
|
||||
if (dnsProvided || dhcpProvided) {
|
||||
if (defaultDns1 != null) {
|
||||
buf.append(" dns1=").append(defaultDns1);
|
||||
@ -2093,6 +2094,9 @@ Configurable, StateListener<VirtualMachine.State, VirtualMachine.Event, VirtualM
|
||||
if (useExtDns) {
|
||||
buf.append(" useextdns=true");
|
||||
}
|
||||
if (useRouterIpResolver) {
|
||||
buf.append(" userouteripresolver=true");
|
||||
}
|
||||
}
|
||||
|
||||
if (Boolean.TRUE.equals(ExposeDnsAndBootpServer.valueIn(dc.getId()))) {
|
||||
@ -2132,6 +2136,18 @@ Configurable, StateListener<VirtualMachine.State, VirtualMachine.Event, VirtualM
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean getUseRouterIpAsResolver(DomainRouterVO router) {
|
||||
if (router == null || router.getVpcId() == null) {
|
||||
return false;
|
||||
}
|
||||
Vpc vpc = _vpcDao.findById(router.getVpcId());
|
||||
if (vpc == null) {
|
||||
s_logger.warn(String.format("Cannot find VPC with ID %s from router %s", router.getVpcId(), router.getName()));
|
||||
return false;
|
||||
}
|
||||
return vpc.useRouterIpAsResolver();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param routerLogrotateFrequency The string to be checked if matches with any acceptable values.
|
||||
* Checks if the value in the global configuration is an acceptable value to be informed to the Virtual Router.
|
||||
|
||||
@ -1145,7 +1145,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
|
||||
@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, Integer publicMtu,
|
||||
final Integer cidrSize, final Long asNumber, final List<Long> bgpPeerIds) throws ResourceAllocationException {
|
||||
final Integer cidrSize, final Long asNumber, final List<Long> bgpPeerIds, Boolean useVrIpResolver) throws ResourceAllocationException {
|
||||
final Account caller = CallContext.current().getCallingAccount();
|
||||
final Account owner = _accountMgr.getAccount(vpcOwnerId);
|
||||
|
||||
@ -1247,6 +1247,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
|
||||
vpcOff.isRedundantRouter(), ip4Dns1, ip4Dns2, ip6Dns1, ip6Dns2);
|
||||
vpc.setPublicMtu(publicMtu);
|
||||
vpc.setDisplay(Boolean.TRUE.equals(displayVpc));
|
||||
vpc.setUseRouterIpResolver(Boolean.TRUE.equals(useVrIpResolver));
|
||||
|
||||
if (vpc.getCidr() == null && cidrSize != null) {
|
||||
// Allocate a CIDR for VPC
|
||||
@ -1305,7 +1306,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
|
||||
List<Long> bgpPeerIds = (cmd instanceof CreateVPCCmdByAdmin) ? ((CreateVPCCmdByAdmin)cmd).getBgpPeerIds() : null;
|
||||
Vpc vpc = 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.getPublicMtu(), cmd.getCidrSize(), cmd.getAsNumber(), bgpPeerIds);
|
||||
cmd.getIp6Dns2(), cmd.isDisplay(), cmd.getPublicMtu(), cmd.getCidrSize(), cmd.getAsNumber(), bgpPeerIds, cmd.getUseVrIpResolver());
|
||||
|
||||
String sourceNatIP = cmd.getSourceNatIP();
|
||||
boolean forNsx = isVpcForNsx(vpc);
|
||||
|
||||
@ -492,7 +492,7 @@ public class VpcManagerImplTest {
|
||||
try {
|
||||
doNothing().when(resourceLimitService).checkResourceLimit(account, Resource.ResourceType.vpc);
|
||||
manager.createVpc(zoneId, vpcOfferingId, vpcOwnerId, vpcName, vpcName, ip4Cidr, vpcDomain,
|
||||
ip4Dns[0], null, null, null, true, 1500, null, null, null);
|
||||
ip4Dns[0], null, null, null, true, 1500, null, null, null, false);
|
||||
} catch (ResourceAllocationException e) {
|
||||
Assert.fail(String.format("failure with exception: %s", e.getMessage()));
|
||||
}
|
||||
@ -504,7 +504,7 @@ public class VpcManagerImplTest {
|
||||
try {
|
||||
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, 1500, null, null, null);
|
||||
ip4Dns[0], ip4Dns[1], ip6Dns[0], null, true, 1500, null, null, null, false);
|
||||
} catch (ResourceAllocationException e) {
|
||||
Assert.fail(String.format("failure with exception: %s", e.getMessage()));
|
||||
}
|
||||
@ -519,7 +519,7 @@ public class VpcManagerImplTest {
|
||||
try {
|
||||
doNothing().when(resourceLimitService).checkResourceLimit(account, Resource.ResourceType.vpc);
|
||||
manager.createVpc(zoneId, vpcOfferingId, vpcOwnerId, vpcName, vpcName, ip4Cidr, vpcDomain,
|
||||
ip4Dns[0], ip4Dns[1], null, null, true, 1500, null, null, null);
|
||||
ip4Dns[0], ip4Dns[1], null, null, true, 1500, null, null, null, false);
|
||||
} catch (ResourceAllocationException e) {
|
||||
Assert.fail(String.format("failure with exception: %s", e.getMessage()));
|
||||
}
|
||||
@ -536,7 +536,7 @@ public class VpcManagerImplTest {
|
||||
try {
|
||||
doNothing().when(resourceLimitService).checkResourceLimit(account, Resource.ResourceType.vpc);
|
||||
manager.createVpc(zoneId, vpcOfferingId, vpcOwnerId, vpcName, vpcName, ip4Cidr, vpcDomain,
|
||||
ip4Dns[0], ip4Dns[1], null, null, true, 1500, null, null, null);
|
||||
ip4Dns[0], ip4Dns[1], null, null, true, 1500, null, null, null, false);
|
||||
} catch (ResourceAllocationException e) {
|
||||
Assert.fail(String.format("failure with exception: %s", e.getMessage()));
|
||||
}
|
||||
@ -559,7 +559,7 @@ public class VpcManagerImplTest {
|
||||
try {
|
||||
doNothing().when(resourceLimitService).checkResourceLimit(account, Resource.ResourceType.vpc);
|
||||
manager.createVpc(zoneId, vpcOfferingId, vpcOwnerId, vpcName, vpcName, null, vpcDomain,
|
||||
ip4Dns[0], ip4Dns[1], null, null, true, 1500, 24, null, bgpPeerIds);
|
||||
ip4Dns[0], ip4Dns[1], null, null, true, 1500, 24, null, bgpPeerIds, false);
|
||||
} catch (ResourceAllocationException e) {
|
||||
Assert.fail(String.format("failure with exception: %s", e.getMessage()));
|
||||
}
|
||||
|
||||
@ -114,6 +114,9 @@ class CsConfig(object):
|
||||
def expose_dns(self):
|
||||
return self.cmdline().idata().get('exposedns', 'false') == 'true'
|
||||
|
||||
def use_router_ip_as_resolver(self):
|
||||
return self.cl.get_use_router_ip_as_resolver()
|
||||
|
||||
def get_dns(self):
|
||||
conf = self.cmdline().idata()
|
||||
dns = []
|
||||
@ -123,9 +126,10 @@ class CsConfig(object):
|
||||
else:
|
||||
dns.append(self.address().get_guest_ip())
|
||||
|
||||
for name in ('dns1', 'dns2'):
|
||||
if name in conf:
|
||||
dns.append(conf[name])
|
||||
if not 'userouteripresolver' in conf:
|
||||
for name in ('dns1', 'dns2'):
|
||||
if name in conf:
|
||||
dns.append(conf[name])
|
||||
return dns
|
||||
|
||||
def get_format(self):
|
||||
|
||||
@ -176,6 +176,11 @@ class CsCmdLine(CsDataBag):
|
||||
return self.idata()['useextdns']
|
||||
return False
|
||||
|
||||
def get_use_router_ip_as_resolver(self):
|
||||
if "userouteripresolver" in self.idata():
|
||||
return self.idata()['userouteripresolver']
|
||||
return False
|
||||
|
||||
def get_advert_int(self):
|
||||
if 'advert_int' in self.idata():
|
||||
return self.idata()['advert_int']
|
||||
|
||||
@ -38,6 +38,9 @@ class CsGuestNetwork:
|
||||
if not self.guest:
|
||||
return self.config.get_dns()
|
||||
|
||||
if self.config.use_router_ip_as_resolver():
|
||||
return [self.data['router_guest_ip']]
|
||||
|
||||
dns = []
|
||||
if 'router_guest_gateway' in self.data and not self.config.use_extdns() and ('is_vr_guest_gateway' not in self.data or not self.data['is_vr_guest_gateway']):
|
||||
dns.append(self.data['router_guest_gateway'])
|
||||
|
||||
@ -2488,6 +2488,7 @@
|
||||
"label.usagetypedescription": "Usage description",
|
||||
"label.use.kubectl.access.cluster": "<code><b>kubectl</b></code> and <code><b>kubeconfig</b></code> file to access cluster",
|
||||
"label.use.local.timezone": "Use local timezone",
|
||||
"label.use.router.ip.resolver": "Use Virtual Router IP as resolver",
|
||||
"label.used": "Used",
|
||||
"label.usehttps": "Use HTTPS",
|
||||
"label.usenewdiskoffering": "Replace disk offering?",
|
||||
|
||||
@ -142,7 +142,15 @@
|
||||
<div style="color: red" v-if="errorPublicMtu" v-html="errorPublicMtu"></div>
|
||||
</a-form-item>
|
||||
</div>
|
||||
<a-row :gutter="12" v-if="selectedVpcOfferingSupportsDns">
|
||||
<div v-if="isNsxNetwork">
|
||||
<a-form-item name="userouteripresolver" ref="userouteripresolver">
|
||||
<template #label>
|
||||
<tooltip-label :title="$t('label.use.router.ip.resolver')" :tooltip="apiParams.userouteripresolver.description"/>
|
||||
</template>
|
||||
<a-switch v-model:checked="useRouterIpResolver" />
|
||||
</a-form-item>
|
||||
</div>
|
||||
<a-row :gutter="12" v-if="selectedVpcOfferingSupportsDns && !useRouterIpResolver">
|
||||
<a-col :md="12" :lg="12">
|
||||
<a-form-item v-if="'dns1' in apiParams" name="dns1" ref="dns1">
|
||||
<template #label>
|
||||
@ -240,7 +248,8 @@ export default {
|
||||
isNsxNetwork: false,
|
||||
asNumberLoading: false,
|
||||
asNumbersZone: [],
|
||||
selectedAsNumber: 0
|
||||
selectedAsNumber: 0,
|
||||
useRouterIpResolver: false
|
||||
}
|
||||
},
|
||||
beforeCreate () {
|
||||
@ -459,6 +468,9 @@ export default {
|
||||
if ('asnumber' in values && this.isASNumberRequired()) {
|
||||
params.asnumber = values.asnumber
|
||||
}
|
||||
if (this.useRouterIpResolver) {
|
||||
params.userouteripresolver = true
|
||||
}
|
||||
this.loading = true
|
||||
const title = this.$t('label.add.vpc')
|
||||
const description = this.$t('message.success.add.vpc')
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user