From cd364330915b4cf0c2da3c2b2c7051c8a8241a0f Mon Sep 17 00:00:00 2001
From: sophon
Date: Mon, 18 Nov 2024 15:46:22 +0800
Subject: [PATCH] chore: update ut
---
.../parameters/combine_upgrade_policy_test.go | 176 +--
controllers/parameters/configuration_test.go | 2 +-
.../parallel_upgrade_policy_test.go | 314 ++---
docs/developer_docs/api-reference/cluster.md | 164 +--
.../config_manager/builder_test.go | 15 -
.../config_manager/config_handler.go | 2 +-
.../config_manager/handler_util_test.go | 1118 ++++++++---------
pkg/configuration/core/config_util.go | 3 +-
pkg/configuration/validate/config_validate.go | 36 -
.../validate/config_validate_test.go | 102 +-
.../configuration/builtin_env_test.go | 516 ++++----
.../configuration/parameter_utils_test.go | 1 +
.../configuration/resource_wrapper_test.go | 10 +-
pkg/controllerutil/parameter_schema.go | 2 +-
14 files changed, 1135 insertions(+), 1326 deletions(-)
diff --git a/controllers/parameters/combine_upgrade_policy_test.go b/controllers/parameters/combine_upgrade_policy_test.go
index c9facd67ee2..daf6559c522 100644
--- a/controllers/parameters/combine_upgrade_policy_test.go
+++ b/controllers/parameters/combine_upgrade_policy_test.go
@@ -19,91 +19,91 @@ along with this program. If not, see .
package parameters
-// import (
-// "fmt"
-//
-// . "github.com/onsi/ginkgo/v2"
-// . "github.com/onsi/gomega"
-//
-// parametersv1alpha1 "github.com/apecloud/kubeblocks/apis/parameters/v1alpha1"
-// testutil "github.com/apecloud/kubeblocks/pkg/testutil/k8s"
-// )
-//
-// var _ = Describe("Reconfigure CombineSyncPolicy", func() {
-//
-// var (
-// k8sMockClient *testutil.K8sClientMockHelper
-// )
-//
-// BeforeEach(func() {
-// k8sMockClient = testutil.NewK8sMockClient()
-// })
-//
-// AfterEach(func() {
-// k8sMockClient.Finish()
-// })
-//
-// Context("combine reconfigure policy test", func() {
-// It("Should success without error", func() {
-// By("check normal policy name")
-// testPolicyExecs := &combineUpgradePolicy{
-// policyExecutors: []reconfigurePolicy{&testPolicy{}},
-// }
-//
-// Expect(upgradePolicyMap[parametersv1alpha1.DynamicReloadAndRestartPolicy]).ShouldNot(BeNil())
-//
-// mockParam := newMockReconfigureParams("simplePolicy", k8sMockClient.Client(),
-// withMockInstanceSet(2, nil),
-// withConfigSpec("for_test", map[string]string{
-// "key": "value",
-// }),
-// withClusterComponent(2))
-//
-// Expect(testPolicyExecs.GetPolicyName()).Should(BeEquivalentTo(parametersv1alpha1.DynamicReloadAndRestartPolicy))
-// status, err := testPolicyExecs.Upgrade(mockParam)
-// Expect(err).Should(Succeed())
-// Expect(status.Status).Should(BeEquivalentTo(ESNone))
-// })
-//
-// It("Should success without error", func() {
-// By("check failed policy name")
-// testPolicyExecs := &combineUpgradePolicy{
-// policyExecutors: []reconfigurePolicy{&testErrorPolicy{}},
-// }
-//
-// mockParam := newMockReconfigureParams("simplePolicy", k8sMockClient.Client(),
-// withMockInstanceSet(2, nil),
-// withConfigSpec("for_test", map[string]string{
-// "key": "value",
-// }),
-// withClusterComponent(2))
-//
-// Expect(testPolicyExecs.GetPolicyName()).Should(BeEquivalentTo(parametersv1alpha1.DynamicReloadAndRestartPolicy))
-// status, err := testPolicyExecs.Upgrade(mockParam)
-// Expect(err).ShouldNot(Succeed())
-// Expect(status.Status).Should(BeEquivalentTo(ESFailedAndRetry))
-// })
-// })
-// })
-//
-// type testPolicy struct {
-// }
-//
-// type testErrorPolicy struct {
-// }
-//
-// func (t testErrorPolicy) Upgrade(params reconfigureContext) (ReturnedStatus, error) {
-// return makeReturnedStatus(ESFailedAndRetry), fmt.Errorf("testErrorPolicy failed")
-// }
-//
-// func (t testErrorPolicy) GetPolicyName() string {
-// return "testErrorPolicy"
-// }
-//
-// func (t testPolicy) Upgrade(params reconfigureContext) (ReturnedStatus, error) {
-// return makeReturnedStatus(ESNone), nil
-// }
-//
-// func (t testPolicy) GetPolicyName() string {
-// return "testPolicy"
-// }
+import (
+ "fmt"
+
+ . "github.com/onsi/ginkgo/v2"
+ . "github.com/onsi/gomega"
+
+ parametersv1alpha1 "github.com/apecloud/kubeblocks/apis/parameters/v1alpha1"
+ testutil "github.com/apecloud/kubeblocks/pkg/testutil/k8s"
+)
+
+var _ = Describe("Reconfigure CombineSyncPolicy", func() {
+
+ var (
+ k8sMockClient *testutil.K8sClientMockHelper
+ )
+
+ BeforeEach(func() {
+ k8sMockClient = testutil.NewK8sMockClient()
+ })
+
+ AfterEach(func() {
+ k8sMockClient.Finish()
+ })
+
+ Context("combine reconfigure policy test", func() {
+ It("Should success without error", func() {
+ By("check normal policy name")
+ testPolicyExecs := &combineUpgradePolicy{
+ policyExecutors: []reconfigurePolicy{&testPolicy{}},
+ }
+
+ Expect(upgradePolicyMap[parametersv1alpha1.DynamicReloadAndRestartPolicy]).ShouldNot(BeNil())
+
+ mockParam := newMockReconfigureParams("simplePolicy", k8sMockClient.Client(),
+ withMockInstanceSet(2, nil),
+ withConfigSpec("for_test", map[string]string{
+ "key": "value",
+ }),
+ withClusterComponent(2))
+
+ Expect(testPolicyExecs.GetPolicyName()).Should(BeEquivalentTo(parametersv1alpha1.DynamicReloadAndRestartPolicy))
+ status, err := testPolicyExecs.Upgrade(mockParam)
+ Expect(err).Should(Succeed())
+ Expect(status.Status).Should(BeEquivalentTo(ESNone))
+ })
+
+ It("Should success without error", func() {
+ By("check failed policy name")
+ testPolicyExecs := &combineUpgradePolicy{
+ policyExecutors: []reconfigurePolicy{&testErrorPolicy{}},
+ }
+
+ mockParam := newMockReconfigureParams("simplePolicy", k8sMockClient.Client(),
+ withMockInstanceSet(2, nil),
+ withConfigSpec("for_test", map[string]string{
+ "key": "value",
+ }),
+ withClusterComponent(2))
+
+ Expect(testPolicyExecs.GetPolicyName()).Should(BeEquivalentTo(parametersv1alpha1.DynamicReloadAndRestartPolicy))
+ status, err := testPolicyExecs.Upgrade(mockParam)
+ Expect(err).ShouldNot(Succeed())
+ Expect(status.Status).Should(BeEquivalentTo(ESFailedAndRetry))
+ })
+ })
+})
+
+type testPolicy struct {
+}
+
+type testErrorPolicy struct {
+}
+
+func (t testErrorPolicy) Upgrade(params reconfigureContext) (ReturnedStatus, error) {
+ return makeReturnedStatus(ESFailedAndRetry), fmt.Errorf("testErrorPolicy failed")
+}
+
+func (t testErrorPolicy) GetPolicyName() string {
+ return "testErrorPolicy"
+}
+
+func (t testPolicy) Upgrade(params reconfigureContext) (ReturnedStatus, error) {
+ return makeReturnedStatus(ESNone), nil
+}
+
+func (t testPolicy) GetPolicyName() string {
+ return "testPolicy"
+}
diff --git a/controllers/parameters/configuration_test.go b/controllers/parameters/configuration_test.go
index a8986f0da0c..200349506fb 100644
--- a/controllers/parameters/configuration_test.go
+++ b/controllers/parameters/configuration_test.go
@@ -183,6 +183,6 @@ func cleanEnv() {
testapps.ClearResourcesWithRemoveFinalizerOption(&testCtx, generics.SecretSignature, true, inNS)
testapps.ClearResourcesWithRemoveFinalizerOption(&testCtx, generics.InstanceSetSignature, true, inNS, ml)
testapps.ClearResourcesWithRemoveFinalizerOption(&testCtx, generics.ConfigurationSignature, false, inNS, ml)
- testapps.ClearResourcesWithRemoveFinalizerOption(&testCtx, generics.ComponentParameterSignature, true, inNS, ml)
+ testapps.ClearResourcesWithRemoveFinalizerOption(&testCtx, generics.ComponentParameterSignature, true, inNS)
testapps.ClearResourcesWithRemoveFinalizerOption(&testCtx, generics.ParameterSignature, true, inNS, ml)
}
diff --git a/controllers/parameters/parallel_upgrade_policy_test.go b/controllers/parameters/parallel_upgrade_policy_test.go
index 925cb5248f5..da86abdffa6 100644
--- a/controllers/parameters/parallel_upgrade_policy_test.go
+++ b/controllers/parameters/parallel_upgrade_policy_test.go
@@ -19,160 +19,160 @@ along with this program. If not, see .
package parameters
-// import (
-// . "github.com/onsi/ginkgo/v2"
-// . "github.com/onsi/gomega"
-//
-// "github.com/golang/mock/gomock"
-//
-// cfgcore "github.com/apecloud/kubeblocks/pkg/configuration/core"
-// cfgproto "github.com/apecloud/kubeblocks/pkg/configuration/proto"
-// mock_proto "github.com/apecloud/kubeblocks/pkg/configuration/proto/mocks"
-// testutil "github.com/apecloud/kubeblocks/pkg/testutil/k8s"
-// )
-//
-// var parallelPolicy = parallelUpgradePolicy{}
-//
-// var _ = Describe("Reconfigure ParallelPolicy", func() {
-//
-// var (
-// k8sMockClient *testutil.K8sClientMockHelper
-// reconfigureClient *mock_proto.MockReconfigureClient
-// )
-//
-// BeforeEach(func() {
-// k8sMockClient = testutil.NewK8sMockClient()
-// reconfigureClient = mock_proto.NewMockReconfigureClient(k8sMockClient.Controller())
-// })
-//
-// AfterEach(func() {
-// k8sMockClient.Finish()
-// })
-//
-// Context("parallel reconfigure policy test", func() {
-// It("Should success without error", func() {
-// Expect(parallelPolicy.GetPolicyName()).Should(BeEquivalentTo("parallel"))
-//
-// // mock client update caller
-// k8sMockClient.MockPatchMethod(testutil.WithSucceed(testutil.WithTimes(3)))
-//
-// reconfigureClient.EXPECT().StopContainer(gomock.Any(), gomock.Any()).Return(
-// &cfgproto.StopContainerResponse{}, nil).
-// Times(3)
-//
-// mockParam := newMockReconfigureParams("parallelPolicy", k8sMockClient.Client(),
-// withGRPCClient(func(addr string) (cfgproto.ReconfigureClient, error) {
-// return reconfigureClient, nil
-// }),
-// withMockInstanceSet(3, nil),
-// withClusterComponent(3),
-// withConfigSpec("for_test", map[string]string{
-// "a": "b",
-// }))
-//
-// k8sMockClient.MockListMethod(testutil.WithListReturned(
-// testutil.WithConstructListReturnedResult(fromPodObjectList(
-// newMockPodsWithInstanceSet(&mockParam.InstanceSetUnits[0], 3),
-// ))))
-//
-// status, err := parallelPolicy.Upgrade(mockParam)
-// Expect(err).Should(Succeed())
-// Expect(status.Status).Should(BeEquivalentTo(ESNone))
-// })
-// })
-//
-// Context("parallel reconfigure policy test with List pods failed", func() {
-// It("Should failed", func() {
-// mockParam := newMockReconfigureParams("parallelPolicy", k8sMockClient.Client(),
-// withGRPCClient(func(addr string) (cfgproto.ReconfigureClient, error) {
-// return reconfigureClient, nil
-// }),
-// withMockInstanceSet(3, nil),
-// withClusterComponent(3),
-// withConfigSpec("for_test", map[string]string{
-// "a": "b",
-// }))
-//
-// // first failed
-// getPodsError := cfgcore.MakeError("for grpc failed.")
-// k8sMockClient.MockListMethod(testutil.WithFailed(getPodsError))
-//
-// status, err := parallelPolicy.Upgrade(mockParam)
-// // first failed
-// Expect(err).Should(BeEquivalentTo(getPodsError))
-// Expect(status.Status).Should(BeEquivalentTo(ESFailedAndRetry))
-// })
-// })
-//
-// Context("parallel reconfigure policy test with stop container failed", func() {
-// It("Should failed", func() {
-// stopError := cfgcore.MakeError("failed to stop!")
-// reconfigureClient.EXPECT().StopContainer(gomock.Any(), gomock.Any()).Return(
-// &cfgproto.StopContainerResponse{}, stopError).
-// Times(1)
-//
-// reconfigureClient.EXPECT().StopContainer(gomock.Any(), gomock.Any()).Return(
-// &cfgproto.StopContainerResponse{
-// ErrMessage: "failed to stop container.",
-// }, nil).
-// Times(1)
-//
-// mockParam := newMockReconfigureParams("parallelPolicy", k8sMockClient.Client(),
-// withGRPCClient(func(addr string) (cfgproto.ReconfigureClient, error) {
-// return reconfigureClient, nil
-// }),
-// withMockInstanceSet(3, nil),
-// withClusterComponent(3),
-// withConfigSpec("for_test", map[string]string{
-// "a": "b",
-// }))
-//
-// k8sMockClient.MockListMethod(testutil.WithListReturned(
-// testutil.WithConstructListReturnedResult(
-// fromPodObjectList(newMockPodsWithInstanceSet(&mockParam.InstanceSetUnits[0], 3))), testutil.WithTimes(2),
-// ))
-//
-// status, err := parallelPolicy.Upgrade(mockParam)
-// // first failed
-// Expect(err).Should(BeEquivalentTo(stopError))
-// Expect(status.Status).Should(BeEquivalentTo(ESFailedAndRetry))
-//
-// status, err = parallelPolicy.Upgrade(mockParam)
-// Expect(err).ShouldNot(Succeed())
-// Expect(err.Error()).Should(ContainSubstring("failed to stop container"))
-// Expect(status.Status).Should(BeEquivalentTo(ESFailedAndRetry))
-// })
-// })
-//
-// Context("parallel reconfigure policy test with patch failed", func() {
-// It("Should failed", func() {
-// // mock client update caller
-// patchError := cfgcore.MakeError("update failed!")
-// k8sMockClient.MockPatchMethod(testutil.WithFailed(patchError, testutil.WithTimes(1)))
-//
-// reconfigureClient.EXPECT().StopContainer(gomock.Any(), gomock.Any()).Return(
-// &cfgproto.StopContainerResponse{}, nil).
-// Times(1)
-//
-// mockParam := newMockReconfigureParams("parallelPolicy", k8sMockClient.Client(),
-// withGRPCClient(func(addr string) (cfgproto.ReconfigureClient, error) {
-// return reconfigureClient, nil
-// }),
-// withMockInstanceSet(3, nil),
-// withClusterComponent(3),
-// withConfigSpec("for_test", map[string]string{
-// "a": "b",
-// }))
-//
-// setPods := newMockPodsWithInstanceSet(&mockParam.InstanceSetUnits[0], 5)
-// k8sMockClient.MockListMethod(testutil.WithListReturned(
-// testutil.WithConstructListReturnedResult(fromPodObjectList(setPods)), testutil.WithAnyTimes(),
-// ))
-//
-// status, err := parallelPolicy.Upgrade(mockParam)
-// // first failed
-// Expect(err).Should(BeEquivalentTo(patchError))
-// Expect(status.Status).Should(BeEquivalentTo(ESFailedAndRetry))
-// })
-// })
-// })
+import (
+ . "github.com/onsi/ginkgo/v2"
+ . "github.com/onsi/gomega"
+
+ "github.com/golang/mock/gomock"
+
+ cfgcore "github.com/apecloud/kubeblocks/pkg/configuration/core"
+ cfgproto "github.com/apecloud/kubeblocks/pkg/configuration/proto"
+ mockproto "github.com/apecloud/kubeblocks/pkg/configuration/proto/mocks"
+ testutil "github.com/apecloud/kubeblocks/pkg/testutil/k8s"
+)
+
+var parallelPolicy = parallelUpgradePolicy{}
+
+var _ = Describe("Reconfigure ParallelPolicy", func() {
+
+ var (
+ k8sMockClient *testutil.K8sClientMockHelper
+ reconfigureClient *mockproto.MockReconfigureClient
+ )
+
+ BeforeEach(func() {
+ k8sMockClient = testutil.NewK8sMockClient()
+ reconfigureClient = mockproto.NewMockReconfigureClient(k8sMockClient.Controller())
+ })
+
+ AfterEach(func() {
+ k8sMockClient.Finish()
+ })
+
+ Context("parallel reconfigure policy test", func() {
+ It("Should success without error", func() {
+ Expect(parallelPolicy.GetPolicyName()).Should(BeEquivalentTo("parallel"))
+
+ // mock client update caller
+ k8sMockClient.MockPatchMethod(testutil.WithSucceed(testutil.WithTimes(3)))
+
+ reconfigureClient.EXPECT().StopContainer(gomock.Any(), gomock.Any()).Return(
+ &cfgproto.StopContainerResponse{}, nil).
+ Times(3)
+
+ mockParam := newMockReconfigureParams("parallelPolicy", k8sMockClient.Client(),
+ withGRPCClient(func(addr string) (cfgproto.ReconfigureClient, error) {
+ return reconfigureClient, nil
+ }),
+ withMockInstanceSet(3, nil),
+ withClusterComponent(3),
+ withConfigSpec("for_test", map[string]string{
+ "a": "b",
+ }))
+
+ k8sMockClient.MockListMethod(testutil.WithListReturned(
+ testutil.WithConstructListReturnedResult(fromPodObjectList(
+ newMockPodsWithInstanceSet(&mockParam.InstanceSetUnits[0], 3),
+ ))))
+
+ status, err := parallelPolicy.Upgrade(mockParam)
+ Expect(err).Should(Succeed())
+ Expect(status.Status).Should(BeEquivalentTo(ESNone))
+ })
+ })
+
+ Context("parallel reconfigure policy test with List pods failed", func() {
+ It("Should failed", func() {
+ mockParam := newMockReconfigureParams("parallelPolicy", k8sMockClient.Client(),
+ withGRPCClient(func(addr string) (cfgproto.ReconfigureClient, error) {
+ return reconfigureClient, nil
+ }),
+ withMockInstanceSet(3, nil),
+ withClusterComponent(3),
+ withConfigSpec("for_test", map[string]string{
+ "a": "b",
+ }))
+
+ // first failed
+ getPodsError := cfgcore.MakeError("for grpc failed.")
+ k8sMockClient.MockListMethod(testutil.WithFailed(getPodsError))
+
+ status, err := parallelPolicy.Upgrade(mockParam)
+ // first failed
+ Expect(err).Should(BeEquivalentTo(getPodsError))
+ Expect(status.Status).Should(BeEquivalentTo(ESFailedAndRetry))
+ })
+ })
+
+ Context("parallel reconfigure policy test with stop container failed", func() {
+ It("Should failed", func() {
+ stopError := cfgcore.MakeError("failed to stop!")
+ reconfigureClient.EXPECT().StopContainer(gomock.Any(), gomock.Any()).Return(
+ &cfgproto.StopContainerResponse{}, stopError).
+ Times(1)
+
+ reconfigureClient.EXPECT().StopContainer(gomock.Any(), gomock.Any()).Return(
+ &cfgproto.StopContainerResponse{
+ ErrMessage: "failed to stop container.",
+ }, nil).
+ Times(1)
+
+ mockParam := newMockReconfigureParams("parallelPolicy", k8sMockClient.Client(),
+ withGRPCClient(func(addr string) (cfgproto.ReconfigureClient, error) {
+ return reconfigureClient, nil
+ }),
+ withMockInstanceSet(3, nil),
+ withClusterComponent(3),
+ withConfigSpec("for_test", map[string]string{
+ "a": "b",
+ }))
+
+ k8sMockClient.MockListMethod(testutil.WithListReturned(
+ testutil.WithConstructListReturnedResult(
+ fromPodObjectList(newMockPodsWithInstanceSet(&mockParam.InstanceSetUnits[0], 3))), testutil.WithTimes(2),
+ ))
+
+ status, err := parallelPolicy.Upgrade(mockParam)
+ // first failed
+ Expect(err).Should(BeEquivalentTo(stopError))
+ Expect(status.Status).Should(BeEquivalentTo(ESFailedAndRetry))
+
+ status, err = parallelPolicy.Upgrade(mockParam)
+ Expect(err).ShouldNot(Succeed())
+ Expect(err.Error()).Should(ContainSubstring("failed to stop container"))
+ Expect(status.Status).Should(BeEquivalentTo(ESFailedAndRetry))
+ })
+ })
+
+ Context("parallel reconfigure policy test with patch failed", func() {
+ It("Should failed", func() {
+ // mock client update caller
+ patchError := cfgcore.MakeError("update failed!")
+ k8sMockClient.MockPatchMethod(testutil.WithFailed(patchError, testutil.WithTimes(1)))
+
+ reconfigureClient.EXPECT().StopContainer(gomock.Any(), gomock.Any()).Return(
+ &cfgproto.StopContainerResponse{}, nil).
+ Times(1)
+
+ mockParam := newMockReconfigureParams("parallelPolicy", k8sMockClient.Client(),
+ withGRPCClient(func(addr string) (cfgproto.ReconfigureClient, error) {
+ return reconfigureClient, nil
+ }),
+ withMockInstanceSet(3, nil),
+ withClusterComponent(3),
+ withConfigSpec("for_test", map[string]string{
+ "a": "b",
+ }))
+
+ setPods := newMockPodsWithInstanceSet(&mockParam.InstanceSetUnits[0], 5)
+ k8sMockClient.MockListMethod(testutil.WithListReturned(
+ testutil.WithConstructListReturnedResult(fromPodObjectList(setPods)), testutil.WithAnyTimes(),
+ ))
+
+ status, err := parallelPolicy.Upgrade(mockParam)
+ // first failed
+ Expect(err).Should(BeEquivalentTo(patchError))
+ Expect(status.Status).Should(BeEquivalentTo(ESFailedAndRetry))
+ })
+ })
+})
diff --git a/docs/developer_docs/api-reference/cluster.md b/docs/developer_docs/api-reference/cluster.md
index fcdbe5b4b5e..6274e7a5cdb 100644
--- a/docs/developer_docs/api-reference/cluster.md
+++ b/docs/developer_docs/api-reference/cluster.md
@@ -837,6 +837,20 @@ bool
If set, all the computing resources will be released.
+
+
+initParameters
+
+
+ComponentParameters
+
+
+ |
+
+(Optional)
+ Specifies the initialization parameters.
+ |
+
@@ -4435,135 +4449,6 @@ string
-ComponentConfigSpec
-
-
-
-
-
-
-Field |
-Description |
-
-
-
-
-
-ComponentTemplateSpec
-
-
-ComponentTemplateSpec
-
-
- |
-
-
-(Members of ComponentTemplateSpec are embedded into this type.)
-
- |
-
-
-
-keys
-
-[]string
-
- |
-
-(Optional)
- Specifies the configuration files within the ConfigMap that support dynamic updates.
-A configuration template (provided in the form of a ConfigMap) may contain templates for multiple
-configuration files.
-Each configuration file corresponds to a key in the ConfigMap.
-Some of these configuration files may support dynamic modification and reloading without requiring
-a pod restart.
-If empty or omitted, all configuration files in the ConfigMap are assumed to support dynamic updates,
-and ConfigConstraint applies to all keys.
- |
-
-
-
-constraintRef
-
-string
-
- |
-
-(Optional)
- Specifies the name of the referenced configuration constraints object.
- |
-
-
-
-asEnvFrom
-
-[]string
-
- |
-
-(Optional)
- Specifies the containers to inject the ConfigMap parameters as environment variables.
-This is useful when application images accept parameters through environment variables and
-generate the final configuration file in the startup script based on these variables.
-This field allows users to specify a list of container names, and KubeBlocks will inject the environment
-variables converted from the ConfigMap into these designated containers. This provides a flexible way to
-pass the configuration items from the ConfigMap to the container without modifying the image.
-Deprecated: asEnvFrom has been deprecated since 0.9.0 and will be removed in 0.10.0.
-Use injectEnvTo instead.
- |
-
-
-
-injectEnvTo
-
-[]string
-
- |
-
-(Optional)
- Specifies the containers to inject the ConfigMap parameters as environment variables.
-This is useful when application images accept parameters through environment variables and
-generate the final configuration file in the startup script based on these variables.
-This field allows users to specify a list of container names, and KubeBlocks will inject the environment
-variables converted from the ConfigMap into these designated containers. This provides a flexible way to
-pass the configuration items from the ConfigMap to the container without modifying the image.
- |
-
-
-
-reRenderResourceTypes
-
-
-[]RerenderResourceType
-
-
- |
-
-(Optional)
- Specifies whether the configuration needs to be re-rendered after v-scale or h-scale operations to reflect changes.
-In some scenarios, the configuration may need to be updated to reflect the changes in resource allocation
-or cluster topology. Examples:
-
-- Redis: adjust maxmemory after v-scale operation.
-- MySQL: increase max connections after v-scale operation.
-- Zookeeper: update zoo.cfg with new node addresses after h-scale operation.
-
- |
-
-
-
-asSecret
-
-bool
-
- |
-
-(Optional)
- Whether to store the final rendered parameters as a secret.
- |
-
-
-
ComponentDefinitionSpec
@@ -5555,7 +5440,7 @@ and other administrative tasks.
ComponentParameters
(map[string]*string
alias)
-(Appears on:ClusterComponentSpec)
+(Appears on:ClusterComponentSpec, ComponentSpec)
@@ -6083,6 +5968,20 @@ bool
If set, all the computing resources will be released.
+
+
+initParameters
+
+
+ComponentParameters
+
+
+ |
+
+(Optional)
+ Specifies the initialization parameters.
+ |
+
ComponentStatus
@@ -6231,7 +6130,7 @@ ProvisionSecretRef
ComponentTemplateSpec
-(Appears on:ComponentConfigSpec, ComponentDefinitionSpec)
+(Appears on:ComponentDefinitionSpec)
@@ -8576,9 +8475,6 @@ int32
RerenderResourceType
(string
alias)
-
-(Appears on:ComponentConfigSpec)
-
RerenderResourceType defines the resource requirements for a component.
diff --git a/pkg/configuration/config_manager/builder_test.go b/pkg/configuration/config_manager/builder_test.go
index b5ced7dfb3a..756b505d7bf 100644
--- a/pkg/configuration/config_manager/builder_test.go
+++ b/pkg/configuration/config_manager/builder_test.go
@@ -266,21 +266,6 @@ formatterConfig:
}
})
- It("builds secondary render correctly", func() {
- mockTplScriptCM()
- param := newCMBuildParams(false)
- reloadOptions := newReloadOptions(parametersv1alpha1.TPLScriptType, syncFn(false))
- for i := range param.ConfigSpecsBuildParams {
- buildParam := ¶m.ConfigSpecsBuildParams[i]
- buildParam.ReloadAction = reloadOptions
- buildParam.ReloadType = parametersv1alpha1.TPLScriptType
- }
- Expect(BuildConfigManagerContainerParams(mockK8sCli.Client(), context.TODO(), param, newVolumeMounts())).Should(Succeed())
- for _, buildParam := range param.ConfigSpecsBuildParams {
- Expect(FindVolumeMount(param.Volumes, GetConfigVolumeName(buildParam.ConfigSpec))).ShouldNot(BeNil())
- }
- })
-
It("builds downwardAPI correctly", func() {
mockTplScriptCM()
param := newCMBuildParams(false)
diff --git a/pkg/configuration/config_manager/config_handler.go b/pkg/configuration/config_manager/config_handler.go
index 39c808684a3..07456085899 100644
--- a/pkg/configuration/config_manager/config_handler.go
+++ b/pkg/configuration/config_manager/config_handler.go
@@ -596,7 +596,7 @@ func CreateCombinedHandler(config string, backupPath string) (ConfigHandler, err
return nil, err
}
hkey := configMeta.ConfigSpec.Name
- if configMeta.ConfigFile == "" {
+ if configMeta.ConfigFile != "" {
hkey = hkey + "/" + configMeta.ConfigFile
}
mHandler.handlers[hkey] = h
diff --git a/pkg/configuration/config_manager/handler_util_test.go b/pkg/configuration/config_manager/handler_util_test.go
index 677854e1671..9db9a416187 100644
--- a/pkg/configuration/config_manager/handler_util_test.go
+++ b/pkg/configuration/config_manager/handler_util_test.go
@@ -19,568 +19,556 @@ along with this program. If not, see .
package configmanager
-// import (
-// "context"
-// "strings"
-// "testing"
-//
-// . "github.com/onsi/ginkgo/v2"
-// . "github.com/onsi/gomega"
-//
-// "github.com/stretchr/testify/assert"
-// corev1 "k8s.io/api/core/v1"
-// metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-// "sigs.k8s.io/controller-runtime/pkg/client"
-//
-// appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1"
-// appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1"
-// cfgcore "github.com/apecloud/kubeblocks/pkg/configuration/core"
-// cfgutil "github.com/apecloud/kubeblocks/pkg/configuration/util"
-// testutil "github.com/apecloud/kubeblocks/pkg/testutil/k8s"
-// )
-//
-// func TestIsSupportReload(t *testing.T) {
-// type args struct {
-// reload *appsv1beta1.ReloadAction
-// }
-// tests := []struct {
-// name string
-// args args
-// want bool
-// }{{
-// name: "reload_test_with_nil_reload_options",
-// args: args{
-// reload: nil,
-// },
-// want: false,
-// }, {
-// name: "reload_test_with_empty_reload_options",
-// args: args{
-// reload: &appsv1beta1.ReloadAction{},
-// },
-// want: false,
-// }, {
-// name: "reload_test_with_unix_signal",
-// args: args{
-// reload: &appsv1beta1.ReloadAction{
-// UnixSignalTrigger: &appsv1beta1.UnixSignalTrigger{
-// ProcessName: "test",
-// Signal: appsv1beta1.SIGHUP,
-// },
-// },
-// },
-// want: true,
-// }, {
-// name: "reload_test_with_shell",
-// args: args{
-// reload: &appsv1beta1.ReloadAction{
-// ShellTrigger: &appsv1beta1.ShellTrigger{
-// Command: strings.Fields("pg_ctl reload"),
-// },
-// },
-// },
-// want: true,
-// }, {
-// name: "reload_test_with_tpl_script",
-// args: args{
-// reload: &appsv1beta1.ReloadAction{
-// TPLScriptTrigger: &appsv1beta1.TPLScriptTrigger{
-// ScriptConfig: appsv1beta1.ScriptConfig{
-// ScriptConfigMapRef: "cm",
-// Namespace: "default",
-// },
-// },
-// },
-// },
-// want: true,
-// }, {
-// name: "auto_trigger_reload_test_with_process_name",
-// args: args{
-// reload: &appsv1beta1.ReloadAction{
-// AutoTrigger: &appsv1beta1.AutoTrigger{
-// ProcessName: "test",
-// },
-// },
-// },
-// want: true,
-// }, {
-// name: "auto_trigger_reload_test",
-// args: args{
-// reload: &appsv1beta1.ReloadAction{
-// AutoTrigger: &appsv1beta1.AutoTrigger{},
-// },
-// },
-// want: true,
-// }}
-// for _, tt := range tests {
-// t.Run(tt.name, func(t *testing.T) {
-// if got := IsSupportReload(tt.args.reload); got != tt.want {
-// t.Errorf("IsSupportReload() = %v, want %v", got, tt.want)
-// }
-// })
-// }
-// }
-//
-// var _ = Describe("Handler Util Test", func() {
-//
-// var mockK8sCli *testutil.K8sClientMockHelper
-//
-// BeforeEach(func() {
-// // Add any setup steps that needs to be executed before each test
-// mockK8sCli = testutil.NewK8sMockClient()
-// })
-//
-// AfterEach(func() {
-// DeferCleanup(mockK8sCli.Finish)
-// })
-//
-// mockConfigConstraint := func(ccName string, reloadOptions *appsv1beta1.ReloadAction) *appsv1beta1.ConfigConstraint {
-// return &appsv1beta1.ConfigConstraint{
-// ObjectMeta: metav1.ObjectMeta{
-// Name: ccName,
-// },
-// Spec: appsv1beta1.ConfigConstraintSpec{
-// ReloadAction: reloadOptions,
-// FileFormatConfig: &appsv1beta1.FileFormatConfig{
-// Format: appsv1beta1.Properties,
-// },
-// }}
-// }
-//
-// mockConfigSpec := func(ccName string) appsv1.ComponentTemplateSpec {
-// return appsv1.ComponentTemplateSpec{
-// Name: "test",
-// TemplateRef: "config_template",
-// Namespace: "default",
-// VolumeName: "for_test",
-// }
-// }
-//
-// Context("TestValidateReloadOptions", func() {
-// It("Should succeed with no error", func() {
-// mockK8sCli.MockGetMethod(
-// testutil.WithFailed(cfgcore.MakeError("failed to get resource."), testutil.WithTimes(1)),
-// testutil.WithSucceed(testutil.WithTimes(1)),
-// )
-//
-// type args struct {
-// reloadAction *appsv1beta1.ReloadAction
-// cli client.Client
-// ctx context.Context
-// }
-// tests := []struct {
-// name string
-// args args
-// wantErr bool
-// }{{
-// name: "unixSignalTest",
-// args: args{
-// reloadAction: &appsv1beta1.ReloadAction{
-// UnixSignalTrigger: &appsv1beta1.UnixSignalTrigger{
-// Signal: appsv1beta1.SIGHUP,
-// }},
-// },
-// wantErr: false,
-// }, {
-// name: "unixSignalTest",
-// args: args{
-// reloadAction: &appsv1beta1.ReloadAction{
-// UnixSignalTrigger: &appsv1beta1.UnixSignalTrigger{
-// Signal: "SIGNOEXIST",
-// }},
-// },
-// wantErr: true,
-// }, {
-// name: "shellTest",
-// args: args{
-// reloadAction: &appsv1beta1.ReloadAction{
-// ShellTrigger: &appsv1beta1.ShellTrigger{
-// Command: nil,
-// }},
-// },
-// wantErr: true,
-// }, {
-// name: "shellTest",
-// args: args{
-// reloadAction: &appsv1beta1.ReloadAction{
-// ShellTrigger: &appsv1beta1.ShellTrigger{
-// Command: strings.Fields("go"),
-// }},
-// },
-// wantErr: false,
-// }, {
-// name: "TPLScriptTest",
-// args: args{
-// reloadAction: &appsv1beta1.ReloadAction{
-// TPLScriptTrigger: &appsv1beta1.TPLScriptTrigger{
-// ScriptConfig: appsv1beta1.ScriptConfig{
-// ScriptConfigMapRef: "test",
-// },
-// }},
-// cli: mockK8sCli.Client(),
-// ctx: context.TODO(),
-// },
-// wantErr: true,
-// }, {
-// name: "TPLScriptTest",
-// args: args{
-// reloadAction: &appsv1beta1.ReloadAction{
-// TPLScriptTrigger: &appsv1beta1.TPLScriptTrigger{
-// ScriptConfig: appsv1beta1.ScriptConfig{
-// ScriptConfigMapRef: "test",
-// },
-// }},
-// cli: mockK8sCli.Client(),
-// ctx: context.TODO(),
-// },
-// wantErr: false,
-// }, {
-// name: "autoTriggerTest",
-// args: args{
-// reloadAction: &appsv1beta1.ReloadAction{
-// AutoTrigger: &appsv1beta1.AutoTrigger{
-// ProcessName: "test",
-// }},
-// },
-// wantErr: false,
-// }, {
-// name: "autoTriggerTest",
-// args: args{
-// reloadAction: &appsv1beta1.ReloadAction{
-// AutoTrigger: &appsv1beta1.AutoTrigger{}},
-// },
-// wantErr: false,
-// }}
-// for _, tt := range tests {
-// By(tt.name)
-// err := ValidateReloadOptions(tt.args.reloadAction, tt.args.cli, tt.args.ctx)
-// Expect(err != nil).Should(BeEquivalentTo(tt.wantErr))
-// }
-// })
-// })
-//
-// Context("TestGetSupportReloadConfigSpecs", func() {
-// It("not support reload", func() {
-// configSpecs, err := GetSupportReloadConfigSpecs([]appsv1.ComponentTemplateSpec{{
-// Name: "test",
-// }}, nil, nil)
-// Expect(err).Should(Succeed())
-// Expect(len(configSpecs)).Should(BeEquivalentTo(0))
-// })
-//
-// It("not ConfigConstraint ", func() {
-// configSpecs, err := GetSupportReloadConfigSpecs([]appsv1.ComponentTemplateSpec{{
-// Name: "test",
-// TemplateRef: "config_template",
-// Namespace: "default",
-// }}, nil, nil)
-// Expect(err).Should(Succeed())
-// Expect(len(configSpecs)).Should(BeEquivalentTo(0))
-// })
-//
-// It("not support reload", func() {
-// ccName := "config_constraint"
-// mockK8sCli.MockGetMethod(testutil.WithGetReturned(testutil.WithConstructSimpleGetResult([]client.Object{
-// mockConfigConstraint(ccName, nil),
-// }), testutil.WithTimes(1)))
-//
-// configSpecs, err := GetSupportReloadConfigSpecs(
-// []appsv1.ComponentTemplateSpec{mockConfigSpec(ccName)},
-// mockK8sCli.Client(), ctx)
-//
-// Expect(err).Should(Succeed())
-// Expect(len(configSpecs)).Should(BeEquivalentTo(0))
-// })
-//
-// It("normal test", func() {
-// ccName := "config_constraint"
-// cc := mockConfigConstraint(ccName, &appsv1beta1.ReloadAction{
-// UnixSignalTrigger: &appsv1beta1.UnixSignalTrigger{
-// ProcessName: "test",
-// Signal: appsv1beta1.SIGHUP,
-// },
-// })
-// mockK8sCli.MockGetMethod(testutil.WithGetReturned(
-// testutil.WithConstructSimpleGetResult([]client.Object{cc}),
-// testutil.WithTimes(1)))
-//
-// configSpecs, err := GetSupportReloadConfigSpecs(
-// []appsv1.ComponentConfigSpec{mockConfigSpec(ccName)},
-// mockK8sCli.Client(), ctx)
-//
-// Expect(err).Should(Succeed())
-// Expect(len(configSpecs)).Should(BeEquivalentTo(1))
-// Expect(configSpecs[0].ConfigSpec).Should(BeEquivalentTo(mockConfigSpec(ccName)))
-// Expect(configSpecs[0].ReloadType).Should(BeEquivalentTo(appsv1beta1.UnixSignalType))
-// Expect(configSpecs[0].FormatterConfig).Should(BeEquivalentTo(*cc.Spec.FileFormatConfig))
-// })
-//
-// It("auto trigger test", func() {
-// ccName := "auto_trigger_config_constraint"
-// cc := mockConfigConstraint(ccName, &appsv1beta1.ReloadAction{
-// AutoTrigger: &appsv1beta1.AutoTrigger{
-// ProcessName: "test",
-// },
-// })
-// mockK8sCli.MockGetMethod(testutil.WithGetReturned(
-// testutil.WithConstructSimpleGetResult([]client.Object{cc}),
-// testutil.WithTimes(1)))
-//
-// configSpecs, err := GetSupportReloadConfigSpecs(
-// []appsv1.ComponentConfigSpec{mockConfigSpec(ccName)},
-// mockK8sCli.Client(), ctx)
-//
-// Expect(err).Should(Succeed())
-// Expect(len(configSpecs)).Should(BeEquivalentTo(0))
-// })
-// })
-//
-// Context("TestFromReloadTypeConfig", func() {
-// It("TestSignalTrigger", func() {
-// Expect(appsv1beta1.UnixSignalType).Should(BeEquivalentTo(FromReloadTypeConfig(&appsv1beta1.ReloadAction{
-// UnixSignalTrigger: &appsv1beta1.UnixSignalTrigger{
-// ProcessName: "test",
-// Signal: appsv1beta1.SIGHUP,
-// }})))
-// })
-//
-// It("TestAutoTrigger", func() {
-// Expect(appsv1beta1.AutoType).Should(BeEquivalentTo(FromReloadTypeConfig(&appsv1beta1.ReloadAction{
-// AutoTrigger: &appsv1beta1.AutoTrigger{
-// ProcessName: "test",
-// }})))
-// })
-//
-// It("TestShellTrigger", func() {
-// Expect(appsv1beta1.ShellType).Should(BeEquivalentTo(FromReloadTypeConfig(&appsv1beta1.ReloadAction{
-// ShellTrigger: &appsv1beta1.ShellTrigger{
-// Command: []string{"/bin/true"},
-// }})))
-// })
-//
-// It("TestTplScriptsTrigger", func() {
-// Expect(appsv1beta1.TPLScriptType).Should(BeEquivalentTo(FromReloadTypeConfig(&appsv1beta1.ReloadAction{
-// TPLScriptTrigger: &appsv1beta1.TPLScriptTrigger{
-// ScriptConfig: appsv1beta1.ScriptConfig{
-// ScriptConfigMapRef: "test",
-// Namespace: "default",
-// },
-// }})))
-// })
-//
-// It("TestInvalidTrigger", func() {
-// Expect("").Should(BeEquivalentTo(FromReloadTypeConfig(&appsv1beta1.ReloadAction{})))
-// })
-// })
-//
-// Context("TestValidateReloadOptions", func() {
-// It("TestSignalTrigger", func() {
-// Expect(ValidateReloadOptions(&appsv1beta1.ReloadAction{
-// UnixSignalTrigger: &appsv1beta1.UnixSignalTrigger{
-// ProcessName: "test",
-// Signal: appsv1beta1.SIGHUP,
-// }}, nil, nil),
-// ).Should(Succeed())
-// })
-//
-// It("TestSignalTrigger", func() {
-// Expect(ValidateReloadOptions(&appsv1beta1.ReloadAction{
-// AutoTrigger: &appsv1beta1.AutoTrigger{
-// ProcessName: "test",
-// }}, nil, nil),
-// ).Should(Succeed())
-// })
-//
-// It("TestShellTrigger", func() {
-// Expect(ValidateReloadOptions(&appsv1beta1.ReloadAction{
-// ShellTrigger: &appsv1beta1.ShellTrigger{
-// Command: []string{"/bin/true"},
-// }}, nil, nil),
-// ).Should(Succeed())
-// })
-//
-// It("TestTplScriptsTrigger", func() {
-// ns := "default"
-// testName1 := "test1"
-// testName2 := "not_test1"
-// mockK8sCli.MockGetMethod(testutil.WithGetReturned(testutil.WithConstructSimpleGetResult([]client.Object{
-// &corev1.ConfigMap{
-// ObjectMeta: metav1.ObjectMeta{
-// Name: testName1,
-// Namespace: ns,
-// },
-// },
-// }), testutil.WithTimes(2)))
-//
-// By("Test valid")
-// Expect(ValidateReloadOptions(&appsv1beta1.ReloadAction{
-// TPLScriptTrigger: &appsv1beta1.TPLScriptTrigger{
-// ScriptConfig: appsv1beta1.ScriptConfig{
-// ScriptConfigMapRef: testName1,
-// Namespace: ns,
-// },
-// }}, mockK8sCli.Client(), ctx),
-// ).Should(Succeed())
-//
-// By("Test invalid")
-// Expect(ValidateReloadOptions(&appsv1beta1.ReloadAction{
-// TPLScriptTrigger: &appsv1beta1.TPLScriptTrigger{
-// ScriptConfig: appsv1beta1.ScriptConfig{
-// ScriptConfigMapRef: testName2,
-// Namespace: ns,
-// },
-// }}, mockK8sCli.Client(), ctx),
-// ).ShouldNot(Succeed())
-// })
-//
-// It("TestInvalidTrigger", func() {
-// Expect(ValidateReloadOptions(&appsv1beta1.ReloadAction{}, nil, nil)).ShouldNot(Succeed())
-// })
-// })
-// })
-//
-// func TestFilterSubPathVolumeMount(t *testing.T) {
-// createConfigMeta := func(volumeName string, reloadType appsv1beta1.DynamicReloadType, reloadAction *appsv1beta1.ReloadAction) ConfigSpecMeta {
-// return ConfigSpecMeta{ConfigSpecInfo: ConfigSpecInfo{
-// ReloadAction: reloadAction,
-// ReloadType: reloadType,
-// ConfigSpec: appsv1.ComponentConfigSpec{
-// ComponentTemplateSpec: appsv1.ComponentTemplateSpec{
-// VolumeName: volumeName,
-// }}}}
-// }
-//
-// type args struct {
-// metas []ConfigSpecMeta
-// volumes []corev1.VolumeMount
-// }
-// tests := []struct {
-// name string
-// args args
-// want []ConfigSpecMeta
-// }{{
-// name: "test1",
-// args: args{
-// metas: []ConfigSpecMeta{
-// createConfigMeta("test1", appsv1beta1.UnixSignalType, &appsv1beta1.ReloadAction{
-// UnixSignalTrigger: &appsv1beta1.UnixSignalTrigger{},
-// }),
-// createConfigMeta("test2", appsv1beta1.ShellType, &appsv1beta1.ReloadAction{
-// ShellTrigger: &appsv1beta1.ShellTrigger{
-// Sync: cfgutil.ToPointer(true),
-// },
-// }),
-// createConfigMeta("test3", appsv1beta1.TPLScriptType, &appsv1beta1.ReloadAction{
-// TPLScriptTrigger: &appsv1beta1.TPLScriptTrigger{
-// Sync: cfgutil.ToPointer(true),
-// },
-// }),
-// },
-// volumes: []corev1.VolumeMount{
-// {Name: "test1", SubPath: "test1"},
-// {Name: "test2", SubPath: "test2"},
-// {Name: "test3", SubPath: "test3"},
-// },
-// },
-// want: []ConfigSpecMeta{
-// createConfigMeta("test2", appsv1beta1.ShellType, &appsv1beta1.ReloadAction{
-// ShellTrigger: &appsv1beta1.ShellTrigger{
-// Sync: cfgutil.ToPointer(true),
-// },
-// }),
-// createConfigMeta("test3", appsv1beta1.TPLScriptType, &appsv1beta1.ReloadAction{
-// TPLScriptTrigger: &appsv1beta1.TPLScriptTrigger{
-// Sync: cfgutil.ToPointer(true),
-// },
-// }),
-// },
-// }, {
-// name: "test2",
-// args: args{
-// metas: []ConfigSpecMeta{
-// createConfigMeta("test1", appsv1beta1.UnixSignalType, &appsv1beta1.ReloadAction{
-// UnixSignalTrigger: &appsv1beta1.UnixSignalTrigger{},
-// }),
-// createConfigMeta("test2", appsv1beta1.ShellType, &appsv1beta1.ReloadAction{
-// ShellTrigger: &appsv1beta1.ShellTrigger{},
-// }),
-// createConfigMeta("test3", appsv1beta1.TPLScriptType, &appsv1beta1.ReloadAction{
-// TPLScriptTrigger: &appsv1beta1.TPLScriptTrigger{},
-// }),
-// },
-// volumes: []corev1.VolumeMount{
-// {Name: "test1"},
-// {Name: "test2"},
-// {Name: "test3"},
-// },
-// },
-// want: []ConfigSpecMeta{
-// createConfigMeta("test1", appsv1beta1.UnixSignalType, &appsv1beta1.ReloadAction{
-// UnixSignalTrigger: &appsv1beta1.UnixSignalTrigger{},
-// }),
-// createConfigMeta("test2", appsv1beta1.ShellType, &appsv1beta1.ReloadAction{
-// ShellTrigger: &appsv1beta1.ShellTrigger{},
-// }),
-// createConfigMeta("test3", appsv1beta1.TPLScriptType, &appsv1beta1.ReloadAction{
-// TPLScriptTrigger: &appsv1beta1.TPLScriptTrigger{},
-// }),
-// },
-// }, {
-// name: "test3",
-// args: args{
-// metas: []ConfigSpecMeta{
-// createConfigMeta("test1", appsv1beta1.UnixSignalType, &appsv1beta1.ReloadAction{
-// UnixSignalTrigger: &appsv1beta1.UnixSignalTrigger{},
-// }),
-// createConfigMeta("test2", appsv1beta1.ShellType, &appsv1beta1.ReloadAction{
-// ShellTrigger: &appsv1beta1.ShellTrigger{},
-// }),
-// createConfigMeta("test3", appsv1beta1.TPLScriptType, &appsv1beta1.ReloadAction{
-// TPLScriptTrigger: &appsv1beta1.TPLScriptTrigger{},
-// }),
-// },
-// volumes: []corev1.VolumeMount{},
-// },
-// want: []ConfigSpecMeta{
-// createConfigMeta("test1", appsv1beta1.UnixSignalType, &appsv1beta1.ReloadAction{
-// UnixSignalTrigger: &appsv1beta1.UnixSignalTrigger{},
-// }),
-// createConfigMeta("test2", appsv1beta1.ShellType, &appsv1beta1.ReloadAction{
-// ShellTrigger: &appsv1beta1.ShellTrigger{},
-// }),
-// createConfigMeta("test3", appsv1beta1.TPLScriptType, &appsv1beta1.ReloadAction{
-// TPLScriptTrigger: &appsv1beta1.TPLScriptTrigger{},
-// }),
-// },
-// }, {
-// name: "test4",
-// args: args{
-// metas: []ConfigSpecMeta{
-// createConfigMeta("test1", appsv1beta1.UnixSignalType, &appsv1beta1.ReloadAction{
-// UnixSignalTrigger: &appsv1beta1.UnixSignalTrigger{},
-// }),
-// createConfigMeta("test2", appsv1beta1.ShellType, &appsv1beta1.ReloadAction{
-// ShellTrigger: &appsv1beta1.ShellTrigger{
-// Sync: cfgutil.ToPointer(false),
-// },
-// }),
-// createConfigMeta("test3", appsv1beta1.TPLScriptType, &appsv1beta1.ReloadAction{
-// TPLScriptTrigger: &appsv1beta1.TPLScriptTrigger{
-// Sync: cfgutil.ToPointer(false),
-// },
-// }),
-// },
-// volumes: []corev1.VolumeMount{
-// {Name: "test1", SubPath: "test1"},
-// {Name: "test2", SubPath: "test2"},
-// {Name: "test3", SubPath: "test3"},
-// },
-// },
-// want: nil,
-// }}
-// for _, tt := range tests {
-// t.Run(tt.name, func(t *testing.T) {
-// assert.Equalf(t, tt.want, FilterSupportReloadActionConfigSpecs(tt.args.metas, tt.args.volumes), "FilterSupportReloadActionConfigSpecs(%v, %v)", tt.args.metas, tt.args.volumes)
-// })
-// }
-// }
+import (
+ "context"
+ "strings"
+ "testing"
+
+ . "github.com/onsi/ginkgo/v2"
+ . "github.com/onsi/gomega"
+
+ "github.com/stretchr/testify/assert"
+ corev1 "k8s.io/api/core/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+
+ appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1"
+ parametersv1alpha1 "github.com/apecloud/kubeblocks/apis/parameters/v1alpha1"
+ cfgcore "github.com/apecloud/kubeblocks/pkg/configuration/core"
+ cfgutil "github.com/apecloud/kubeblocks/pkg/configuration/util"
+ testutil "github.com/apecloud/kubeblocks/pkg/testutil/k8s"
+)
+
+func TestIsSupportReload(t *testing.T) {
+ type args struct {
+ reload *parametersv1alpha1.ReloadAction
+ }
+ tests := []struct {
+ name string
+ args args
+ want bool
+ }{{
+ name: "reload_test_with_nil_reload_options",
+ args: args{
+ reload: nil,
+ },
+ want: false,
+ }, {
+ name: "reload_test_with_empty_reload_options",
+ args: args{
+ reload: ¶metersv1alpha1.ReloadAction{},
+ },
+ want: false,
+ }, {
+ name: "reload_test_with_unix_signal",
+ args: args{
+ reload: ¶metersv1alpha1.ReloadAction{
+ UnixSignalTrigger: ¶metersv1alpha1.UnixSignalTrigger{
+ ProcessName: "test",
+ Signal: parametersv1alpha1.SIGHUP,
+ },
+ },
+ },
+ want: true,
+ }, {
+ name: "reload_test_with_shell",
+ args: args{
+ reload: ¶metersv1alpha1.ReloadAction{
+ ShellTrigger: ¶metersv1alpha1.ShellTrigger{
+ Command: strings.Fields("pg_ctl reload"),
+ },
+ },
+ },
+ want: true,
+ }, {
+ name: "reload_test_with_tpl_script",
+ args: args{
+ reload: ¶metersv1alpha1.ReloadAction{
+ TPLScriptTrigger: ¶metersv1alpha1.TPLScriptTrigger{
+ ScriptConfig: parametersv1alpha1.ScriptConfig{
+ ScriptConfigMapRef: "cm",
+ Namespace: "default",
+ },
+ },
+ },
+ },
+ want: true,
+ }, {
+ name: "auto_trigger_reload_test_with_process_name",
+ args: args{
+ reload: ¶metersv1alpha1.ReloadAction{
+ AutoTrigger: ¶metersv1alpha1.AutoTrigger{
+ ProcessName: "test",
+ },
+ },
+ },
+ want: true,
+ }, {
+ name: "auto_trigger_reload_test",
+ args: args{
+ reload: ¶metersv1alpha1.ReloadAction{
+ AutoTrigger: ¶metersv1alpha1.AutoTrigger{},
+ },
+ },
+ want: true,
+ }}
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ if got := IsSupportReload(tt.args.reload); got != tt.want {
+ t.Errorf("IsSupportReload() = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}
+
+var _ = Describe("Handler Util Test", func() {
+
+ var mockK8sCli *testutil.K8sClientMockHelper
+
+ BeforeEach(func() {
+ // Add any setup steps that needs to be executed before each test
+ mockK8sCli = testutil.NewK8sMockClient()
+ })
+
+ AfterEach(func() {
+ DeferCleanup(mockK8sCli.Finish)
+ })
+
+ mockParametersDef := func(ccName string, reloadOptions *parametersv1alpha1.ReloadAction) *parametersv1alpha1.ParametersDefinition {
+ return ¶metersv1alpha1.ParametersDefinition{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: ccName,
+ },
+ Spec: parametersv1alpha1.ParametersDefinitionSpec{
+ FileName: "test",
+ ReloadAction: reloadOptions,
+ }}
+ }
+ mockConfigDescription := func(tplName string, format parametersv1alpha1.CfgFileFormat) []parametersv1alpha1.ComponentConfigDescription {
+ return []parametersv1alpha1.ComponentConfigDescription{
+ {
+ Name: "test",
+ TemplateName: tplName,
+ FileFormatConfig: ¶metersv1alpha1.FileFormatConfig{
+ Format: format,
+ },
+ },
+ }
+ }
+
+ mockConfigSpec := func(tplName string) appsv1.ComponentTemplateSpec {
+ return appsv1.ComponentTemplateSpec{
+ Name: tplName,
+ TemplateRef: "config_template",
+ Namespace: "default",
+ VolumeName: "for_test",
+ }
+ }
+
+ Context("TestValidateReloadOptions", func() {
+ It("Should succeed with no error", func() {
+ mockK8sCli.MockGetMethod(
+ testutil.WithFailed(cfgcore.MakeError("failed to get resource."), testutil.WithTimes(1)),
+ testutil.WithSucceed(testutil.WithTimes(1)),
+ )
+
+ type args struct {
+ reloadAction *parametersv1alpha1.ReloadAction
+ cli client.Client
+ ctx context.Context
+ }
+ tests := []struct {
+ name string
+ args args
+ wantErr bool
+ }{{
+ name: "unixSignalTest",
+ args: args{
+ reloadAction: ¶metersv1alpha1.ReloadAction{
+ UnixSignalTrigger: ¶metersv1alpha1.UnixSignalTrigger{
+ Signal: parametersv1alpha1.SIGHUP,
+ }},
+ },
+ wantErr: false,
+ }, {
+ name: "unixSignalTest",
+ args: args{
+ reloadAction: ¶metersv1alpha1.ReloadAction{
+ UnixSignalTrigger: ¶metersv1alpha1.UnixSignalTrigger{
+ Signal: "SIGNOEXIST",
+ }},
+ },
+ wantErr: true,
+ }, {
+ name: "shellTest",
+ args: args{
+ reloadAction: ¶metersv1alpha1.ReloadAction{
+ ShellTrigger: ¶metersv1alpha1.ShellTrigger{
+ Command: nil,
+ }},
+ },
+ wantErr: true,
+ }, {
+ name: "shellTest",
+ args: args{
+ reloadAction: ¶metersv1alpha1.ReloadAction{
+ ShellTrigger: ¶metersv1alpha1.ShellTrigger{
+ Command: strings.Fields("go"),
+ }},
+ },
+ wantErr: false,
+ }, {
+ name: "TPLScriptTest",
+ args: args{
+ reloadAction: ¶metersv1alpha1.ReloadAction{
+ TPLScriptTrigger: ¶metersv1alpha1.TPLScriptTrigger{
+ ScriptConfig: parametersv1alpha1.ScriptConfig{
+ ScriptConfigMapRef: "test",
+ },
+ }},
+ cli: mockK8sCli.Client(),
+ ctx: context.TODO(),
+ },
+ wantErr: true,
+ }, {
+ name: "TPLScriptTest",
+ args: args{
+ reloadAction: ¶metersv1alpha1.ReloadAction{
+ TPLScriptTrigger: ¶metersv1alpha1.TPLScriptTrigger{
+ ScriptConfig: parametersv1alpha1.ScriptConfig{
+ ScriptConfigMapRef: "test",
+ },
+ }},
+ cli: mockK8sCli.Client(),
+ ctx: context.TODO(),
+ },
+ wantErr: false,
+ }, {
+ name: "autoTriggerTest",
+ args: args{
+ reloadAction: ¶metersv1alpha1.ReloadAction{
+ AutoTrigger: ¶metersv1alpha1.AutoTrigger{
+ ProcessName: "test",
+ }},
+ },
+ wantErr: false,
+ }, {
+ name: "autoTriggerTest",
+ args: args{
+ reloadAction: ¶metersv1alpha1.ReloadAction{
+ AutoTrigger: ¶metersv1alpha1.AutoTrigger{}},
+ },
+ wantErr: false,
+ }}
+ for _, tt := range tests {
+ By(tt.name)
+ err := ValidateReloadOptions(tt.args.reloadAction, tt.args.cli, tt.args.ctx)
+ Expect(err != nil).Should(BeEquivalentTo(tt.wantErr))
+ }
+ })
+ })
+
+ Context("TestGetSupportReloadConfigSpecs", func() {
+ It("not support reload", func() {
+ configSpecs, err := GetSupportReloadConfigSpecs([]appsv1.ComponentTemplateSpec{{
+ Name: "test",
+ }}, nil, nil)
+ Expect(err).Should(Succeed())
+ Expect(len(configSpecs)).Should(BeEquivalentTo(0))
+ })
+
+ It("not ComponentConfigDescription", func() {
+ configSpecs, err := GetSupportReloadConfigSpecs([]appsv1.ComponentTemplateSpec{{
+ Name: "test",
+ TemplateRef: "config_template",
+ Namespace: "default",
+ }}, nil, []*parametersv1alpha1.ParametersDefinition{mockParametersDef("test", nil)})
+ Expect(err).Should(Succeed())
+ Expect(len(configSpecs)).Should(BeEquivalentTo(0))
+ })
+
+ It("not support reload for paramsDef", func() {
+ ccName := "config_constraint"
+ configtpl := mockConfigSpec(ccName)
+ configSpecs, err := GetSupportReloadConfigSpecs(
+ []appsv1.ComponentTemplateSpec{configtpl},
+ mockConfigDescription(configtpl.Name, parametersv1alpha1.Ini),
+ nil,
+ )
+
+ Expect(err).Should(Succeed())
+ Expect(len(configSpecs)).Should(BeEquivalentTo(0))
+ })
+
+ It("normal test", func() {
+ ccName := "config_constraint"
+ pd := mockParametersDef(ccName, ¶metersv1alpha1.ReloadAction{
+ UnixSignalTrigger: ¶metersv1alpha1.UnixSignalTrigger{
+ ProcessName: "test",
+ Signal: parametersv1alpha1.SIGHUP,
+ },
+ })
+
+ cd := mockConfigDescription(ccName, parametersv1alpha1.Ini)
+ configSpecs, err := GetSupportReloadConfigSpecs(
+ []appsv1.ComponentTemplateSpec{mockConfigSpec(ccName)},
+ cd,
+ []*parametersv1alpha1.ParametersDefinition{pd},
+ )
+
+ Expect(err).Should(Succeed())
+ Expect(len(configSpecs)).Should(BeEquivalentTo(1))
+ Expect(configSpecs[0].ConfigSpec).Should(BeEquivalentTo(mockConfigSpec(ccName)))
+ Expect(configSpecs[0].ReloadType).Should(BeEquivalentTo(parametersv1alpha1.UnixSignalType))
+ Expect(&configSpecs[0].FormatterConfig).Should(BeEquivalentTo(cd[0].FileFormatConfig))
+ })
+ })
+
+ Context("TestFromReloadTypeConfig", func() {
+ It("TestSignalTrigger", func() {
+ Expect(parametersv1alpha1.UnixSignalType).Should(BeEquivalentTo(FromReloadTypeConfig(¶metersv1alpha1.ReloadAction{
+ UnixSignalTrigger: ¶metersv1alpha1.UnixSignalTrigger{
+ ProcessName: "test",
+ Signal: parametersv1alpha1.SIGHUP,
+ }})))
+ })
+
+ It("TestAutoTrigger", func() {
+ Expect(parametersv1alpha1.AutoType).Should(BeEquivalentTo(FromReloadTypeConfig(¶metersv1alpha1.ReloadAction{
+ AutoTrigger: ¶metersv1alpha1.AutoTrigger{
+ ProcessName: "test",
+ }})))
+ })
+
+ It("TestShellTrigger", func() {
+ Expect(parametersv1alpha1.ShellType).Should(BeEquivalentTo(FromReloadTypeConfig(¶metersv1alpha1.ReloadAction{
+ ShellTrigger: ¶metersv1alpha1.ShellTrigger{
+ Command: []string{"/bin/true"},
+ }})))
+ })
+
+ It("TestTplScriptsTrigger", func() {
+ Expect(parametersv1alpha1.TPLScriptType).Should(BeEquivalentTo(FromReloadTypeConfig(¶metersv1alpha1.ReloadAction{
+ TPLScriptTrigger: ¶metersv1alpha1.TPLScriptTrigger{
+ ScriptConfig: parametersv1alpha1.ScriptConfig{
+ ScriptConfigMapRef: "test",
+ Namespace: "default",
+ },
+ }})))
+ })
+
+ It("TestInvalidTrigger", func() {
+ Expect("").Should(BeEquivalentTo(FromReloadTypeConfig(¶metersv1alpha1.ReloadAction{})))
+ })
+ })
+
+ Context("TestValidateReloadOptions", func() {
+ It("TestSignalTrigger", func() {
+ Expect(ValidateReloadOptions(¶metersv1alpha1.ReloadAction{
+ UnixSignalTrigger: ¶metersv1alpha1.UnixSignalTrigger{
+ ProcessName: "test",
+ Signal: parametersv1alpha1.SIGHUP,
+ }}, nil, nil),
+ ).Should(Succeed())
+ })
+
+ It("TestSignalTrigger", func() {
+ Expect(ValidateReloadOptions(¶metersv1alpha1.ReloadAction{
+ AutoTrigger: ¶metersv1alpha1.AutoTrigger{
+ ProcessName: "test",
+ }}, nil, nil),
+ ).Should(Succeed())
+ })
+
+ It("TestShellTrigger", func() {
+ Expect(ValidateReloadOptions(¶metersv1alpha1.ReloadAction{
+ ShellTrigger: ¶metersv1alpha1.ShellTrigger{
+ Command: []string{"/bin/true"},
+ }}, nil, nil),
+ ).Should(Succeed())
+ })
+
+ It("TestTplScriptsTrigger", func() {
+ ns := "default"
+ testName1 := "test1"
+ testName2 := "not_test1"
+ mockK8sCli.MockGetMethod(testutil.WithGetReturned(testutil.WithConstructSimpleGetResult([]client.Object{
+ &corev1.ConfigMap{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: testName1,
+ Namespace: ns,
+ },
+ },
+ }), testutil.WithTimes(2)))
+
+ By("Test valid")
+ Expect(ValidateReloadOptions(¶metersv1alpha1.ReloadAction{
+ TPLScriptTrigger: ¶metersv1alpha1.TPLScriptTrigger{
+ ScriptConfig: parametersv1alpha1.ScriptConfig{
+ ScriptConfigMapRef: testName1,
+ Namespace: ns,
+ },
+ }}, mockK8sCli.Client(), ctx),
+ ).Should(Succeed())
+
+ By("Test invalid")
+ Expect(ValidateReloadOptions(¶metersv1alpha1.ReloadAction{
+ TPLScriptTrigger: ¶metersv1alpha1.TPLScriptTrigger{
+ ScriptConfig: parametersv1alpha1.ScriptConfig{
+ ScriptConfigMapRef: testName2,
+ Namespace: ns,
+ },
+ }}, mockK8sCli.Client(), ctx),
+ ).ShouldNot(Succeed())
+ })
+
+ It("TestInvalidTrigger", func() {
+ Expect(ValidateReloadOptions(¶metersv1alpha1.ReloadAction{}, nil, nil)).ShouldNot(Succeed())
+ })
+ })
+})
+
+func TestFilterSubPathVolumeMount(t *testing.T) {
+ createConfigMeta := func(volumeName string, reloadType parametersv1alpha1.DynamicReloadType, reloadAction *parametersv1alpha1.ReloadAction) ConfigSpecMeta {
+ return ConfigSpecMeta{ConfigSpecInfo: ConfigSpecInfo{
+ ReloadAction: reloadAction,
+ ReloadType: reloadType,
+ ConfigSpec: appsv1.ComponentTemplateSpec{
+ VolumeName: volumeName,
+ }}}
+ }
+
+ type args struct {
+ metas []ConfigSpecMeta
+ volumes []corev1.VolumeMount
+ }
+ tests := []struct {
+ name string
+ args args
+ want []ConfigSpecMeta
+ }{{
+ name: "test1",
+ args: args{
+ metas: []ConfigSpecMeta{
+ createConfigMeta("test1", parametersv1alpha1.UnixSignalType, ¶metersv1alpha1.ReloadAction{
+ UnixSignalTrigger: ¶metersv1alpha1.UnixSignalTrigger{},
+ }),
+ createConfigMeta("test2", parametersv1alpha1.ShellType, ¶metersv1alpha1.ReloadAction{
+ ShellTrigger: ¶metersv1alpha1.ShellTrigger{
+ Sync: cfgutil.ToPointer(true),
+ },
+ }),
+ createConfigMeta("test3", parametersv1alpha1.TPLScriptType, ¶metersv1alpha1.ReloadAction{
+ TPLScriptTrigger: ¶metersv1alpha1.TPLScriptTrigger{
+ Sync: cfgutil.ToPointer(true),
+ },
+ }),
+ },
+ volumes: []corev1.VolumeMount{
+ {Name: "test1", SubPath: "test1"},
+ {Name: "test2", SubPath: "test2"},
+ {Name: "test3", SubPath: "test3"},
+ },
+ },
+ want: []ConfigSpecMeta{
+ createConfigMeta("test2", parametersv1alpha1.ShellType, ¶metersv1alpha1.ReloadAction{
+ ShellTrigger: ¶metersv1alpha1.ShellTrigger{
+ Sync: cfgutil.ToPointer(true),
+ },
+ }),
+ createConfigMeta("test3", parametersv1alpha1.TPLScriptType, ¶metersv1alpha1.ReloadAction{
+ TPLScriptTrigger: ¶metersv1alpha1.TPLScriptTrigger{
+ Sync: cfgutil.ToPointer(true),
+ },
+ }),
+ },
+ }, {
+ name: "test2",
+ args: args{
+ metas: []ConfigSpecMeta{
+ createConfigMeta("test1", parametersv1alpha1.UnixSignalType, ¶metersv1alpha1.ReloadAction{
+ UnixSignalTrigger: ¶metersv1alpha1.UnixSignalTrigger{},
+ }),
+ createConfigMeta("test2", parametersv1alpha1.ShellType, ¶metersv1alpha1.ReloadAction{
+ ShellTrigger: ¶metersv1alpha1.ShellTrigger{},
+ }),
+ createConfigMeta("test3", parametersv1alpha1.TPLScriptType, ¶metersv1alpha1.ReloadAction{
+ TPLScriptTrigger: ¶metersv1alpha1.TPLScriptTrigger{},
+ }),
+ },
+ volumes: []corev1.VolumeMount{
+ {Name: "test1"},
+ {Name: "test2"},
+ {Name: "test3"},
+ },
+ },
+ want: []ConfigSpecMeta{
+ createConfigMeta("test1", parametersv1alpha1.UnixSignalType, ¶metersv1alpha1.ReloadAction{
+ UnixSignalTrigger: ¶metersv1alpha1.UnixSignalTrigger{},
+ }),
+ createConfigMeta("test2", parametersv1alpha1.ShellType, ¶metersv1alpha1.ReloadAction{
+ ShellTrigger: ¶metersv1alpha1.ShellTrigger{},
+ }),
+ createConfigMeta("test3", parametersv1alpha1.TPLScriptType, ¶metersv1alpha1.ReloadAction{
+ TPLScriptTrigger: ¶metersv1alpha1.TPLScriptTrigger{},
+ }),
+ },
+ }, {
+ name: "test3",
+ args: args{
+ metas: []ConfigSpecMeta{
+ createConfigMeta("test1", parametersv1alpha1.UnixSignalType, ¶metersv1alpha1.ReloadAction{
+ UnixSignalTrigger: ¶metersv1alpha1.UnixSignalTrigger{},
+ }),
+ createConfigMeta("test2", parametersv1alpha1.ShellType, ¶metersv1alpha1.ReloadAction{
+ ShellTrigger: ¶metersv1alpha1.ShellTrigger{},
+ }),
+ createConfigMeta("test3", parametersv1alpha1.TPLScriptType, ¶metersv1alpha1.ReloadAction{
+ TPLScriptTrigger: ¶metersv1alpha1.TPLScriptTrigger{},
+ }),
+ },
+ volumes: []corev1.VolumeMount{},
+ },
+ want: []ConfigSpecMeta{
+ createConfigMeta("test1", parametersv1alpha1.UnixSignalType, ¶metersv1alpha1.ReloadAction{
+ UnixSignalTrigger: ¶metersv1alpha1.UnixSignalTrigger{},
+ }),
+ createConfigMeta("test2", parametersv1alpha1.ShellType, ¶metersv1alpha1.ReloadAction{
+ ShellTrigger: ¶metersv1alpha1.ShellTrigger{},
+ }),
+ createConfigMeta("test3", parametersv1alpha1.TPLScriptType, ¶metersv1alpha1.ReloadAction{
+ TPLScriptTrigger: ¶metersv1alpha1.TPLScriptTrigger{},
+ }),
+ },
+ }, {
+ name: "test4",
+ args: args{
+ metas: []ConfigSpecMeta{
+ createConfigMeta("test1", parametersv1alpha1.UnixSignalType, ¶metersv1alpha1.ReloadAction{
+ UnixSignalTrigger: ¶metersv1alpha1.UnixSignalTrigger{},
+ }),
+ createConfigMeta("test2", parametersv1alpha1.ShellType, ¶metersv1alpha1.ReloadAction{
+ ShellTrigger: ¶metersv1alpha1.ShellTrigger{
+ Sync: cfgutil.ToPointer(false),
+ },
+ }),
+ createConfigMeta("test3", parametersv1alpha1.TPLScriptType, ¶metersv1alpha1.ReloadAction{
+ TPLScriptTrigger: ¶metersv1alpha1.TPLScriptTrigger{
+ Sync: cfgutil.ToPointer(false),
+ },
+ }),
+ },
+ volumes: []corev1.VolumeMount{
+ {Name: "test1", SubPath: "test1"},
+ {Name: "test2", SubPath: "test2"},
+ {Name: "test3", SubPath: "test3"},
+ },
+ },
+ want: nil,
+ }}
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ assert.Equalf(t, tt.want, FilterSupportReloadActionConfigSpecs(tt.args.metas, tt.args.volumes), "FilterSupportReloadActionConfigSpecs(%v, %v)", tt.args.metas, tt.args.volumes)
+ })
+ }
+}
diff --git a/pkg/configuration/core/config_util.go b/pkg/configuration/core/config_util.go
index d4c740e0144..00b8d3c66ff 100644
--- a/pkg/configuration/core/config_util.go
+++ b/pkg/configuration/core/config_util.go
@@ -21,6 +21,7 @@ package core
import (
"context"
+ "path/filepath"
"regexp"
"strings"
@@ -133,7 +134,7 @@ func ToV1ConfigDescription(keys []string, format *parametersv1alpha1.FileFormatC
var configs []parametersv1alpha1.ComponentConfigDescription
for _, key := range keys {
configs = append(configs, parametersv1alpha1.ComponentConfigDescription{
- Name: key,
+ Name: filepath.Base(key),
FileFormatConfig: format,
})
}
diff --git a/pkg/configuration/validate/config_validate.go b/pkg/configuration/validate/config_validate.go
index 6f20aa9a603..6d43cfb800f 100644
--- a/pkg/configuration/validate/config_validate.go
+++ b/pkg/configuration/validate/config_validate.go
@@ -20,7 +20,6 @@ along with this program. If not, see .
package validate
import (
- "github.com/StudioSol/set"
apiext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"k8s.io/kube-openapi/pkg/validation/errors"
kubeopenapispec "k8s.io/kube-openapi/pkg/validation/spec"
@@ -37,35 +36,12 @@ type ConfigValidator interface {
Validate(data string) error
}
-type cmKeySelector struct {
- // A ConfigMap object may contain multiple configuration files and only some of them can be parsed and verified by kubeblocks,
- // such as postgresql, there are two files pg_hba.conf & postgresql.conf in the ConfigMap, and we can only validate postgresql.conf,
- // so pg_hba.conf file needs to be ignored during when doing verification.
- // keySelector filters the keys in the configmap.
- keySelector []ValidatorOptions
-}
-
type configCueValidator struct {
- cmKeySelector
-
// cue describes configuration template
cueScript string
cfgType parametersv1alpha1.CfgFileFormat
}
-func (s *cmKeySelector) filter(key string) bool {
- if len(s.keySelector) == 0 {
- return false
- }
-
- for _, option := range s.keySelector {
- if !option(key) {
- return true
- }
- }
- return false
-}
-
func (c *configCueValidator) Validate(content string) error {
if c.cueScript == "" {
return nil
@@ -74,8 +50,6 @@ func (c *configCueValidator) Validate(content string) error {
}
type schemaValidator struct {
- cmKeySelector
-
typeName string
schema *apiext.JSONSchemaProps
cfgType parametersv1alpha1.CfgFileFormat
@@ -103,16 +77,6 @@ func (e emptyValidator) Validate(_ string) error {
return nil
}
-func WithKeySelector(keys []string) ValidatorOptions {
- var sets *set.LinkedHashSetString
- if len(keys) > 0 {
- sets = core.FromCMKeysSelector(keys)
- }
- return func(key string) bool {
- return sets == nil || sets.InArray(key)
- }
-}
-
func NewConfigValidator(paramsSchema *parametersv1alpha1.ParametersSchema, fileFormat *parametersv1alpha1.FileFormatConfig) ConfigValidator {
if fileFormat == nil {
return &emptyValidator{}
diff --git a/pkg/configuration/validate/config_validate_test.go b/pkg/configuration/validate/config_validate_test.go
index 6058d747d89..81f8ab013a7 100644
--- a/pkg/configuration/validate/config_validate_test.go
+++ b/pkg/configuration/validate/config_validate_test.go
@@ -48,7 +48,6 @@ func TestSchemaValidatorWithCue(t *testing.T) {
cueFile string
configFile string
format parametersv1alpha1.CfgFileFormat
- options []ValidatorOptions
}
tests := []struct {
name string
@@ -112,9 +111,8 @@ mysqld.innodb_autoinc_lock_mode: conflicting values 2 and 100:
name: "configmap_key_filter",
args: args{
cueFile: "cue_testdata/mysql.cue",
- configFile: "cue_testdata/mysql_err.cnf",
+ configFile: "cue_testdata/mysql.cnf",
format: parametersv1alpha1.Ini,
- options: []ValidatorOptions{WithKeySelector([]string{"key2", "key3"})},
},
}}
@@ -127,62 +125,44 @@ mysqld.innodb_autoinc_lock_mode: conflicting values 2 and 100:
}
}
-// func TestSchemaValidatorWithSelector(t *testing.T) {
-// validator := NewConfigValidator(newFakeConfigSchema("cue_testdata/mysql.cue", appsv1beta1.Ini))
-// require.NotNil(t, validator)
-// require.ErrorContains(t, validator.Validate(
-// map[string]string{
-// "normal_key": fromTestData("cue_testdata/mysql.cnf"),
-// "abnormal_key": fromTestData("cue_testdata/mysql_err.cnf"),
-// }), "[mysqld.innodb_autoinc_lock_mode: 3 errors in empty disjunction")
-//
-// validator = NewConfigValidator(newFakeConfigSchema("cue_testdata/mysql.cue", appsv1beta1.Ini), WithKeySelector([]string{}))
-// require.NotNil(t, validator)
-// require.ErrorContains(t, validator.Validate(
-// map[string]string{
-// "normal_key": fromTestData("cue_testdata/mysql.cnf"),
-// "abnormal_key": fromTestData("cue_testdata/mysql_err.cnf"),
-// }), "[mysqld.innodb_autoinc_lock_mode: 3 errors in empty disjunction")
-//
-// validator = NewConfigValidator(newFakeConfigSchema("cue_testdata/mysql.cue", appsv1beta1.Ini), WithKeySelector([]string{"normal_key"}))
-// require.NotNil(t, validator)
-// require.Nil(t, validator.Validate(
-// map[string]string{
-// "normal_key": fromTestData("cue_testdata/mysql.cnf"),
-// "abnormal_key": fromTestData("cue_testdata/mysql_err.cnf"),
-// }))
-// }
+func TestSchemaValidatorWithSelector(t *testing.T) {
+ validator := NewConfigValidator(newFakeConfigSchema("cue_testdata/mysql.cue"), ¶metersv1alpha1.FileFormatConfig{Format: parametersv1alpha1.Ini})
+ require.NotNil(t, validator)
+ require.ErrorContains(t, validator.Validate(
+ fromTestData("cue_testdata/mysql_err.cnf"),
+ ), "[mysqld.innodb_autoinc_lock_mode: 3 errors in empty disjunction")
+}
-// func TestSchemaValidatorWithOpenSchema(t *testing.T) {
-// type args struct {
-// cueFile string
-// configFile string
-// format parametersv1alpha1.CfgFileFormat
-// SchemaTypeName string
-// }
-// tests := []struct {
-// name string
-// args args
-// err error
-// }{{
-// name: "test_wesql",
-// args: args{
-// cueFile: "cue_testdata/mysql.cue",
-// configFile: "cue_testdata/mysql.cnf",
-// format: parametersv1alpha1.Ini,
-// },
-// err: nil,
-// }}
-//
-// for _, tt := range tests {
-// t.Run(tt.name, func(t *testing.T) {
-// tplConstraint := newFakeConfigSchema(tt.args.cueFile)
-// validator := &schemaValidator{
-// typeName: tt.args.SchemaTypeName,
-// cfgType: tt.args.format,
-// schema: tplConstraint.ParametersSchema.SchemaInJSON,
-// }
-// require.Equal(t, tt.err, validator.Validate(fromTestData(tt.args.configFile)))
-// })
-// }
-// }
+func TestSchemaValidatorWithOpenSchema(t *testing.T) {
+ type args struct {
+ cueFile string
+ configFile string
+ format parametersv1alpha1.CfgFileFormat
+ SchemaTypeName string
+ }
+ tests := []struct {
+ name string
+ args args
+ err error
+ }{{
+ name: "test_wesql",
+ args: args{
+ cueFile: "cue_testdata/mysql.cue",
+ configFile: "cue_testdata/mysql.cnf",
+ format: parametersv1alpha1.Ini,
+ },
+ err: nil,
+ }}
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ configSchema := newFakeConfigSchema(tt.args.cueFile)
+ validator := &schemaValidator{
+ typeName: tt.args.SchemaTypeName,
+ cfgType: tt.args.format,
+ schema: configSchema.SchemaInJSON,
+ }
+ require.Equal(t, tt.err, validator.Validate(fromTestData(tt.args.configFile)))
+ })
+ }
+}
diff --git a/pkg/controller/configuration/builtin_env_test.go b/pkg/controller/configuration/builtin_env_test.go
index b1715c0e661..5a29cf3ded4 100644
--- a/pkg/controller/configuration/builtin_env_test.go
+++ b/pkg/controller/configuration/builtin_env_test.go
@@ -19,261 +19,261 @@ along with this program. If not, see .
package configuration
-// import (
-// "fmt"
-// "strconv"
-//
-// . "github.com/onsi/ginkgo/v2"
-// . "github.com/onsi/gomega"
-//
-// corev1 "k8s.io/api/core/v1"
-// "k8s.io/apimachinery/pkg/api/resource"
-// metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-// coreclient "sigs.k8s.io/controller-runtime/pkg/client"
-//
-// appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1"
-// "github.com/apecloud/kubeblocks/pkg/constant"
-// ctrlcomp "github.com/apecloud/kubeblocks/pkg/controller/component"
-// testutil "github.com/apecloud/kubeblocks/pkg/testutil/k8s"
-// )
-//
-// var _ = Describe("tpl env template", func() {
-//
-// patroniTemplate := `
-// bootstrap:
-// initdb:
-// - auth-host: md5
-// - auth-local: trust
-// `
-// const (
-// cmTemplateName = "patroni-template-config"
-// cmConfigFileName = "postgresql.yaml"
-// )
-//
-// var (
-// podSpec *corev1.PodSpec
-// component *ctrlcomp.SynthesizedComponent
-// cluster *appsv1.Cluster
-//
-// mockClient *testutil.K8sClientMockHelper
-// )
-//
-// BeforeEach(func() {
-// mockClient = testutil.NewK8sMockClient()
-//
-// mockClient.MockGetMethod(testutil.WithGetReturned(testutil.WithConstructSimpleGetResult([]coreclient.Object{
-// &corev1.ConfigMap{
-// ObjectMeta: metav1.ObjectMeta{
-// Name: cmTemplateName,
-// Namespace: "default",
-// },
-// Data: map[string]string{
-// cmConfigFileName: patroniTemplate,
-// }},
-// &corev1.ConfigMap{
-// ObjectMeta: metav1.ObjectMeta{
-// Name: "my-config-env",
-// Namespace: "default",
-// },
-// Data: map[string]string{
-// "KB_0_HOSTNAME": "my-mysql-0.my-mysql-headless",
-// "KB_FOLLOWERS": "",
-// "KB_LEADER": "my-mysql-0",
-// "KB_REPLICA_COUNT": "1",
-// "LOOP_REFERENCE_A": "$(LOOP_REFERENCE_B)",
-// "LOOP_REFERENCE_B": "$(LOOP_REFERENCE_C)",
-// "LOOP_REFERENCE_C": "$(LOOP_REFERENCE_A)",
-// }},
-// &corev1.Secret{
-// ObjectMeta: metav1.ObjectMeta{
-// Name: "my-conn-credential",
-// Namespace: "default",
-// },
-// Data: map[string][]byte{
-// "password": []byte("4zrqfl2r"),
-// "username": []byte("root"),
-// }},
-// }), testutil.WithAnyTimes()))
-//
-// // 2 configmap and 2 secret
-// // Add any setup steps that needs to be executed before each test
-// podSpec = &corev1.PodSpec{
-// Containers: []corev1.Container{
-// {
-// Name: "mytest",
-// Env: []corev1.EnvVar{
-// {
-// Name: constant.KBEnvClusterName,
-// Value: "my",
-// },
-// {
-// Name: constant.KBEnvCompName,
-// Value: "mysql",
-// },
-// {
-// Name: "MEMORY_SIZE",
-// ValueFrom: &corev1.EnvVarSource{
-// ResourceFieldRef: &corev1.ResourceFieldSelector{
-// ContainerName: "mytest",
-// Resource: "limits.memory",
-// },
-// },
-// },
-// {
-// Name: "CPU",
-// ValueFrom: &corev1.EnvVarSource{
-// ResourceFieldRef: &corev1.ResourceFieldSelector{
-// Resource: "limits.cpu",
-// },
-// },
-// },
-// {
-// Name: "CPU2",
-// ValueFrom: &corev1.EnvVarSource{
-// ResourceFieldRef: &corev1.ResourceFieldSelector{
-// ContainerName: "not_exist_container",
-// Resource: "limits.memory",
-// },
-// },
-// },
-// {
-// Name: "MYSQL_USER",
-// ValueFrom: &corev1.EnvVarSource{
-// SecretKeyRef: &corev1.SecretKeySelector{
-// LocalObjectReference: corev1.LocalObjectReference{
-// Name: "my-conn-credential",
-// },
-// Key: "username",
-// },
-// },
-// },
-// {
-// Name: "MYSQL_PASSWORD",
-// ValueFrom: &corev1.EnvVarSource{
-// SecretKeyRef: &corev1.SecretKeySelector{
-// LocalObjectReference: corev1.LocalObjectReference{
-// Name: "my-conn-credential",
-// },
-// Key: "password",
-// },
-// },
-// },
-// {
-// Name: "SPILO_CONFIGURATION",
-// ValueFrom: &corev1.EnvVarSource{
-// ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
-// LocalObjectReference: corev1.LocalObjectReference{
-// Name: cmTemplateName,
-// },
-// Key: cmConfigFileName,
-// },
-// },
-// },
-// },
-// EnvFrom: []corev1.EnvFromSource{
-// {
-// ConfigMapRef: &corev1.ConfigMapEnvSource{
-// LocalObjectReference: corev1.LocalObjectReference{
-// Name: "my-config-env",
-// },
-// },
-// },
-// {
-// SecretRef: &corev1.SecretEnvSource{
-// LocalObjectReference: corev1.LocalObjectReference{
-// Name: "my-secret-env",
-// },
-// },
-// },
-// },
-// Resources: corev1.ResourceRequirements{
-// Limits: map[corev1.ResourceName]resource.Quantity{
-// corev1.ResourceMemory: resource.MustParse("8Gi"),
-// corev1.ResourceCPU: resource.MustParse("4"),
-// },
-// },
-// },
-// {
-// Name: "invalid_container",
-// },
-// },
-// }
-// cluster = &appsv1.Cluster{
-// ObjectMeta: metav1.ObjectMeta{
-// Name: "my",
-// UID: "b006a20c-fb03-441c-bffa-2605cad7e297",
-// },
-// }
-// component = &ctrlcomp.SynthesizedComponent{
-// Name: "mysql",
-// ClusterName: cluster.Name,
-// }
-// })
-//
-// AfterEach(func() {
-// mockClient.Finish()
-// })
-//
-// // for test GetContainerWithVolumeMount
-// Context("ConfigTemplateBuilder built-in env test", func() {
-// It("test built-in function", func() {
-// cfgBuilder := newTemplateBuilder(
-// "my_test",
-// "default",
-// ctx, mockClient.Client(),
-// )
-//
-// localObjs := []coreclient.Object{
-// &corev1.ConfigMap{
-// ObjectMeta: metav1.ObjectMeta{
-// Name: cmTemplateName,
-// Namespace: "default",
-// },
-// Data: map[string]string{
-// cmConfigFileName: patroniTemplate,
-// }},
-// }
-// cfgBuilder.injectBuiltInObjectsAndFunctions(podSpec, component, localObjs,
-// &appsv1.Cluster{
-// ObjectMeta: metav1.ObjectMeta{
-// Name: "my_test",
-// Namespace: "default",
-// },
-// })
-//
-// rendered, err := cfgBuilder.render(map[string]string{
-// // KB_CLUSTER_NAME, KB_COMP_NAME from env
-// // MYSQL_USER,MYSQL_PASSWORD from valueFrom secret key
-// // SPILO_CONFIGURATION from valueFrom configmap key
-// // KB_LEADER from envFrom configmap
-// // MEMORY_SIZE, CPU from resourceFieldRef
-// "my": fmt.Sprintf("{{ getEnvByName ( index $.podSpec.containers 0 ) \"%s\" }}", constant.KBEnvClusterName),
-// "mysql": fmt.Sprintf("{{ getEnvByName ( index $.podSpec.containers 0 ) \"%s\" }}", constant.KBEnvCompName),
-// "root": "{{ getEnvByName ( index $.podSpec.containers 0 ) \"MYSQL_USER\" }}",
-// "4zrqfl2r": "{{ getEnvByName ( index $.podSpec.containers 0 ) \"MYSQL_PASSWORD\" }}",
-// patroniTemplate: "{{ getEnvByName ( index $.podSpec.containers 0 ) \"SPILO_CONFIGURATION\" }}",
-// "my-mysql-0": "{{ getEnvByName ( index $.podSpec.containers 0 ) \"KB_LEADER\" }}",
-//
-// strconv.Itoa(4): "{{ getEnvByName ( index $.podSpec.containers 0 ) \"CPU\" }}",
-// strconv.Itoa(8 * 1024 * 1024 * 1024): "{{ getEnvByName ( index $.podSpec.containers 0 ) \"MEMORY_SIZE\" }}",
-// })
-//
-// Expect(err).Should(Succeed())
-// for key, value := range rendered {
-// Expect(key).Should(BeEquivalentTo(value))
-// }
-//
-// _, err = cfgBuilder.render(map[string]string{
-// "error": "{{ getEnvByName ( index $.podSpec.containers 0 ) \"CPU2\" }}",
-// })
-// Expect(err).ShouldNot(Succeed())
-// Expect(err.Error()).Should(ContainSubstring("not found named[not_exist_container] container"))
-//
-// _, err = cfgBuilder.render(map[string]string{
-// "error_loop_reference": "{{ getEnvByName ( index $.podSpec.containers 0 ) \"LOOP_REFERENCE_A\" }}",
-// })
-// Expect(err).ShouldNot(Succeed())
-// Expect(err.Error()).Should(ContainSubstring("too many reference count, maybe there is a cycled reference"))
-// })
-// })
-// })
+import (
+ "fmt"
+ "strconv"
+
+ . "github.com/onsi/ginkgo/v2"
+ . "github.com/onsi/gomega"
+
+ corev1 "k8s.io/api/core/v1"
+ "k8s.io/apimachinery/pkg/api/resource"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ coreclient "sigs.k8s.io/controller-runtime/pkg/client"
+
+ appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1"
+ "github.com/apecloud/kubeblocks/pkg/constant"
+ ctrlcomp "github.com/apecloud/kubeblocks/pkg/controller/component"
+ testapps "github.com/apecloud/kubeblocks/pkg/testutil/apps"
+ testutil "github.com/apecloud/kubeblocks/pkg/testutil/k8s"
+)
+
+var _ = Describe("tpl env template", func() {
+
+ patroniTemplate := `
+bootstrap:
+ initdb:
+ - auth-host: md5
+ - auth-local: trust
+`
+ const (
+ cmTemplateName = "patroni-template-config"
+ cmConfigFileName = "postgresql.yaml"
+ )
+
+ var (
+ podSpec *corev1.PodSpec
+ component *ctrlcomp.SynthesizedComponent
+ cluster *appsv1.Cluster
+
+ mockClient *testutil.K8sClientMockHelper
+ )
+
+ BeforeEach(func() {
+ mockClient = testutil.NewK8sMockClient()
+
+ mockClient.MockGetMethod(testutil.WithGetReturned(testutil.WithConstructSimpleGetResult([]coreclient.Object{
+ &corev1.ConfigMap{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: cmTemplateName,
+ Namespace: "default",
+ },
+ Data: map[string]string{
+ cmConfigFileName: patroniTemplate,
+ }},
+ &corev1.ConfigMap{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "my-config-env",
+ Namespace: "default",
+ },
+ Data: map[string]string{
+ "KB_0_HOSTNAME": "my-mysql-0.my-mysql-headless",
+ "KB_FOLLOWERS": "",
+ "KB_LEADER": "my-mysql-0",
+ "KB_REPLICA_COUNT": "1",
+ "LOOP_REFERENCE_A": "$(LOOP_REFERENCE_B)",
+ "LOOP_REFERENCE_B": "$(LOOP_REFERENCE_C)",
+ "LOOP_REFERENCE_C": "$(LOOP_REFERENCE_A)",
+ }},
+ &corev1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "my-conn-credential",
+ Namespace: "default",
+ },
+ Data: map[string][]byte{
+ "password": []byte("4zrqfl2r"),
+ "username": []byte("root"),
+ }},
+ }), testutil.WithAnyTimes()))
+
+ // 2 configmap and 2 secret
+ // Add any setup steps that needs to be executed before each test
+ podSpec = &corev1.PodSpec{
+ Containers: []corev1.Container{
+ {
+ Name: "mytest",
+ Env: []corev1.EnvVar{
+ {
+ Name: constant.KBEnvClusterName,
+ Value: "my",
+ },
+ {
+ Name: constant.KBEnvCompName,
+ Value: "mysql",
+ },
+ {
+ Name: "MEMORY_SIZE",
+ ValueFrom: &corev1.EnvVarSource{
+ ResourceFieldRef: &corev1.ResourceFieldSelector{
+ ContainerName: "mytest",
+ Resource: "limits.memory",
+ },
+ },
+ },
+ {
+ Name: "CPU",
+ ValueFrom: &corev1.EnvVarSource{
+ ResourceFieldRef: &corev1.ResourceFieldSelector{
+ Resource: "limits.cpu",
+ },
+ },
+ },
+ {
+ Name: "CPU2",
+ ValueFrom: &corev1.EnvVarSource{
+ ResourceFieldRef: &corev1.ResourceFieldSelector{
+ ContainerName: "not_exist_container",
+ Resource: "limits.memory",
+ },
+ },
+ },
+ {
+ Name: "MYSQL_USER",
+ ValueFrom: &corev1.EnvVarSource{
+ SecretKeyRef: &corev1.SecretKeySelector{
+ LocalObjectReference: corev1.LocalObjectReference{
+ Name: "my-conn-credential",
+ },
+ Key: "username",
+ },
+ },
+ },
+ {
+ Name: "MYSQL_PASSWORD",
+ ValueFrom: &corev1.EnvVarSource{
+ SecretKeyRef: &corev1.SecretKeySelector{
+ LocalObjectReference: corev1.LocalObjectReference{
+ Name: "my-conn-credential",
+ },
+ Key: "password",
+ },
+ },
+ },
+ {
+ Name: "SPILO_CONFIGURATION",
+ ValueFrom: &corev1.EnvVarSource{
+ ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
+ LocalObjectReference: corev1.LocalObjectReference{
+ Name: cmTemplateName,
+ },
+ Key: cmConfigFileName,
+ },
+ },
+ },
+ },
+ EnvFrom: []corev1.EnvFromSource{
+ {
+ ConfigMapRef: &corev1.ConfigMapEnvSource{
+ LocalObjectReference: corev1.LocalObjectReference{
+ Name: "my-config-env",
+ },
+ },
+ },
+ {
+ SecretRef: &corev1.SecretEnvSource{
+ LocalObjectReference: corev1.LocalObjectReference{
+ Name: "my-secret-env",
+ },
+ },
+ },
+ },
+ Resources: corev1.ResourceRequirements{
+ Limits: map[corev1.ResourceName]resource.Quantity{
+ corev1.ResourceMemory: resource.MustParse("8Gi"),
+ corev1.ResourceCPU: resource.MustParse("4"),
+ },
+ },
+ },
+ {
+ Name: "invalid_container",
+ },
+ },
+ }
+ cluster = &appsv1.Cluster{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "my",
+ UID: "b006a20c-fb03-441c-bffa-2605cad7e297",
+ },
+ }
+ component = &ctrlcomp.SynthesizedComponent{
+ Name: "mysql",
+ ClusterName: cluster.Name,
+ }
+ })
+
+ AfterEach(func() {
+ mockClient.Finish()
+ })
+
+ // for test GetContainerWithVolumeMount
+ Context("ConfigTemplateBuilder built-in env test", func() {
+ It("test built-in function", func() {
+ cfgBuilder := NewTemplateBuilder(
+ &ReconcileCtx{
+ ResourceCtx: &ResourceCtx{
+ Context: ctx,
+ Client: mockClient.Client(),
+ Namespace: testCtx.DefaultNamespace,
+ },
+ Cluster: testapps.NewClusterFactory("my_test", "default", "cmpd").GetObject(),
+ SynthesizedComponent: component,
+ Cache: []coreclient.Object{
+ &corev1.ConfigMap{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: cmTemplateName,
+ Namespace: "default",
+ },
+ Data: map[string]string{
+ cmConfigFileName: patroniTemplate,
+ }},
+ },
+ PodSpec: podSpec,
+ },
+ )
+
+ rendered, err := cfgBuilder.render(map[string]string{
+ // KB_CLUSTER_NAME, KB_COMP_NAME from env
+ // MYSQL_USER,MYSQL_PASSWORD from valueFrom secret key
+ // SPILO_CONFIGURATION from valueFrom configmap key
+ // KB_LEADER from envFrom configmap
+ // MEMORY_SIZE, CPU from resourceFieldRef
+ "my": fmt.Sprintf("{{ getEnvByName ( index $.podSpec.containers 0 ) \"%s\" }}", constant.KBEnvClusterName),
+ "mysql": fmt.Sprintf("{{ getEnvByName ( index $.podSpec.containers 0 ) \"%s\" }}", constant.KBEnvCompName),
+ "root": "{{ getEnvByName ( index $.podSpec.containers 0 ) \"MYSQL_USER\" }}",
+ "4zrqfl2r": "{{ getEnvByName ( index $.podSpec.containers 0 ) \"MYSQL_PASSWORD\" }}",
+ patroniTemplate: "{{ getEnvByName ( index $.podSpec.containers 0 ) \"SPILO_CONFIGURATION\" }}",
+ "my-mysql-0": "{{ getEnvByName ( index $.podSpec.containers 0 ) \"KB_LEADER\" }}",
+
+ strconv.Itoa(4): "{{ getEnvByName ( index $.podSpec.containers 0 ) \"CPU\" }}",
+ strconv.Itoa(8 * 1024 * 1024 * 1024): "{{ getEnvByName ( index $.podSpec.containers 0 ) \"MEMORY_SIZE\" }}",
+ })
+
+ Expect(err).Should(Succeed())
+ for key, value := range rendered {
+ Expect(key).Should(BeEquivalentTo(value))
+ }
+
+ _, err = cfgBuilder.render(map[string]string{
+ "error": "{{ getEnvByName ( index $.podSpec.containers 0 ) \"CPU2\" }}",
+ })
+ Expect(err).ShouldNot(Succeed())
+ Expect(err.Error()).Should(ContainSubstring("not found named[not_exist_container] container"))
+
+ _, err = cfgBuilder.render(map[string]string{
+ "error_loop_reference": "{{ getEnvByName ( index $.podSpec.containers 0 ) \"LOOP_REFERENCE_A\" }}",
+ })
+ Expect(err).ShouldNot(Succeed())
+ Expect(err.Error()).Should(ContainSubstring("too many reference count, maybe there is a cycled reference"))
+ })
+ })
+})
diff --git a/pkg/controller/configuration/parameter_utils_test.go b/pkg/controller/configuration/parameter_utils_test.go
index 76223688cd3..e445f2b163e 100644
--- a/pkg/controller/configuration/parameter_utils_test.go
+++ b/pkg/controller/configuration/parameter_utils_test.go
@@ -19,6 +19,7 @@ package configuration
import (
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
+
corev1 "k8s.io/api/core/v1"
"k8s.io/utils/pointer"
diff --git a/pkg/controller/configuration/resource_wrapper_test.go b/pkg/controller/configuration/resource_wrapper_test.go
index 85093e343be..a85e6e25158 100644
--- a/pkg/controller/configuration/resource_wrapper_test.go
+++ b/pkg/controller/configuration/resource_wrapper_test.go
@@ -25,12 +25,11 @@ import (
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
appsv1 "github.com/apecloud/kubeblocks/apis/apps/v1"
- appsv1beta1 "github.com/apecloud/kubeblocks/apis/apps/v1beta1"
cfgcore "github.com/apecloud/kubeblocks/pkg/configuration/core"
+ "github.com/apecloud/kubeblocks/pkg/controller/builder"
testapps "github.com/apecloud/kubeblocks/pkg/testutil/apps"
testutil "github.com/apecloud/kubeblocks/pkg/testutil/k8s"
)
@@ -70,18 +69,13 @@ var _ = Describe("resource Fetcher", func() {
[]client.Object{
cluster,
testapps.NewConfigMap("default", cfgcore.GetComponentCfgName(clusterName, mysqlCompName, mysqlConfigName)),
- &appsv1beta1.ConfigConstraint{
- ObjectMeta: metav1.ObjectMeta{
- Name: mysqlConfigName,
- },
- },
+ builder.NewComponentParameterBuilder(testCtx.DefaultNamespace, cfgcore.GenerateComponentParameterName(clusterName, mysqlCompName)).GetObject(),
},
), testutil.WithAnyTimes()))
err := NewTest(k8sMockClient.Client(), ctx).
Cluster().
ComponentSpec().
ConfigMap(mysqlConfigName).
- // ConfigConstraints(mysqlConfigName).
ComponentParameter().
Complete()
Expect(err).Should(Succeed())
diff --git a/pkg/controllerutil/parameter_schema.go b/pkg/controllerutil/parameter_schema.go
index 6c7437e4dd6..93694890a9e 100644
--- a/pkg/controllerutil/parameter_schema.go
+++ b/pkg/controllerutil/parameter_schema.go
@@ -43,7 +43,7 @@ func ResolveConfigParameterSchema(paramDef *parametersv1alpha1.ParametersDefinit
}
paramMeta := &ParameterMeta{
- FileName: paramDef.Name,
+ FileName: paramDef.Spec.FileName,
ConfigTemplateName: configTemplate.Name,
}
props := openapi.FlattenSchema(schema.Properties[openapi.DefaultSchemaName]).Properties