@@ -44,6 +44,8 @@ import (
44
44
"github.com/IBM/vpc-go-sdk/vpcv1"
45
45
46
46
corev1 "k8s.io/api/core/v1"
47
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
48
+ "k8s.io/apimachinery/pkg/labels"
47
49
"k8s.io/apimachinery/pkg/types"
48
50
"k8s.io/apimachinery/pkg/util/intstr"
49
51
"k8s.io/client-go/tools/cache"
@@ -996,7 +998,45 @@ func (m *PowerVSMachineScope) CreateVPCLoadBalancerPoolMember(ctx context.Contex
996
998
997
999
internalIP := m .GetMachineInternalIP ()
998
1000
1001
+ // lbAdditionalListeners is a mapping of additionalListener's port-protocol to the additionalListener as defined in the specification
1002
+ // It will be used later to get the default pool associated with the listener
1003
+ lbAdditionalListeners := map [string ]infrav1beta2.AdditionalListenerSpec {}
1004
+ for _ , additionalListener := range lb .AdditionalListeners {
1005
+ if additionalListener .Protocol == nil {
1006
+ additionalListener .Protocol = & infrav1beta2 .VPCLoadBalancerListenerProtocolTCP
1007
+ }
1008
+ lbAdditionalListeners [fmt .Sprintf ("%d-%s" , additionalListener .Port , * additionalListener .Protocol )] = additionalListener
1009
+ }
1010
+
1011
+ // loadBalancerListeners is a mapping of the loadBalancer listener's defaultPoolName to the additionalListener
1012
+ // as the default pool name might be empty in spec and should be fetched from the cloud's listener
1013
+ loadBalancerListeners := map [string ]infrav1beta2.AdditionalListenerSpec {}
1014
+ for _ , listener := range loadBalancer .Listeners {
1015
+ listenerOptions := & vpcv1.GetLoadBalancerListenerOptions {}
1016
+ listenerOptions .SetLoadBalancerID (* loadBalancer .ID )
1017
+ listenerOptions .SetID (* listener .ID )
1018
+ loadBalancerListener , _ , err := m .IBMVPCClient .GetLoadBalancerListener (listenerOptions )
1019
+ if err != nil {
1020
+ return nil , fmt .Errorf ("failed to list %s load balancer listener: %w" , * listener .ID , err )
1021
+ }
1022
+ if additionalListener , ok := lbAdditionalListeners [fmt .Sprintf ("%d-%s" , * loadBalancerListener .Port , * loadBalancerListener .Protocol )]; ok {
1023
+ if loadBalancerListener .DefaultPool != nil {
1024
+ loadBalancerListeners [* loadBalancerListener .DefaultPool .Name ] = additionalListener
1025
+ }
1026
+ } else if loadBalancerListener .Port != nil && * loadBalancerListener .Port == int64 (6443 ) {
1027
+ // add default pool 6443 to all control plane machines
1028
+ log .V (3 ).Info ("loadbalancerlisteners port match" , "port" , loadBalancerListener .Port )
1029
+
1030
+ protocol := infrav1beta2 .VPCLoadBalancerListenerProtocol (* loadBalancerListener .Protocol )
1031
+ listener := infrav1beta2.AdditionalListenerSpec {
1032
+ Port : * loadBalancerListener .Port ,
1033
+ Protocol : & protocol ,
1034
+ }
1035
+ loadBalancerListeners [* loadBalancerListener .DefaultPool .Name ] = listener
1036
+ }
1037
+ }
999
1038
// Update each LoadBalancer pool
1039
+ // For each pool, get the additionalListener associated with the pool from the loadBalancerListeners map.
1000
1040
for _ , pool := range loadBalancer .Pools {
1001
1041
log .V (3 ).Info ("Updating LoadBalancer pool member" , "pool" , * pool .Name , "loadBalancerName" , * loadBalancer .Name , "IP" , internalIP )
1002
1042
listOptions := & vpcv1.ListLoadBalancerPoolMembersOptions {}
@@ -1009,32 +1049,35 @@ func (m *PowerVSMachineScope) CreateVPCLoadBalancerPoolMember(ctx context.Contex
1009
1049
var targetPort int64
1010
1050
var alreadyRegistered bool
1011
1051
1012
- if len (listLoadBalancerPoolMembers .Members ) == 0 {
1013
- // For adding the first member to the pool we depend on the pool name to get the target port
1014
- // pool name will have port number appended at the end
1015
- lbNameSplit := strings .Split (* pool .Name , "-" )
1016
- if len (lbNameSplit ) == 0 {
1017
- // user might have created additional pool
1018
- log .V (3 ).Info ("Not updating pool as it might be created externally" , "poolName" , * pool .Name )
1052
+ if loadBalancerListener , ok := loadBalancerListeners [* pool .Name ]; ok {
1053
+ targetPort = loadBalancerListener .Port
1054
+ log .V (3 ).Info ("Checking if machine label matches with the label selector in listener" , "machine label" , m .IBMPowerVSMachine .Labels , "label selector" , loadBalancerListener .Selector )
1055
+ selector , err := metav1 .LabelSelectorAsSelector (& loadBalancerListener .Selector )
1056
+ if err != nil {
1057
+ log .V (5 ).Error (err , "Skipping listener addition, failed to get label selector from spec selector" )
1019
1058
continue
1020
1059
}
1021
- targetPort , err = strconv .ParseInt (lbNameSplit [len (lbNameSplit )- 1 ], 10 , 64 )
1022
- if err != nil {
1023
- // user might have created additional pool
1024
- log .Error (err , "unable to fetch target port from pool name" , "poolName" , * pool .Name )
1060
+
1061
+ if selector .Empty () && ! util .IsControlPlaneMachine (m .Machine ) {
1062
+ log .V (3 ).Info ("Skipping listener addition as the selector is empty and not a control plane machine" )
1063
+ continue
1064
+ }
1065
+ // Skip adding the listener if the selector does not match
1066
+ if ! selector .Empty () && ! selector .Matches (labels .Set (m .IBMPowerVSMachine .Labels )) {
1067
+ log .V (3 ).Info ("Skip adding listener, machine label doesn't match with the listener label selector" , "pool" , * pool .Name , "IP" , internalIP )
1025
1068
continue
1026
1069
}
1027
- } else {
1028
- for _ , member := range listLoadBalancerPoolMembers .Members {
1029
- if target , ok := member .Target .(* vpcv1.LoadBalancerPoolMemberTarget ); ok {
1030
- targetPort = * member .Port
1031
- if * target .Address == internalIP {
1032
- alreadyRegistered = true
1033
- log .V (3 ).Info ("Target IP already configured for pool" , "IP" , internalIP , "poolName" , * pool .Name )
1034
- }
1070
+ }
1071
+
1072
+ for _ , member := range listLoadBalancerPoolMembers .Members {
1073
+ if target , ok := member .Target .(* vpcv1.LoadBalancerPoolMemberTarget ); ok {
1074
+ if * target .Address == internalIP {
1075
+ alreadyRegistered = true
1076
+ log .V (3 ).Info ("Target IP already configured for pool" , "IP" , internalIP , "poolName" , * pool .Name )
1035
1077
}
1036
1078
}
1037
1079
}
1080
+
1038
1081
if alreadyRegistered {
1039
1082
log .V (3 ).Info ("PoolMember already exist" , "poolName" , * pool .Name , "IP" , internalIP , "targetPort" , targetPort )
1040
1083
continue
0 commit comments