@@ -30,12 +30,14 @@ var (
3030	ResourceTypeSubnet         =  common .ResourceTypeSubnet 
3131	NewConverter               =  common .NewConverter 
3232	// Default static ip-pool under Subnet. 
33- 	SubnetTypeError  =  errors .New ("unsupported type" )
33+ 	SubnetTypeError             =  errors .New ("unsupported type" )
34+ 	ErrorCodeUnrecognizedField  =  int64 (287 )
3435)
3536
3637type  SubnetService  struct  {
3738	common.Service 
38- 	SubnetStore  * SubnetStore 
39+ 	SubnetStore   * SubnetStore 
40+ 	useLegacyAPI  bool 
3941}
4042
4143// SubnetParameters stores parameters to CRUD Subnet object 
@@ -81,9 +83,22 @@ func InitializeSubnetService(service common.Service) (*SubnetService, error) {
8183	return  subnetService , nil 
8284}
8385
84- func  (service  * SubnetService ) CreateOrUpdateSubnet (obj  client.Object , vpcInfo  common.VPCResourceInfo , tags  []model.Tag ) (string , error ) {
86+ func  (service  * SubnetService ) CreateOrUpdateSubnet (obj  client.Object , vpcInfo  common.VPCResourceInfo , tags  []model.Tag ) (subnetPath  string , err  error ) {
87+ 	if  subnetPath , err  =  service .createOrUpdateSubnetWithAPI (obj , vpcInfo , tags , service .useLegacyAPI ); err  !=  nil  {
88+ 		if  nsxErr , ok  :=  err .(* nsxutil.NSXApiError ); ok  {
89+ 			if  * nsxErr .ErrorCode  ==  ErrorCodeUnrecognizedField  {
90+ 				log .Info ("NSX does not support subnet_dhcp_config, using old API" , "error" , err )
91+ 				service .useLegacyAPI  =  true 
92+ 				subnetPath , err  =  service .createOrUpdateSubnetWithAPI (obj , vpcInfo , tags , service .useLegacyAPI )
93+ 			}
94+ 		}
95+ 	}
96+ 	return  subnetPath , err 
97+ }
98+ 
99+ func  (service  * SubnetService ) createOrUpdateSubnetWithAPI (obj  client.Object , vpcInfo  common.VPCResourceInfo , tags  []model.Tag , useLegacyAPI  bool ) (string , error ) {
85100	uid  :=  string (obj .GetUID ())
86- 	nsxSubnet , err  :=  service .buildSubnet (obj , tags )
101+ 	nsxSubnet , err  :=  service .buildSubnet (obj , tags ,  useLegacyAPI )
87102	if  err  !=  nil  {
88103		log .Error (err , "Failed to build Subnet" )
89104		return  "" , err 
@@ -97,9 +112,13 @@ func (service *SubnetService) CreateOrUpdateSubnet(obj client.Object, vpcInfo co
97112		} else  {
98113			changed  =  common .CompareResource (SubnetToComparable (existingSubnet ), SubnetToComparable (nsxSubnet ))
99114			if  changed  {
100- 				// Only tags are expected to be updated 
115+ 				// Only tags and dhcp  are expected to be updated 
101116				// inherit other fields from the existing Subnet 
102117				existingSubnet .Tags  =  nsxSubnet .Tags 
118+ 				if  existingSubnet .SubnetDhcpConfig  !=  nil  {
119+ 					existingSubnet .SubnetDhcpConfig  =  nsxSubnet .SubnetDhcpConfig 
120+ 					existingSubnet .AdvancedConfig .StaticIpAllocation .Enabled  =  nsxSubnet .AdvancedConfig .StaticIpAllocation .Enabled 
121+ 				}
103122				nsxSubnet  =  existingSubnet 
104123			}
105124		}
@@ -388,11 +407,15 @@ func (service *SubnetService) GenerateSubnetNSTags(obj client.Object) []model.Ta
388407	return  tags 
389408}
390409
391- func  (service  * SubnetService ) UpdateSubnetSetTags (ns  string , vpcSubnets  []* model.VpcSubnet , tags  []model.Tag ) error  {
410+ func  (service  * SubnetService ) UpdateSubnetSet (ns  string , vpcSubnets  []* model.VpcSubnet , tags  []model.Tag , dhcpMode  string ) error  {
411+ 	if  dhcpMode  ==  ""  {
412+ 		dhcpMode  =  v1alpha1 .DHCPConfigModeDeactivated 
413+ 	}
414+ 	staticIpAllocation  :=  (dhcpMode  ==  v1alpha1 .DHCPConfigModeDeactivated )
392415	for  i , vpcSubnet  :=  range  vpcSubnets  {
393416		subnetSet  :=  & v1alpha1.SubnetSet {}
394417		var  name  string 
395- 
418+ 		 // Generate new Subnet tags 
396419		matchNamespace  :=  false 
397420		for  _ , t  :=  range  vpcSubnets [i ].Tags  {
398421			tag  :=  t 
@@ -417,12 +440,30 @@ func (service *SubnetService) UpdateSubnetSetTags(ns string, vpcSubnets []*model
417440			return  fmt .Errorf ("failed to get SubnetSet %s in Namespace %s: %w" , name , ns , err )
418441		}
419442		newTags  :=  append (service .buildBasicTags (subnetSet ), tags ... )
420- 		changed  :=  common .CompareResource (SubnetToComparable (vpcSubnets [i ]), SubnetToComparable (& model.VpcSubnet {Tags : newTags }))
443+ 
444+ 		var  updatedSubnet  * model.VpcSubnet 
445+ 		if  vpcSubnets [i ].SubnetDhcpConfig  ==  nil  {
446+ 			updatedSubnet  =  & model.VpcSubnet {
447+ 				Tags : newTags ,
448+ 			}
449+ 		} else  {
450+ 			updatedSubnet  =  & model.VpcSubnet {
451+ 				Tags :             newTags ,
452+ 				SubnetDhcpConfig : service .buildSubnetDHCPConfig (dhcpMode ),
453+ 			}
454+ 		}
455+ 		changed  :=  common .CompareResource (SubnetToComparable (vpcSubnets [i ]), SubnetToComparable (updatedSubnet ))
421456		if  ! changed  {
422- 			log .Info ("NSX Subnet tags  unchanged, skipping update" , "subnet " , * vpcSubnet .Id )
457+ 			log .Info ("NSX Subnet unchanged, skipping update" , "Subnet " , * vpcSubnet .Id )
423458			continue 
424459		}
460+ 
425461		vpcSubnets [i ].Tags  =  newTags 
462+ 		// Update the SubnetSet DHCP Config 
463+ 		if  vpcSubnets [i ].SubnetDhcpConfig  !=  nil  {
464+ 			vpcSubnets [i ].SubnetDhcpConfig  =  service .buildSubnetDHCPConfig (dhcpMode )
465+ 			vpcSubnets [i ].AdvancedConfig .StaticIpAllocation .Enabled  =  & staticIpAllocation 
466+ 		}
426467
427468		vpcInfo , err  :=  common .ParseVPCResourcePath (* vpcSubnets [i ].Path )
428469		if  err  !=  nil  {
@@ -432,7 +473,7 @@ func (service *SubnetService) UpdateSubnetSetTags(ns string, vpcSubnets []*model
432473		if  _ , err  :=  service .createOrUpdateSubnet (subnetSet , vpcSubnets [i ], & vpcInfo ); err  !=  nil  {
433474			return  fmt .Errorf ("failed to update Subnet %s in SubnetSet %s: %w" , * vpcSubnet .Id , subnetSet .Name , err )
434475		}
435- 		log .Info ("Successfully updated SubnetSet tags " , "subnetSet" , subnetSet , "Subnet" , * vpcSubnet .Id )
476+ 		log .Info ("Successfully updated SubnetSet" , "subnetSet" , subnetSet , "Subnet" , * vpcSubnet .Id )
436477	}
437478	return  nil 
438479}
0 commit comments