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