@@ -32,6 +32,8 @@ import (
32
32
"github.com/gophercloud/gophercloud/v2/openstack"
33
33
"github.com/gophercloud/gophercloud/v2/openstack/blockstorage/v3/volumes"
34
34
"github.com/gophercloud/gophercloud/v2/openstack/compute/v2/servers"
35
+ "github.com/gophercloud/gophercloud/v2/openstack/loadbalancer/v2/loadbalancers"
36
+ "github.com/gophercloud/gophercloud/v2/openstack/loadbalancer/v2/monitors"
35
37
"github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/layer3/routers"
36
38
"github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/security/groups"
37
39
"github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/trunks"
@@ -1029,6 +1031,128 @@ var _ = Describe("e2e tests [PR-Blocking]", func() {
1029
1031
), "OpenStackMachine should be marked not ready with InstanceDeletedReason" )
1030
1032
})
1031
1033
})
1034
+
1035
+ Describe ("Workload cluster (health monitor)" , func () {
1036
+ It ("should configure load balancer health monitor with custom settings" , func (ctx context.Context ) {
1037
+ shared .Logf ("Creating a cluster with custom health monitor configuration" )
1038
+ clusterName := fmt .Sprintf ("cluster-%s" , namespace .Name )
1039
+ configCluster := defaultConfigCluster (clusterName , namespace .Name )
1040
+ configCluster .ControlPlaneMachineCount = ptr .To (int64 (1 ))
1041
+ configCluster .WorkerMachineCount = ptr .To (int64 (1 ))
1042
+ configCluster .Flavor = shared .FlavorHealthMonitor
1043
+ createCluster (ctx , configCluster , clusterResources )
1044
+
1045
+ openStackCluster , err := shared .ClusterForSpec (ctx , e2eCtx , namespace )
1046
+ Expect (err ).NotTo (HaveOccurred ())
1047
+
1048
+ Expect (openStackCluster .Spec .APIServerLoadBalancer ).ToNot (BeNil ())
1049
+ Expect (openStackCluster .Spec .APIServerLoadBalancer .Monitor ).ToNot (BeNil ())
1050
+ Expect (openStackCluster .Spec .APIServerLoadBalancer .Monitor .Delay ).ToNot (BeNil ())
1051
+ Expect (openStackCluster .Spec .APIServerLoadBalancer .Monitor .Delay ).To (Equal (15 ))
1052
+ Expect (openStackCluster .Spec .APIServerLoadBalancer .Monitor .Timeout ).ToNot (BeNil ())
1053
+ Expect (openStackCluster .Spec .APIServerLoadBalancer .Monitor .Timeout ).To (Equal (10 ))
1054
+ Expect (openStackCluster .Spec .APIServerLoadBalancer .Monitor .MaxRetries ).ToNot (BeNil ())
1055
+ Expect (openStackCluster .Spec .APIServerLoadBalancer .Monitor .MaxRetries ).To (Equal (3 ))
1056
+ Expect (openStackCluster .Spec .APIServerLoadBalancer .Monitor .MaxRetriesDown ).ToNot (BeNil ())
1057
+ Expect (openStackCluster .Spec .APIServerLoadBalancer .Monitor .MaxRetriesDown ).To (Equal (2 ))
1058
+
1059
+ shared .Logf ("Looking for load balancer for cluster %s" , clusterName )
1060
+ expectedLBName := fmt .Sprintf ("k8s-clusterapi-cluster-%s-%s-kubeapi" , namespace .Name , clusterName )
1061
+ loadBalancers , err := shared .DumpOpenStackLoadBalancers (e2eCtx , loadbalancers.ListOpts {
1062
+ Name : expectedLBName ,
1063
+ })
1064
+ Expect (err ).NotTo (HaveOccurred ())
1065
+
1066
+ if len (loadBalancers ) == 0 {
1067
+ shared .Logf ("Load balancer not found by name, trying by tags" )
1068
+ loadBalancers , err = shared .DumpOpenStackLoadBalancers (e2eCtx , loadbalancers.ListOpts {
1069
+ Tags : []string {clusterName },
1070
+ })
1071
+ Expect (err ).NotTo (HaveOccurred ())
1072
+ }
1073
+ Expect (loadBalancers ).ToNot (BeEmpty (), "Load balancer should exist for cluster" )
1074
+
1075
+ loadBalancer := loadBalancers [0 ]
1076
+ shared .Logf ("Found load balancer %s with ID %s" , loadBalancer .Name , loadBalancer .ID )
1077
+
1078
+ shared .Logf ("Looking for health monitors for load balancer %s" , loadBalancer .ID )
1079
+ monitorList , err := shared .DumpOpenStackLoadBalancerMonitors (e2eCtx , monitors.ListOpts {})
1080
+ Expect (err ).NotTo (HaveOccurred ())
1081
+
1082
+ expectedMonitorName := fmt .Sprintf ("%s-6443" , loadBalancer .Name )
1083
+
1084
+ var clusterMonitor * monitors.Monitor
1085
+ for i := range monitorList {
1086
+ monitor := & monitorList [i ]
1087
+ if monitor .Name == expectedMonitorName || strings .Contains (monitor .Name , loadBalancer .Name ) {
1088
+ clusterMonitor = monitor
1089
+ break
1090
+ }
1091
+ }
1092
+ Expect (clusterMonitor ).ToNot (BeNil (), "Health monitor should exist for the cluster load balancer" )
1093
+
1094
+ shared .Logf ("Found health monitor %s with ID %s" , clusterMonitor .Name , clusterMonitor .ID )
1095
+
1096
+ Expect (clusterMonitor .Delay ).To (Equal (15 ), "Monitor delay should match configured value" )
1097
+ Expect (clusterMonitor .Timeout ).To (Equal (10 ), "Monitor timeout should match configured value" )
1098
+ Expect (clusterMonitor .MaxRetries ).To (Equal (3 ), "Monitor maxRetries should match configured value" )
1099
+ Expect (clusterMonitor .MaxRetriesDown ).To (Equal (2 ), "Monitor maxRetriesDown should match configured value" )
1100
+ Expect (clusterMonitor .Type ).To (Equal ("TCP" ), "Monitor should be TCP type" )
1101
+
1102
+ shared .Logf ("Testing health monitor configuration update" )
1103
+ openStackCluster , err = shared .ClusterForSpec (ctx , e2eCtx , namespace )
1104
+ Expect (err ).NotTo (HaveOccurred ())
1105
+
1106
+ updatedCluster := openStackCluster .DeepCopy ()
1107
+ updatedCluster .Spec .APIServerLoadBalancer .Monitor .Delay = 20
1108
+ updatedCluster .Spec .APIServerLoadBalancer .Monitor .MaxRetries = 4
1109
+
1110
+ Expect (e2eCtx .Environment .BootstrapClusterProxy .GetClient ().Update (ctx , updatedCluster )).To (Succeed ())
1111
+
1112
+ Eventually (func () (bool , error ) {
1113
+ updatedMonitor , err := shared .GetOpenStackLoadBalancerMonitor (e2eCtx , clusterMonitor .ID )
1114
+ if err != nil {
1115
+ return false , err
1116
+ }
1117
+ return updatedMonitor .Delay == 20 && updatedMonitor .MaxRetries == 4 , nil
1118
+ }, e2eCtx .E2EConfig .GetIntervals (specName , "wait-cluster" )... ).Should (BeTrue (), "Monitor should be updated with new configuration" )
1119
+
1120
+ finalMonitor , err := shared .GetOpenStackLoadBalancerMonitor (e2eCtx , clusterMonitor .ID )
1121
+ Expect (err ).NotTo (HaveOccurred ())
1122
+ Expect (finalMonitor .Delay ).To (Equal (20 ), "Monitor delay should be updated" )
1123
+ Expect (finalMonitor .MaxRetries ).To (Equal (4 ), "Monitor maxRetries should be updated" )
1124
+ Expect (finalMonitor .Timeout ).To (Equal (10 ), "Monitor timeout should remain unchanged" )
1125
+ Expect (finalMonitor .MaxRetriesDown ).To (Equal (2 ), "Monitor maxRetriesDown should remain unchanged" )
1126
+
1127
+ shared .Logf ("Testing monitor configuration removal and default value reversion" )
1128
+ openStackCluster , err = shared .ClusterForSpec (ctx , e2eCtx , namespace )
1129
+ Expect (err ).NotTo (HaveOccurred ())
1130
+
1131
+ clusterWithRemovedMonitor := openStackCluster .DeepCopy ()
1132
+ clusterWithRemovedMonitor .Spec .APIServerLoadBalancer .Monitor = nil
1133
+ if clusterWithRemovedMonitor .Annotations == nil {
1134
+ clusterWithRemovedMonitor .Annotations = make (map [string ]string )
1135
+ }
1136
+ clusterWithRemovedMonitor .Annotations ["test.e2e/monitor-update" ] = fmt .Sprintf ("%d" , time .Now ().Unix ())
1137
+ Expect (e2eCtx .Environment .BootstrapClusterProxy .GetClient ().Update (ctx , clusterWithRemovedMonitor )).To (Succeed ())
1138
+
1139
+ Eventually (func () (bool , error ) {
1140
+ revertedMonitor , err := shared .GetOpenStackLoadBalancerMonitor (e2eCtx , clusterMonitor .ID )
1141
+ if err != nil {
1142
+ return false , err
1143
+ }
1144
+ return revertedMonitor .Delay == 10 && revertedMonitor .Timeout == 5 &&
1145
+ revertedMonitor .MaxRetries == 5 && revertedMonitor .MaxRetriesDown == 3 , nil
1146
+ }, e2eCtx .E2EConfig .GetIntervals (specName , "wait-cluster" )... ).Should (BeTrue (), "Monitor should revert to all default values when configuration is removed" )
1147
+
1148
+ revertedMonitor , err := shared .GetOpenStackLoadBalancerMonitor (e2eCtx , clusterMonitor .ID )
1149
+ Expect (err ).NotTo (HaveOccurred ())
1150
+ Expect (revertedMonitor .Delay ).To (Equal (10 ), "Monitor delay should revert to default value (10)" )
1151
+ Expect (revertedMonitor .Timeout ).To (Equal (5 ), "Monitor timeout should revert to default value (5)" )
1152
+ Expect (revertedMonitor .MaxRetries ).To (Equal (5 ), "Monitor maxRetries should revert to default value (5)" )
1153
+ Expect (revertedMonitor .MaxRetriesDown ).To (Equal (3 ), "Monitor maxRetriesDown should revert to default value (3)" )
1154
+ })
1155
+ })
1032
1156
})
1033
1157
1034
1158
func defaultConfigCluster (clusterName , namespace string ) clusterctl.ConfigClusterInput {
0 commit comments