@@ -100,6 +100,12 @@ const (
100100 // See https://nip.io
101101 defaultProxyHostnameSuffix = "nip.io"
102102 ServiceAnnotationLoadBalancerID = "loadbalancer.openstack.org/load-balancer-id"
103+
104+ // Octavia resources name formats
105+ lbFormat = "%s%s_%s_%s"
106+ listenerFormat = "listener_%d_%s"
107+ poolFormat = "pool_%d_%s"
108+ monitorFormat = "monitor_%d_%s"
103109)
104110
105111// LbaasV2 is a LoadBalancer implementation based on Octavia
@@ -501,20 +507,17 @@ func (lbaas *LbaasV2) createOctaviaLoadBalancer(name, clusterName string, servic
501507
502508 if ! lbaas .opts .ProviderRequiresSerialAPICalls {
503509 for portIndex , port := range service .Spec .Ports {
504- listenerCreateOpt := lbaas .buildListenerCreateOpt (port , svcConf )
505- listenerCreateOpt .Name = cpoutil .CutString255 (fmt .Sprintf ("listener_%d_%s" , portIndex , name ))
510+ listenerCreateOpt := lbaas .buildListenerCreateOpt (port , svcConf , cpoutil .Sprintf255 (listenerFormat , portIndex , name ))
506511 members , newMembers , err := lbaas .buildBatchUpdateMemberOpts (port , nodes , svcConf )
507512 if err != nil {
508513 return nil , err
509514 }
510- poolCreateOpt := lbaas .buildPoolCreateOpt (string (listenerCreateOpt .Protocol ), service , svcConf )
515+ poolCreateOpt := lbaas .buildPoolCreateOpt (string (listenerCreateOpt .Protocol ), service , svcConf , cpoutil . Sprintf255 ( poolFormat , portIndex , name ) )
511516 poolCreateOpt .Members = members
512517 // Pool name must be provided to create fully populated loadbalancer
513- poolCreateOpt .Name = cpoutil .CutString255 (fmt .Sprintf ("pool_%d_%s" , portIndex , name ))
514518 var withHealthMonitor string
515519 if svcConf .enableMonitor {
516- opts := lbaas .buildMonitorCreateOpts (svcConf , port )
517- opts .Name = cpoutil .CutString255 (fmt .Sprintf ("monitor_%d_%s" , port .Port , name ))
520+ opts := lbaas .buildMonitorCreateOpts (svcConf , port , cpoutil .Sprintf255 (monitorFormat , portIndex , name ))
518521 poolCreateOpt .Monitor = & opts
519522 withHealthMonitor = " with healthmonitor"
520523 }
@@ -586,8 +589,7 @@ func (lbaas *LbaasV2) GetLoadBalancer(ctx context.Context, clusterName string, s
586589
587590// GetLoadBalancerName returns the constructed load balancer name.
588591func (lbaas * LbaasV2 ) GetLoadBalancerName (_ context.Context , clusterName string , service * corev1.Service ) string {
589- name := fmt .Sprintf ("%s%s_%s_%s" , servicePrefix , clusterName , service .Namespace , service .Name )
590- return cpoutil .CutString255 (name )
592+ return cpoutil .Sprintf255 (lbFormat , servicePrefix , clusterName , service .Namespace , service .Name )
591593}
592594
593595// getLoadBalancerLegacyName returns the legacy load balancer name for backward compatibility.
@@ -1039,55 +1041,56 @@ func (lbaas *LbaasV2) ensureFloatingIP(clusterName string, service *corev1.Servi
10391041func (lbaas * LbaasV2 ) ensureOctaviaHealthMonitor (lbID string , name string , pool * v2pools.Pool , port corev1.ServicePort , svcConf * serviceConfig ) error {
10401042 monitorID := pool .MonitorID
10411043
1042- if monitorID != "" {
1043- monitor , err := openstackutil .GetHealthMonitor (lbaas .lb , monitorID )
1044- if err != nil {
1045- return err
1046- }
1047- //Recreate health monitor with correct protocol if externalTrafficPolicy was changed
1048- createOpts := lbaas .buildMonitorCreateOpts (svcConf , port )
1049- if createOpts .Type != monitor .Type {
1050- klog .InfoS ("Recreating health monitor for the pool" , "pool" , pool .ID , "oldMonitor" , monitorID )
1051- if err := openstackutil .DeleteHealthMonitor (lbaas .lb , monitorID , lbID ); err != nil {
1052- return err
1053- }
1054- monitorID = ""
1055- }
1056- if svcConf .healthMonitorDelay != monitor .Delay ||
1057- svcConf .healthMonitorTimeout != monitor .Timeout ||
1058- svcConf .healthMonitorMaxRetries != monitor .MaxRetries ||
1059- svcConf .healthMonitorMaxRetriesDown != monitor .MaxRetriesDown {
1060- updateOpts := v2monitors.UpdateOpts {
1061- Delay : svcConf .healthMonitorDelay ,
1062- Timeout : svcConf .healthMonitorTimeout ,
1063- MaxRetries : svcConf .healthMonitorMaxRetries ,
1064- MaxRetriesDown : svcConf .healthMonitorMaxRetriesDown ,
1065- }
1066- klog .Infof ("Updating health monitor %s updateOpts %+v" , monitorID , updateOpts )
1067- if err := openstackutil .UpdateHealthMonitor (lbaas .lb , monitorID , updateOpts , lbID ); err != nil {
1068- return err
1069- }
1044+ if monitorID == "" {
1045+ // do nothing
1046+ if ! svcConf .enableMonitor {
1047+ return nil
10701048 }
1071- }
1072- if monitorID == "" && svcConf . enableMonitor {
1049+
1050+ // a new monitor must be created
10731051 klog .V (2 ).Infof ("Creating monitor for pool %s" , pool .ID )
1052+ createOpts := lbaas .buildMonitorCreateOpts (svcConf , port , name )
1053+ return lbaas .createOctaviaHealthMonitor (createOpts , pool .ID , lbID )
1054+ }
10741055
1075- createOpts := lbaas .buildMonitorCreateOpts (svcConf , port )
1076- // Populate PoolID, attribute is omitted for consumption of the createOpts for fully populated Loadbalancer
1077- createOpts .PoolID = pool .ID
1078- createOpts .Name = name
1079- monitor , err := openstackutil .CreateHealthMonitor (lbaas .lb , createOpts , lbID )
1080- if err != nil {
1081- return err
1082- }
1083- monitorID = monitor .ID
1084- klog .Infof ("Health monitor %s for pool %s created." , monitorID , pool .ID )
1085- } else if monitorID != "" && ! svcConf .enableMonitor {
1056+ // an existing monitor must be deleted
1057+ if ! svcConf .enableMonitor {
10861058 klog .Infof ("Deleting health monitor %s for pool %s" , monitorID , pool .ID )
1059+ return openstackutil .DeleteHealthMonitor (lbaas .lb , monitorID , lbID )
1060+ }
10871061
1062+ // get an existing monitor status
1063+ monitor , err := openstackutil .GetHealthMonitor (lbaas .lb , monitorID )
1064+ if err != nil {
1065+ // return err on 404 is ok, since we get monitorID dynamically from the pool
1066+ return err
1067+ }
1068+
1069+ // recreate health monitor with a new type
1070+ createOpts := lbaas .buildMonitorCreateOpts (svcConf , port , name )
1071+ if createOpts .Type != monitor .Type {
1072+ klog .InfoS ("Recreating health monitor for the pool" , "pool" , pool .ID , "oldMonitor" , monitorID )
10881073 if err := openstackutil .DeleteHealthMonitor (lbaas .lb , monitorID , lbID ); err != nil {
10891074 return err
10901075 }
1076+ return lbaas .createOctaviaHealthMonitor (createOpts , pool .ID , lbID )
1077+ }
1078+
1079+ // update new monitor parameters
1080+ if name != monitor .Name ||
1081+ svcConf .healthMonitorDelay != monitor .Delay ||
1082+ svcConf .healthMonitorTimeout != monitor .Timeout ||
1083+ svcConf .healthMonitorMaxRetries != monitor .MaxRetries ||
1084+ svcConf .healthMonitorMaxRetriesDown != monitor .MaxRetriesDown {
1085+ updateOpts := v2monitors.UpdateOpts {
1086+ Name : & name ,
1087+ Delay : svcConf .healthMonitorDelay ,
1088+ Timeout : svcConf .healthMonitorTimeout ,
1089+ MaxRetries : svcConf .healthMonitorMaxRetries ,
1090+ MaxRetriesDown : svcConf .healthMonitorMaxRetriesDown ,
1091+ }
1092+ klog .Infof ("Updating health monitor %s updateOpts %+v" , monitorID , updateOpts )
1093+ return openstackutil .UpdateHealthMonitor (lbaas .lb , monitorID , updateOpts , lbID )
10911094 }
10921095
10931096 return nil
@@ -1097,7 +1100,9 @@ func (lbaas *LbaasV2) canUseHTTPMonitor(port corev1.ServicePort) bool {
10971100 if lbaas .opts .LBProvider == "ovn" {
10981101 // ovn-octavia-provider doesn't support HTTP monitors at all. We got to avoid creating it with ovn.
10991102 return false
1100- } else if port .Protocol == corev1 .ProtocolUDP {
1103+ }
1104+
1105+ if port .Protocol == corev1 .ProtocolUDP {
11011106 // Older Octavia versions or OVN provider doesn't support HTTP monitors on UDP pools. We got to check if that's the case.
11021107 return openstackutil .IsOctaviaFeatureSupported (lbaas .lb , openstackutil .OctaviaFeatureHTTPMonitorsOnUDP , lbaas .opts .LBProvider )
11031108 }
@@ -1106,8 +1111,9 @@ func (lbaas *LbaasV2) canUseHTTPMonitor(port corev1.ServicePort) bool {
11061111}
11071112
11081113// buildMonitorCreateOpts returns a v2monitors.CreateOpts without PoolID for consumption of both, fully popuplated Loadbalancers and Monitors.
1109- func (lbaas * LbaasV2 ) buildMonitorCreateOpts (svcConf * serviceConfig , port corev1.ServicePort ) v2monitors.CreateOpts {
1114+ func (lbaas * LbaasV2 ) buildMonitorCreateOpts (svcConf * serviceConfig , port corev1.ServicePort , name string ) v2monitors.CreateOpts {
11101115 opts := v2monitors.CreateOpts {
1116+ Name : name ,
11111117 Type : string (port .Protocol ),
11121118 Delay : svcConf .healthMonitorDelay ,
11131119 Timeout : svcConf .healthMonitorTimeout ,
@@ -1126,6 +1132,18 @@ func (lbaas *LbaasV2) buildMonitorCreateOpts(svcConf *serviceConfig, port corev1
11261132 return opts
11271133}
11281134
1135+ func (lbaas * LbaasV2 ) createOctaviaHealthMonitor (createOpts v2monitors.CreateOpts , poolID , lbID string ) error {
1136+ // populate PoolID, attribute is omitted for consumption of the createOpts for fully populated Loadbalancer
1137+ createOpts .PoolID = poolID
1138+ monitor , err := openstackutil .CreateHealthMonitor (lbaas .lb , createOpts , lbID )
1139+ if err != nil {
1140+ return err
1141+ }
1142+ klog .Infof ("Health monitor %s for pool %s created." , monitor .ID , poolID )
1143+
1144+ return nil
1145+ }
1146+
11291147// Make sure the pool is created for the Service, nodes are added as pool members.
11301148func (lbaas * LbaasV2 ) ensureOctaviaPool (lbID string , name string , listener * listeners.Listener , service * corev1.Service , port corev1.ServicePort , nodes []* corev1.Node , svcConf * serviceConfig ) (* v2pools.Pool , error ) {
11311149 pool , err := openstackutil .GetPoolByListener (lbaas .lb , lbID , listener .ID )
@@ -1153,9 +1171,8 @@ func (lbaas *LbaasV2) ensureOctaviaPool(lbID string, name string, listener *list
11531171 }
11541172
11551173 if pool == nil {
1156- createOpt := lbaas .buildPoolCreateOpt (listener .Protocol , service , svcConf )
1174+ createOpt := lbaas .buildPoolCreateOpt (listener .Protocol , service , svcConf , name )
11571175 createOpt .ListenerID = listener .ID
1158- createOpt .Name = name
11591176
11601177 klog .InfoS ("Creating pool" , "listenerID" , listener .ID , "protocol" , createOpt .Protocol )
11611178 pool , err = openstackutil .CreatePool (lbaas .lb , createOpt , lbID )
@@ -1200,7 +1217,7 @@ func (lbaas *LbaasV2) ensureOctaviaPool(lbID string, name string, listener *list
12001217 return pool , nil
12011218}
12021219
1203- func (lbaas * LbaasV2 ) buildPoolCreateOpt (listenerProtocol string , service * corev1.Service , svcConf * serviceConfig ) v2pools.CreateOpts {
1220+ func (lbaas * LbaasV2 ) buildPoolCreateOpt (listenerProtocol string , service * corev1.Service , svcConf * serviceConfig , name string ) v2pools.CreateOpts {
12041221 // By default, use the protocol of the listener
12051222 poolProto := v2pools .Protocol (listenerProtocol )
12061223 if svcConf .enableProxyProtocol {
@@ -1227,6 +1244,7 @@ func (lbaas *LbaasV2) buildPoolCreateOpt(listenerProtocol string, service *corev
12271244
12281245 lbmethod := v2pools .LBMethod (lbaas .opts .LBMethod )
12291246 return v2pools.CreateOpts {
1247+ Name : name ,
12301248 Protocol : poolProto ,
12311249 LBMethod : lbmethod ,
12321250 Persistence : persistence ,
@@ -1279,9 +1297,8 @@ func (lbaas *LbaasV2) ensureOctaviaListener(lbID string, name string, curListene
12791297 Port : int (port .Port ),
12801298 }]
12811299 if ! isPresent {
1282- listenerCreateOpt := lbaas .buildListenerCreateOpt (port , svcConf )
1300+ listenerCreateOpt := lbaas .buildListenerCreateOpt (port , svcConf , name )
12831301 listenerCreateOpt .LoadbalancerID = lbID
1284- listenerCreateOpt .Name = name
12851302
12861303 klog .V (2 ).Infof ("Creating listener for port %d using protocol %s" , int (port .Port ), listenerCreateOpt .Protocol )
12871304
@@ -1366,11 +1383,10 @@ func (lbaas *LbaasV2) ensureOctaviaListener(lbID string, name string, curListene
13661383}
13671384
13681385// buildListenerCreateOpt returns listeners.CreateOpts for a specific Service port and configuration
1369- func (lbaas * LbaasV2 ) buildListenerCreateOpt (port corev1.ServicePort , svcConf * serviceConfig ) listeners.CreateOpts {
1370- listenerProtocol := listeners .Protocol (port .Protocol )
1371-
1386+ func (lbaas * LbaasV2 ) buildListenerCreateOpt (port corev1.ServicePort , svcConf * serviceConfig , name string ) listeners.CreateOpts {
13721387 listenerCreateOpt := listeners.CreateOpts {
1373- Protocol : listenerProtocol ,
1388+ Name : name ,
1389+ Protocol : listeners .Protocol (port .Protocol ),
13741390 ProtocolPort : int (port .Port ),
13751391 ConnLimit : & svcConf .connLimit ,
13761392 }
@@ -1970,17 +1986,17 @@ func (lbaas *LbaasV2) ensureOctaviaLoadBalancer(ctx context.Context, clusterName
19701986 }
19711987
19721988 for portIndex , port := range service .Spec .Ports {
1973- listener , err := lbaas .ensureOctaviaListener (loadbalancer .ID , cpoutil .CutString255 ( fmt . Sprintf ( "listener_%d_%s" , portIndex , lbName ) ), curListenerMapping , port , svcConf , service )
1989+ listener , err := lbaas .ensureOctaviaListener (loadbalancer .ID , cpoutil .Sprintf255 ( listenerFormat , portIndex , lbName ), curListenerMapping , port , svcConf , service )
19741990 if err != nil {
19751991 return nil , err
19761992 }
19771993
1978- pool , err := lbaas .ensureOctaviaPool (loadbalancer .ID , cpoutil .CutString255 ( fmt . Sprintf ( "pool_%d_%s" , portIndex , lbName ) ), listener , service , port , nodes , svcConf )
1994+ pool , err := lbaas .ensureOctaviaPool (loadbalancer .ID , cpoutil .Sprintf255 ( poolFormat , portIndex , lbName ), listener , service , port , nodes , svcConf )
19791995 if err != nil {
19801996 return nil , err
19811997 }
19821998
1983- if err := lbaas .ensureOctaviaHealthMonitor (loadbalancer .ID , cpoutil .CutString255 ( fmt . Sprintf ( "monitor_%d_%s" , portIndex , lbName ) ), pool , port , svcConf ); err != nil {
1999+ if err := lbaas .ensureOctaviaHealthMonitor (loadbalancer .ID , cpoutil .Sprintf255 ( monitorFormat , portIndex , lbName ), pool , port , svcConf ); err != nil {
19842000 return nil , err
19852001 }
19862002
@@ -2138,7 +2154,12 @@ func (lbaas *LbaasV2) updateOctaviaLoadBalancer(ctx context.Context, clusterName
21382154 return fmt .Errorf ("loadbalancer %s does not contain required listener for port %d and protocol %s" , loadbalancer .ID , port .Port , port .Protocol )
21392155 }
21402156
2141- _ , err := lbaas .ensureOctaviaPool (loadbalancer .ID , cpoutil .CutString255 (fmt .Sprintf ("pool_%d_%s" , portIndex , loadbalancer .Name )), & listener , service , port , nodes , svcConf )
2157+ pool , err := lbaas .ensureOctaviaPool (loadbalancer .ID , cpoutil .Sprintf255 (poolFormat , portIndex , loadbalancer .Name ), & listener , service , port , nodes , svcConf )
2158+ if err != nil {
2159+ return err
2160+ }
2161+
2162+ err = lbaas .ensureOctaviaHealthMonitor (loadbalancer .ID , cpoutil .Sprintf255 (monitorFormat , portIndex , loadbalancer .Name ), pool , port , svcConf )
21422163 if err != nil {
21432164 return err
21442165 }
0 commit comments