Skip to content

Commit 41b8998

Browse files
chideatclaudeCopilot
authored
Enhanced Stability, Pause Logic, and Sentinel Improvements (#59)
* fix: correct IsPodAnnotationDiff function name in RDS controllers - Update function call from IsPodAnnonationDiff to IsPodAnnotationDiff - Maintain all other resource cleanup and finalizer functionality * refactor: major service comparison and actor improvements - Add comprehensive IsServiceChanged function for detailed service comparison - Refactor actor ensure resource ordering and method names - Improve service change detection with proper label/annotation comparison - Enhance statefulset handling with better error checking - Add utility functions for service port and spec comparison * fix: try meed failed cluster nodes * feat: Refactor annotation merging for restart annotation Refactored the annotation merging logic to specifically handle the `RestartAnnotationKey`. - Introduced `MergeRestartAnnotation` to compare and merge restart annotations based on timestamps. - Replaced the generic `MergeAnnotations` function with the new specialized function. - Ensured that the restart annotation is correctly propagated during updates. * feat: set pause status after all pods deleted * feat: Improve pause logic and increase sentinel startup probe delay - Modified the pause logic in the cluster, failover, and sentinel controllers to requeue the resource if nodes still exist, allowing them to scale down gracefully. The operator will now pause reconciliation only after all pods have been terminated. - Increased the initial delay for the sentinel startup probe to 30 seconds to prevent premature failures on slower systems. * fix: clean dumplicate resource settings * fix: fix bug of config update when do redis version update * fix: added support of force failover to force the sentinel refresh the nodes announce * Update helper commands and initialization scripts - Modified cluster, failover, and sentinel command implementations - Updated initialization scripts for different deployment modes - Improved helper functionality across command modules 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Seer <kvcnow@gmail.com> * chore: update release pipeline and dependencies * fake: add unit tests for sentinel statefulset builder and service client * test: add unit tests for IsStatefulsetChanged2, IsServiceChanged, failover/sentinel actors, and e2e local run infra - internal/util/kubernetes_test.go: add table-driven tests for IsStatefulsetChanged2 (changed/immutableChanged booleans) and IsServiceChanged (port, annotation, label, selector, type diffs) - internal/ops/failover/actor/actor_update_config_test.go: new file with mockFailoverInstance and tests for ConfigMap-not-found, config-unchanged, hot-config-changed, and restart-required-changed paths - internal/ops/failover/actor/actor_ensure_resource_test.go: new file testing pause logic (all-pods-deleted → Pause, pods-exist → Requeue, STS scale-down) - internal/ops/sentinel/actor/actor_ensure_resource_test.go: mirrors failover pause tests for the sentinel actor path - Makefile: add kind-setup, kind-load, and test-e2e-local targets - config/kind/kind-config.yaml: Kind cluster config exposing NodePorts 30000-30030 for e2e test instances Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: update envtest to use GitHub releases instead of deprecated GCS GCS (storage.googleapis.com) now returns 401 Unauthorized for kubebuilder tools downloads, breaking CI. Switch to the GitHub-hosted index by adding --use-deprecated-gcs=false and bumping ENVTEST_K8S_VERSION from 1.30.0 to 1.31.0 (the first version available in the GitHub release index). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Signed-off-by: Seer <kvcnow@gmail.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent c1f2c3f commit 41b8998

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+2606
-742
lines changed

.github/workflows/release-pipeline.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,6 @@ jobs:
5858
needs: build
5959
steps:
6060
- name: Create Release
61-
uses: softprops/action-gh-release@v1
61+
uses: softprops/action-gh-release@v2
6262
with:
6363
generate_release_notes: true

Makefile

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ OPERATOR_SDK_VERSION ?= v1.38.0
6161
# Image URL to use all building/pushing image targets
6262
IMG ?= $(IMAGE_TAG_BASE):v$(VERSION)
6363
# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.
64-
ENVTEST_K8S_VERSION = 1.30.0
64+
ENVTEST_K8S_VERSION = 1.31.0
6565

6666
# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
6767
ifeq (,$(shell go env GOBIN))
@@ -121,13 +121,28 @@ vet: ## Run go vet against code.
121121

122122
.PHONY: test
123123
test: manifests generate fmt vet envtest ## Run tests.
124-
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test $$(go list ./... | grep -vE "/test|/e2e|mocks|_generated") -coverprofile coverage.txt
124+
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path --use-deprecated-gcs=false)" go test $$(go list ./... | grep -vE "/test|/e2e|mocks|_generated") -coverprofile coverage.txt
125+
126+
KIND_CLUSTER ?= valkey-operator
125127

126128
# Utilize Kind or modify the e2e tests to load the image locally, enabling compatibility with other vendors.
127129
.PHONY: test-e2e # Run the e2e tests against a Kind k8s instance that is spun up.
128130
test-e2e:
129131
SKIP_DEPLOY_OPERATOR=1 SKIP_DEPLOY_PROMETHEUS=1 SKIP_DEPLOY_CERT_MANAGER=1 go test ./test/e2e/ --ginkgo.v --ginkgo.timeout 6h
130132

133+
.PHONY: kind-setup
134+
kind-setup: ## Create a local Kind cluster if it does not already exist.
135+
kind get clusters | grep -q "^$(KIND_CLUSTER)$$" || \
136+
kind create cluster --name $(KIND_CLUSTER) --config config/kind/kind-config.yaml
137+
138+
.PHONY: kind-load
139+
kind-load: docker-build kind-setup ## Build the operator image and load it into the Kind cluster.
140+
kind load docker-image ${IMG} --name $(KIND_CLUSTER)
141+
142+
.PHONY: test-e2e-local
143+
test-e2e-local: kind-load install deploy ## Run e2e tests against a local Kind cluster (installs dependencies automatically).
144+
go test ./test/e2e/ --ginkgo.v --ginkgo.timeout 6h
145+
131146
.PHONY: lint
132147
lint: golangci-lint ## Run golangci-lint linter
133148
$(GOLANGCI_LINT) run

api/rds/v1alpha1/valkey_types.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,10 @@ type ValkeySpec struct {
7272
// for detailed settings, please refer to https://github.com/valkey-io/valkey/blob/unstable/valkey.conf
7373
CustomConfigs map[string]string `json:"customConfigs,omitempty"`
7474

75-
// Modules defines the module settings for Valkey
75+
// Modules defines a list of modules to be loaded into the valkey instance.
76+
// Each module is specified by its name and version.
77+
// Modules are loaded at startup and can extend Redis functionality.
78+
// +optional
7679
Modules []core.ValkeyModule `json:"modules,omitempty"`
7780

7881
// Storage defines the storage settings for Valkey

api/v1alpha1/cluster_types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ import (
2222
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2323
)
2424

25+
const (
26+
ClusterResourceCleanFinalizer = "buf.red/cluster-resource-clean"
27+
)
28+
2529
type ShardConfig struct {
2630
// Slots is the slot range for the shard, eg: 0-1000,1002,1005-1100
2731
//+kubebuilder:validation:Pattern:=`^(\d{1,5}|(\d{1,5}-\d{1,5}))(,(\d{1,5}|(\d{1,5}-\d{1,5})))*$`

cmd/helper/commands/cluster/access.go

Lines changed: 21 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,21 @@ import (
3535
"k8s.io/client-go/kubernetes"
3636
)
3737

38-
// ExposeNodePort
39-
func ExposeNodePort(ctx context.Context, client *kubernetes.Clientset, namespace, podName, ipfamily string, serviceType corev1.ServiceType, logger logr.Logger) error {
40-
logger.Info("Info", "serviceType", serviceType, "ipfamily", ipfamily)
38+
// Access
39+
func Access(ctx context.Context, client *kubernetes.Clientset, namespace, podName, ipfamily string, logger logr.Logger) error {
40+
podSvc, err := commands.RetryGetService(ctx, client, namespace, podName, 20, logger)
41+
if errors.IsNotFound(err) {
42+
if podSvc, err = commands.RetryGetService(ctx, client, namespace, podName, 20, logger); err != nil {
43+
logger.Error(err, "get service failed", "target", fmt.Sprintf("%s/%s", namespace, podName))
44+
return err
45+
}
46+
} else if err != nil {
47+
logger.Error(err, "get service failed", "target", fmt.Sprintf("%s/%s", namespace, podName))
48+
return err
49+
}
50+
serviceType := podSvc.Spec.Type
51+
52+
logger.Info("check pod service type", "ipfamily", ipfamily, "serviceType", serviceType, "podName", podName)
4153
pod, err := commands.GetPod(ctx, client, namespace, podName, logger)
4254
if err != nil {
4355
logger.Error(err, "get pods failed", "namespace", namespace, "name", podName)
@@ -54,16 +66,6 @@ func ExposeNodePort(ctx context.Context, client *kubernetes.Clientset, namespace
5466
announceIPort int32 = 16379
5567
)
5668
if serviceType == corev1.ServiceTypeNodePort {
57-
podSvc, err := commands.RetryGetService(ctx, client, namespace, podName, corev1.ServiceTypeNodePort, 20, logger)
58-
if errors.IsNotFound(err) {
59-
if podSvc, err = commands.RetryGetService(ctx, client, namespace, podName, corev1.ServiceTypeNodePort, 20, logger); err != nil {
60-
logger.Error(err, "get service failed", "target", fmt.Sprintf("%s/%s", namespace, podName))
61-
return err
62-
}
63-
} else if err != nil {
64-
logger.Error(err, "get service failed", "target", fmt.Sprintf("%s/%s", namespace, podName))
65-
return err
66-
}
6769
for _, v := range podSvc.Spec.Ports {
6870
if v.Name == "client" {
6971
announcePort = v.NodePort
@@ -121,17 +123,6 @@ func ExposeNodePort(ctx context.Context, client *kubernetes.Clientset, namespace
121123
return err
122124
}
123125
} else if serviceType == corev1.ServiceTypeLoadBalancer {
124-
podSvc, err := commands.RetryGetService(ctx, client, namespace, podName, corev1.ServiceTypeLoadBalancer, 20, logger)
125-
if errors.IsNotFound(err) {
126-
if podSvc, err = commands.RetryGetService(ctx, client, namespace, podName, corev1.ServiceTypeLoadBalancer, 20, logger); err != nil {
127-
logger.Error(err, "retry get lb service failed")
128-
return err
129-
}
130-
} else if err != nil {
131-
logger.Error(err, "get lb service failed", "target", fmt.Sprintf("%s/%s", namespace, podName))
132-
return err
133-
}
134-
135126
for _, v := range podSvc.Status.LoadBalancer.Ingress {
136127
if v.IP != "" {
137128
ip, err := netip.ParseAddr(v.IP)
@@ -165,14 +156,14 @@ func ExposeNodePort(ctx context.Context, client *kubernetes.Clientset, namespace
165156
}
166157
}
167158

168-
format_announceIp := strings.Replace(announceIp, ":", "-", -1)
169-
if strings.HasSuffix(format_announceIp, "-") {
170-
format_announceIp = fmt.Sprintf("%s0", format_announceIp)
159+
fAnnounceIp := strings.ReplaceAll(announceIp, ":", "-")
160+
if strings.HasSuffix(fAnnounceIp, "-") {
161+
fAnnounceIp = fmt.Sprintf("%s0", fAnnounceIp)
171162
}
172163
labelPatch := fmt.Sprintf(`[{"op":"add","path":"/metadata/labels/%s","value":"%s"},{"op":"add","path":"/metadata/labels/%s","value":"%s"},{"op":"add","path":"/metadata/labels/%s","value":"%s"}]`,
173-
strings.Replace(builder.AnnounceIPLabelKey, "/", "~1", -1), format_announceIp,
174-
strings.Replace(builder.AnnouncePortLabelKey, "/", "~1", -1), strconv.Itoa(int(announcePort)),
175-
strings.Replace(builder.AnnounceIPortLabelKey, "/", "~1", -1), strconv.Itoa(int(announceIPort)))
164+
strings.ReplaceAll(builder.AnnounceIPLabelKey, "/", "~1"), fAnnounceIp,
165+
strings.ReplaceAll(builder.AnnouncePortLabelKey, "/", "~1"), strconv.Itoa(int(announcePort)),
166+
strings.ReplaceAll(builder.AnnounceIPortLabelKey, "/", "~1"), strconv.Itoa(int(announceIPort)))
176167

177168
logger.Info(labelPatch)
178169
_, err = client.CoreV1().Pods(pod.Namespace).Patch(ctx, podName, types.JSONPatchType, []byte(labelPatch), metav1.PatchOptions{})

cmd/helper/commands/cluster/command.go

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import (
2222

2323
"github.com/chideat/valkey-operator/cmd/helper/commands"
2424
"github.com/urfave/cli/v2"
25-
corev1 "k8s.io/api/core/v1"
2625
)
2726

2827
func NewCommand(ctx context.Context) *cli.Command {
@@ -99,12 +98,6 @@ func NewCommand(ctx context.Context) *cli.Command {
9998
Usage: "IP_FAMILY for expose",
10099
EnvVars: []string{"IP_FAMILY_PREFER"},
101100
},
102-
&cli.StringFlag{
103-
Name: "service-type",
104-
Usage: "Service type for sentinel service",
105-
EnvVars: []string{"SERVICE_TYPE"},
106-
Value: "ClusterIP",
107-
},
108101
},
109102
Subcommands: []*cli.Command{
110103
{
@@ -113,10 +106,9 @@ func NewCommand(ctx context.Context) *cli.Command {
113106
Flags: []cli.Flag{},
114107
Action: func(c *cli.Context) error {
115108
var (
116-
namespace = c.String("namespace")
117-
podName = c.String("pod-name")
118-
ipFamily = c.String("ip-family")
119-
serviceType = corev1.ServiceType(c.String("service-type"))
109+
namespace = c.String("namespace")
110+
podName = c.String("pod-name")
111+
ipFamily = c.String("ip-family")
120112
)
121113
if namespace == "" {
122114
return cli.Exit("require namespace", 1)
@@ -133,7 +125,7 @@ func NewCommand(ctx context.Context) *cli.Command {
133125
return cli.Exit(err, 1)
134126
}
135127

136-
if err := ExposeNodePort(ctx, client, namespace, podName, ipFamily, serviceType, logger); err != nil {
128+
if err := Access(ctx, client, namespace, podName, ipFamily, logger); err != nil {
137129
logger.Error(err, "expose node port failed")
138130
return cli.Exit(err, 1)
139131
}

cmd/helper/commands/failover/access.go

Lines changed: 19 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,25 @@ import (
3434
"k8s.io/client-go/kubernetes"
3535
)
3636

37-
func Access(ctx context.Context, client *kubernetes.Clientset, namespace, podName, ipfamily string, serviceType corev1.ServiceType, logger logr.Logger) error {
38-
logger.Info("service access", "serviceType", serviceType, "ipfamily", ipfamily, "podName", podName)
37+
func Access(ctx context.Context, client *kubernetes.Clientset, namespace, podName, ipfamily string, logger logr.Logger) error {
38+
podSvc, err := commands.RetryGetService(ctx, client, namespace, podName, 20, logger)
39+
if errors.IsNotFound(err) {
40+
if podSvc, err = commands.RetryGetService(ctx, client, namespace, podName, 20, logger); err != nil {
41+
logger.Error(err, "get service failed", "target", fmt.Sprintf("%s/%s", namespace, podName))
42+
return err
43+
}
44+
} else if err != nil {
45+
logger.Error(err, "get service failed", "target", fmt.Sprintf("%s/%s", namespace, podName))
46+
return err
47+
}
48+
serviceType := podSvc.Spec.Type
49+
50+
logger.Info("check pod service type", "ipfamily", ipfamily, "serviceType", serviceType, "podName", podName)
3951
pod, err := commands.GetPod(ctx, client, namespace, podName, logger)
4052
if err != nil {
4153
logger.Error(err, "get pods failed", "namespace", namespace, "name", podName)
4254
return err
4355
}
44-
4556
if pod.Status.HostIP == "" {
4657
return fmt.Errorf("pod not found or pod with invalid hostIP")
4758
}
@@ -51,16 +62,6 @@ func Access(ctx context.Context, client *kubernetes.Clientset, namespace, podNam
5162
announcePort int32 = 6379
5263
)
5364
if serviceType == corev1.ServiceTypeNodePort {
54-
podSvc, err := commands.RetryGetService(ctx, client, namespace, podName, corev1.ServiceTypeNodePort, 20, logger)
55-
if errors.IsNotFound(err) {
56-
if podSvc, err = commands.RetryGetService(ctx, client, namespace, podName, corev1.ServiceTypeNodePort, 20, logger); err != nil {
57-
logger.Error(err, "get service failed", "target", fmt.Sprintf("%s/%s", namespace, podName))
58-
return err
59-
}
60-
} else if err != nil {
61-
logger.Error(err, "get service failed", "target", fmt.Sprintf("%s/%s", namespace, podName))
62-
return err
63-
}
6465
for _, v := range podSvc.Spec.Ports {
6566
if v.Name == "client" {
6667
announcePort = v.NodePort
@@ -115,17 +116,6 @@ func Access(ctx context.Context, client *kubernetes.Clientset, namespace, podNam
115116
return err
116117
}
117118
} else if serviceType == corev1.ServiceTypeLoadBalancer {
118-
podSvc, err := commands.RetryGetService(ctx, client, namespace, podName, corev1.ServiceTypeLoadBalancer, 20, logger)
119-
if errors.IsNotFound(err) {
120-
if podSvc, err = commands.RetryGetService(ctx, client, namespace, podName, corev1.ServiceTypeLoadBalancer, 20, logger); err != nil {
121-
logger.Error(err, "retry get lb service failed")
122-
return err
123-
}
124-
} else if err != nil {
125-
logger.Error(err, "get lb service failed", "target", fmt.Sprintf("%s/%s", namespace, podName))
126-
return err
127-
}
128-
129119
for _, v := range podSvc.Status.LoadBalancer.Ingress {
130120
if v.IP == "" {
131121
continue
@@ -161,13 +151,13 @@ func Access(ctx context.Context, client *kubernetes.Clientset, namespace, podNam
161151
}
162152
}
163153

164-
format_announceIp := strings.Replace(announceIp, ":", "-", -1)
165-
if strings.HasSuffix(format_announceIp, "-") {
166-
format_announceIp = fmt.Sprintf("%s0", format_announceIp)
154+
fAnnounceIp := strings.ReplaceAll(announceIp, ":", "-")
155+
if strings.HasSuffix(fAnnounceIp, "-") {
156+
fAnnounceIp = fmt.Sprintf("%s0", fAnnounceIp)
167157
}
168158
labelPatch := fmt.Sprintf(`[{"op":"add","path":"/metadata/labels/%s","value":"%s"},{"op":"add","path":"/metadata/labels/%s","value":"%s"}]`,
169-
strings.Replace(builder.AnnounceIPLabelKey, "/", "~1", -1), format_announceIp,
170-
strings.Replace(builder.AnnouncePortLabelKey, "/", "~1", -1), strconv.Itoa(int(announcePort)))
159+
strings.ReplaceAll(builder.AnnounceIPLabelKey, "/", "~1"), fAnnounceIp,
160+
strings.ReplaceAll(builder.AnnouncePortLabelKey, "/", "~1"), strconv.Itoa(int(announcePort)))
171161

172162
logger.Info(labelPatch)
173163
_, err = client.CoreV1().Pods(pod.Namespace).Patch(ctx, podName, types.JSONPatchType, []byte(labelPatch), metav1.PatchOptions{})

cmd/helper/commands/failover/command.go

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import (
2121

2222
"github.com/chideat/valkey-operator/cmd/helper/commands"
2323
"github.com/urfave/cli/v2"
24-
corev1 "k8s.io/api/core/v1"
2524
)
2625

2726
func NewCommand(ctx context.Context) *cli.Command {
@@ -49,11 +48,6 @@ func NewCommand(ctx context.Context) *cli.Command {
4948
Usage: "The id of current pod",
5049
EnvVars: []string{"POD_UID"},
5150
},
52-
&cli.StringFlag{
53-
Name: "service-name",
54-
Usage: "Service name of the statefulset",
55-
EnvVars: []string{"SERVICE_NAME"},
56-
},
5751
&cli.StringFlag{
5852
Name: "operator-username",
5953
Usage: "Operator username",
@@ -108,12 +102,6 @@ func NewCommand(ctx context.Context) *cli.Command {
108102
Usage: "IP_FAMILY for servie access",
109103
EnvVars: []string{"IP_FAMILY_PREFER"},
110104
},
111-
&cli.StringFlag{
112-
Name: "service-type",
113-
Usage: "Service type for sentinel service",
114-
EnvVars: []string{"SERVICE_TYPE"},
115-
Value: "ClusterIP",
116-
},
117105
},
118106
Subcommands: []*cli.Command{
119107
{
@@ -122,10 +110,9 @@ func NewCommand(ctx context.Context) *cli.Command {
122110
Flags: []cli.Flag{},
123111
Action: func(c *cli.Context) error {
124112
var (
125-
namespace = c.String("namespace")
126-
podName = c.String("pod-name")
127-
ipFamily = c.String("ip-family")
128-
serviceType = corev1.ServiceType(c.String("service-type"))
113+
namespace = c.String("namespace")
114+
podName = c.String("pod-name")
115+
ipFamily = c.String("ip-family")
129116
)
130117
if namespace == "" {
131118
return cli.Exit("require namespace", 1)
@@ -142,7 +129,7 @@ func NewCommand(ctx context.Context) *cli.Command {
142129
return cli.Exit(err, 1)
143130
}
144131

145-
if err := Access(ctx, client, namespace, podName, ipFamily, serviceType, logger); err != nil {
132+
if err := Access(ctx, client, namespace, podName, ipFamily, logger); err != nil {
146133
logger.Error(err, "enable nodeport service access failed")
147134
return cli.Exit(err, 1)
148135
}

cmd/helper/commands/failover/shutdown.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ func loadAnnounceAddress(filepath string, logger logr.Logger) string {
4040
}
4141
data, err := os.ReadFile(filepath)
4242
if err != nil {
43+
if os.IsNotExist(err) {
44+
return ""
45+
}
4346
logger.Error(err, "read announce file failed", "path", filepath)
4447
return ""
4548
}

cmd/helper/commands/helper.go

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -196,21 +196,15 @@ func GetPod(ctx context.Context, client *kubernetes.Clientset, namespace, name s
196196
return pod, nil
197197
}
198198

199-
func RetryGetService(ctx context.Context, clientset *kubernetes.Clientset, svcNamespace, svcName string, typ corev1.ServiceType,
200-
count int, logger logr.Logger) (*corev1.Service, error) {
201-
202-
serviceChecker := func(svc *corev1.Service, typ corev1.ServiceType) error {
199+
func RetryGetService(ctx context.Context, clientset *kubernetes.Clientset, svcNamespace, svcName string, count int, logger logr.Logger) (*corev1.Service, error) {
200+
serviceChecker := func(svc *corev1.Service) error {
203201
if svc == nil {
204202
return fmt.Errorf("service not found")
205203
}
206204
if len(svc.Spec.Ports) < 1 {
207205
return fmt.Errorf("service port not found")
208206
}
209207

210-
if svc.Spec.Type != typ {
211-
return fmt.Errorf("service type not match")
212-
}
213-
214208
switch svc.Spec.Type {
215209
case corev1.ServiceTypeNodePort:
216210
for _, port := range svc.Spec.Ports {
@@ -233,13 +227,13 @@ func RetryGetService(ctx context.Context, clientset *kubernetes.Clientset, svcNa
233227
}
234228

235229
logger.Info("retry get service", "target", fmt.Sprintf("%s/%s", svcNamespace, svcName), "count", count)
236-
for i := 0; i < count+1; i++ {
230+
for range count + 1 {
237231
svc, err := clientset.CoreV1().Services(svcNamespace).Get(ctx, svcName, metav1.GetOptions{})
238232
if err != nil {
239233
logger.Error(err, "get service failed", "target", fmt.Sprintf("%s/%s", svcNamespace, svcName))
240234
return nil, err
241235
}
242-
if serviceChecker(svc, typ) != nil {
236+
if serviceChecker(svc) != nil {
243237
logger.Error(err, "service check failed", "target", fmt.Sprintf("%s/%s", svcNamespace, svcName))
244238
} else {
245239
return svc, nil

0 commit comments

Comments
 (0)