diff --git a/.changes/unreleased/Fixed-20250223-222850.yaml b/.changes/unreleased/Fixed-20250223-222850.yaml new file mode 100644 index 00000000..d951ee77 --- /dev/null +++ b/.changes/unreleased/Fixed-20250223-222850.yaml @@ -0,0 +1,3 @@ +kind: Fixed +body: 'bug: regression with pod name in grpc-public-host arg' +time: 2025-02-23T22:28:50.688471+08:00 diff --git a/.golangci.yml b/.golangci.yml index 1dc7fd9d..38c43fd7 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -35,7 +35,8 @@ run: # output configuration options output: # colored-line-number|line-number|json|tab|checkstyle, default is "colored-line-number" - format: colored-line-number + formats: + - format: colored-line-number print-issued-lines: true @@ -61,13 +62,6 @@ linters-settings: # report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`; # default is false: such cases aren't reported by default. check-blank: false - govet: - # report about shadowed variables - shadow: true - fieldalignment: true - golint: - # minimal confidence for issues, default is 0.8 - min-confidence: 0.8 gofmt: # simplify code: gofmt with `-s` option, true by default simplify: true @@ -85,9 +79,6 @@ linters-settings: - G101 - G115 - G601 # no longer actual since 1.22 - fieldalignment: - # print struct with more effective memory layout or not, false by default - suggest-new: true misspell: # Correct spellings using locale preferences for US or UK. # Default is to use a neutral variety of English. @@ -118,17 +109,7 @@ linters-settings: - name: empty-block - name: superfluous-else - name: unreachable-code - unused: - # treat code as a program (not a library) and report unused exported identifiers; default is false. - # XXX: if you enable this setting, unused will report a lot of false-positives in text editors: - # if it's called for subdir of a project it can't find funcs usages. All text editor integrations - # with golangci-lint call it on a directory with the changed file. - check-exported: false unparam: - # call graph construction algorithm (cha, rta). In general, use cha for libraries, - # and rta for programs with main packages. Default is cha. - algo: cha - # Inspect exported functions, default is false. Set to true if no external program/library imports your code. # XXX: if you enable this setting, unparam will report a lot of false-positives in text editors: # if it's called for subdir of a project it can't find external interfaces. All text editor integrations @@ -192,9 +173,6 @@ issues: # Default value for this option is true. exclude-use-default: true - # Maximum issues count per one linter. Set to 0 to disable. Default is 50. - max-per-linter: 0 - # Maximum count of issues with the same text. Set to 0 to disable. Default is 3. max-same-issues: 0 diff --git a/internal/controllers/database/controller_test.go b/internal/controllers/database/controller_test.go index 467726a5..a36e0694 100644 --- a/internal/controllers/database/controller_test.go +++ b/internal/controllers/database/controller_test.go @@ -308,40 +308,47 @@ var _ = Describe("Database controller medium tests", func() { Expect(args).To(ContainElements([]string{"--grpc-public-address-v4", "--grpc-public-target-name-override"})) }) + checkContainerArg := func(expectedArgKey, expectedArgValue string) error { + foundStatefulSet := appsv1.StatefulSet{} + Eventually(func() error { + return k8sClient.Get(ctx, + types.NamespacedName{ + Name: testobjects.DatabaseName, + Namespace: testobjects.YdbNamespace, + }, + &foundStatefulSet, + ) + }, test.Timeout, test.Interval).Should(Succeed()) + podContainerArgs := foundStatefulSet.Spec.Template.Spec.Containers[0].Args + for idx, argKey := range podContainerArgs { + if argKey == expectedArgKey { + if podContainerArgs[idx+1] != expectedArgValue { + return fmt.Errorf( + "Found arg `%s` value %s does not match with expected: %s", + expectedArgKey, + podContainerArgs[idx+1], + expectedArgValue, + ) + } + } + } + return nil + } + It("Check externalPort GRPC Service field propagation", func() { By("Create test database") databaseSample = *testobjects.DefaultDatabase() + databaseSample.Spec.Service.GRPC.ExternalHost = fmt.Sprintf("%s.%s", testobjects.YdbNamespace, "k8s.external.net") Expect(k8sClient.Create(ctx, &databaseSample)).Should(Succeed()) - checkPublicPortArg := func(expectedGRPCPort string) error { - foundStatefulSet := appsv1.StatefulSet{} - Eventually(func() error { - return k8sClient.Get(ctx, - types.NamespacedName{ - Name: testobjects.DatabaseName, - Namespace: testobjects.YdbNamespace, - }, - &foundStatefulSet, - ) - }, test.Timeout, test.Interval).Should(Succeed()) - podContainerArgs := foundStatefulSet.Spec.Template.Spec.Containers[0].Args - for idx, argKey := range podContainerArgs { - if argKey == "--grpc-public-port" { - if podContainerArgs[idx+1] != expectedGRPCPort { - return fmt.Errorf( - "Found arg `--grpc-public-port` value %s does not match with expected: %s", - podContainerArgs[idx+1], - expectedGRPCPort, - ) - } - } - } - return nil - } - By("Check that args `--grpc-public-host` and `--grpc-public-port` propagated to StatefulSet pods...") Eventually( - checkPublicPortArg(fmt.Sprintf("%d", v1alpha1.GRPCPort)), + checkContainerArg("--grpc-public-host", fmt.Sprintf("%s.%s", "$(POD_NAME)", databaseSample.Spec.Service.GRPC.ExternalHost)), + test.Timeout, + test.Interval).ShouldNot(HaveOccurred()) + + Eventually( + checkContainerArg("--grpc-public-port", fmt.Sprintf("%d", v1alpha1.GRPCPort)), test.Timeout, test.Interval).ShouldNot(HaveOccurred()) @@ -384,7 +391,29 @@ var _ = Describe("Database controller medium tests", func() { By("Check that args `--grpc-public-port` was updated in StatefulSet...") Eventually( - checkPublicPortArg(fmt.Sprintf("%d", externalPort)), + checkContainerArg("--grpc-public-port", fmt.Sprintf("%d", externalPort)), + test.Timeout, + test.Interval).ShouldNot(HaveOccurred()) + }) + + It("Checking args propagation from annotation to StatefulSet", func() { + By("Check that Database with annotations was created...") + databaseSample = *testobjects.DefaultDatabase() + databaseSample.Annotations = map[string]string{ + v1alpha1.AnnotationGRPCPublicHost: fmt.Sprintf("%s.%s", testobjects.YdbNamespace, "k8s.external.net"), + v1alpha1.AnnotationGRPCPublicPort: fmt.Sprintf("%d", 30001), + } + Expect(k8sClient.Create(ctx, &databaseSample)).Should(Succeed()) + + By("Check that args `--grpc-public-host` propagated to StatefulSet pods...") + Eventually( + checkContainerArg("--grpc-public-host", fmt.Sprintf("%s.%s.%s", "$(POD_NAME)", testobjects.YdbNamespace, "k8s.external.net")), + test.Timeout, + test.Interval).ShouldNot(HaveOccurred()) + + By("Check that args `--grpc-public-port` propagated to StatefulSet pods...") + Eventually( + checkContainerArg("--grpc-public-port", fmt.Sprintf("%d", 30001)), test.Timeout, test.Interval).ShouldNot(HaveOccurred()) }) diff --git a/internal/resources/database_statefulset.go b/internal/resources/database_statefulset.go index a27f977b..fa04465b 100644 --- a/internal/resources/database_statefulset.go +++ b/internal/resources/database_statefulset.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "regexp" + "strings" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" @@ -657,6 +658,9 @@ func (b *DatabaseStatefulSetBuilder) buildContainerArgs() ([]string, []string) { if value, ok := b.ObjectMeta.Annotations[api.AnnotationGRPCPublicHost]; ok { publicHost = value } + if !(strings.HasPrefix(publicHost, "$(POD_NAME)") || strings.HasPrefix(publicHost, "$(NODE_NAME)")) { + publicHost = fmt.Sprintf("%s.%s", "$(POD_NAME)", publicHost) + } if b.Spec.Service.GRPC.IPDiscovery != nil && b.Spec.Service.GRPC.IPDiscovery.Enabled { targetNameOverride := b.Spec.Service.GRPC.IPDiscovery.TargetNameOverride