diff --git a/operator/pkg/controllers/bkapp/common/env_vars.go b/operator/pkg/controllers/bkapp/common/env_vars.go index 5ce040c80e..80fd7c58e6 100644 --- a/operator/pkg/controllers/bkapp/common/env_vars.go +++ b/operator/pkg/controllers/bkapp/common/env_vars.go @@ -20,7 +20,9 @@ package common import ( "sort" + "strings" + "github.com/samber/lo" corev1 "k8s.io/api/core/v1" paasv1alpha2 "bk.tencent.com/paas-app-operator/api/v1alpha2" @@ -37,3 +39,33 @@ func GetAppEnvs(bkapp *paasv1alpha2.BkApp) []corev1.EnvVar { sort.Slice(envs, func(i, j int) bool { return envs[i].Name < envs[j].Name }) return envs } + +// VarsRenderContext is the context object for rendering variables list +type VarsRenderContext struct { + // ProcessType is the type of the process, e.g. "web", "worker" + ProcessType string +} + +// RenderAppVars render a list of env variables, it replaces var template with their +// actual values. Only a limited set of vars are supported, including: +// +// - {{bk_var_process_type}} -> real process type +func RenderAppVars(vars []corev1.EnvVar, context VarsRenderContext) []corev1.EnvVar { + supportedKeySuffixes := []string{"_LOG_NAME_PREFIX", "_PROCESS_TYPE"} + + results := make([]corev1.EnvVar, len(vars)) + for i, v := range vars { + newValue := v.Value + // Only do the rendering if the key ends with any supported suffix to prevent + // unnecessary rendering. + if lo.SomeBy(supportedKeySuffixes, func(suffix string) bool { + return strings.HasSuffix(v.Name, suffix) + }) { + // TODO: Use other method to replace the variables when more variables are supported + newValue = strings.Replace(newValue, "{{bk_var_process_type}}", context.ProcessType, -1) + } + + results[i] = corev1.EnvVar{Name: v.Name, Value: newValue} + } + return results +} diff --git a/operator/pkg/controllers/bkapp/common/env_vars_test.go b/operator/pkg/controllers/bkapp/common/env_vars_test.go index 8f7e58247a..0b2fe88184 100644 --- a/operator/pkg/controllers/bkapp/common/env_vars_test.go +++ b/operator/pkg/controllers/bkapp/common/env_vars_test.go @@ -21,6 +21,7 @@ package common import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" paasv1alpha2 "bk.tencent.com/paas-app-operator/api/v1alpha2" @@ -66,3 +67,38 @@ var _ = Describe("Get App Envs", func() { Expect(len(envs)).To(Equal(0)) }) }) + +var _ = Describe("Get App Envs", func() { + It("No \"bk-var-*\" vars in the value", func() { + envs := []corev1.EnvVar{ + {Name: "FOO", Value: "some random value foo"}, + {Name: "BAR", Value: "some random value bar"}, + } + renderedVars := RenderAppVars(envs, VarsRenderContext{ProcessType: "web"}) + + By("The rendered vars should be the same as the input vars") + Expect(renderedVars).To(Equal(envs)) + }) + + It("Contains supported vars", func() { + envs := []corev1.EnvVar{ + {Name: "BKPAAS_PROCESS_TYPE", Value: "{{bk_var_process_type}}"}, + {Name: "OTHER_PRE_LOG_NAME_PREFIX", Value: "foo-{{bk_var_process_type}}"}, + // with valid name but variable does not match + {Name: "OTHER_PRE_PROCESS_TYPE", Value: "{{another_var}}"}, + {Name: "FOO", Value: "some random value foo"}, + // the variable matches but the name is not in whitelist + {Name: "BAR", Value: "{{bk_var_process_type}}"}, + } + renderedVars := RenderAppVars(envs, VarsRenderContext{ProcessType: "web"}) + + By("The `process_type` should be rendered properly.") + Expect(renderedVars).To(Equal([]corev1.EnvVar{ + {Name: "BKPAAS_PROCESS_TYPE", Value: "web"}, + {Name: "OTHER_PRE_LOG_NAME_PREFIX", Value: "foo-web"}, + {Name: "OTHER_PRE_PROCESS_TYPE", Value: "{{another_var}}"}, + {Name: "FOO", Value: "some random value foo"}, + {Name: "BAR", Value: "{{bk_var_process_type}}"}, + })) + }) +}) diff --git a/operator/pkg/controllers/bkapp/hooks/resources/hooks.go b/operator/pkg/controllers/bkapp/hooks/resources/hooks.go index 72776c2630..ab46119e0e 100644 --- a/operator/pkg/controllers/bkapp/hooks/resources/hooks.go +++ b/operator/pkg/controllers/bkapp/hooks/resources/hooks.go @@ -122,6 +122,11 @@ func BuildPreReleaseHook(bkapp *paasv1alpha2.BkApp, status *paasv1alpha2.HookSta command = append([]string{"launcher"}, command...) } + // Generate the environment variables and render the "{{bk_var_*}}" var placeholder which + // might be used in the values. + envVars := common.GetAppEnvs(bkapp) + envVars = common.RenderAppVars(envVars, common.VarsRenderContext{ProcessType: "sys-pre-rel"}) + return &HookInstance{ Pod: &corev1.Pod{ TypeMeta: metav1.TypeMeta{ @@ -146,7 +151,7 @@ func BuildPreReleaseHook(bkapp *paasv1alpha2.BkApp, status *paasv1alpha2.HookSta Image: bkapp.Spec.Build.Image, Command: kubeutil.ReplaceCommandEnvVariables(command), Args: kubeutil.ReplaceCommandEnvVariables(args), - Env: common.GetAppEnvs(bkapp), + Env: envVars, Name: "hook", ImagePullPolicy: bkapp.Spec.Build.ImagePullPolicy, // pre-hook 使用默认资源配置 diff --git a/operator/pkg/controllers/bkapp/processes/resources/deployment.go b/operator/pkg/controllers/bkapp/processes/resources/deployment.go index d4f0f0efb6..d211672ca6 100644 --- a/operator/pkg/controllers/bkapp/processes/resources/deployment.go +++ b/operator/pkg/controllers/bkapp/processes/resources/deployment.go @@ -62,8 +62,11 @@ func BuildProcDeployment(app *paasv1alpha2.BkApp, procName string) (*appsv1.Depl deployID = DefaultDeployID } - // Prepare data + // Generate the environment variables and render the "{{bk_var_*}}" var placeholder which + // might be used in the values. envVars := common.GetAppEnvs(app) + envVars = common.RenderAppVars(envVars, common.VarsRenderContext{ProcessType: procName}) + mounterMap, err := volumes.GetAllVolumeMounterMap(app) if err != nil { return nil, err