diff --git a/.golangci.yml b/.golangci.yml index 0fae128cd..795e08728 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -16,6 +16,12 @@ issues: - goconst - golint text: "underscore" + - path: ^pkg\/util\/envvar + linters: + - forbidigo + - path: ^cmd\/(readiness|versionhook|manager)\/main\.go$ + linters: + - forbidigo linters: enable: - govet @@ -28,10 +34,25 @@ linters: - rowserrcheck - gosec - unconvert + - forbidigo linters-settings: gosec: excludes: - G115 + forbidigo: + forbid: + - p: os\.(Getenv|LookupEnv|Environ|ExpandEnv) + pkg: os + msg: "Reading environemnt variables here is prohibited. Please read environment variables in the main package." + - p: os\.(Clearenv|Unsetenv|Setenv) + msg: "Modifying environemnt variables is prohibited." + pkg: os + - p: envvar\.(Read.*?|MergeWithOverride|GetEnvOrDefault) + pkg: github.com/mongodb/mongodb-kubernetes-operator/pkg/util/envvar + msg: "Using this envvar package here is prohibited. Please work with environment variables in the main package." + # Rules with the `pkg` depend on it + analyze-types: true + run: modules-download-mode: mod # timeout for analysis, e.g. 30s, 5m, default is 1m diff --git a/controllers/construct/build_statefulset_test.go b/controllers/construct/build_statefulset_test.go index e02095c63..791fa5a8b 100644 --- a/controllers/construct/build_statefulset_test.go +++ b/controllers/construct/build_statefulset_test.go @@ -109,7 +109,7 @@ func assertStatefulSetIsBuiltCorrectly(t *testing.T, mdb mdbv1.MongoDBCommunity, assert.Len(t, sts.Spec.Template.Spec.Containers[0].Env, 4) assert.Len(t, sts.Spec.Template.Spec.Containers[1].Env, 1) - managedSecurityContext := envvar.ReadBool(podtemplatespec.ManagedSecurityContextEnv) + managedSecurityContext := envvar.ReadBool(podtemplatespec.ManagedSecurityContextEnv) // nolint:forbidigo if !managedSecurityContext { assert.NotNil(t, sts.Spec.Template.Spec.SecurityContext) assert.Equal(t, podtemplatespec.DefaultPodSecurityContext(), *sts.Spec.Template.Spec.SecurityContext) diff --git a/controllers/construct/mongodbstatefulset.go b/controllers/construct/mongodbstatefulset.go index cec2e5be7..68513b89f 100644 --- a/controllers/construct/mongodbstatefulset.go +++ b/controllers/construct/mongodbstatefulset.go @@ -417,7 +417,7 @@ func collectEnvVars() []corev1.EnvVar { }) addEnvVarIfSet := func(name string) { - value := os.Getenv(name) + value := os.Getenv(name) // nolint:forbidigo if value != "" { envVars = append(envVars, corev1.EnvVar{ Name: name, diff --git a/controllers/replica_set_controller.go b/controllers/replica_set_controller.go index d7f2ee65d..01bc2ca84 100644 --- a/controllers/replica_set_controller.go +++ b/controllers/replica_set_controller.go @@ -219,7 +219,7 @@ func (r ReplicaSetReconciler) Reconcile(ctx context.Context, request reconcile.R } res, err := status.Update(ctx, r.client.Status(), &mdb, statusOptions(). - withMongoURI(mdb.MongoURI(os.Getenv(clusterDomain))). + withMongoURI(mdb.MongoURI(os.Getenv(clusterDomain))). // nolint:forbidigo withMongoDBMembers(mdb.AutomationConfigMembersThisReconciliation()). withStatefulSetReplicas(mdb.StatefulSetReplicasThisReconciliation()). withStatefulSetArbiters(mdb.StatefulSetArbitersThisReconciliation()). @@ -232,7 +232,7 @@ func (r ReplicaSetReconciler) Reconcile(ctx context.Context, request reconcile.R return res, err } - if err := r.updateConnectionStringSecrets(ctx, mdb, os.Getenv(clusterDomain)); err != nil { + if err := r.updateConnectionStringSecrets(ctx, mdb, os.Getenv(clusterDomain)); err != nil { // nolint:forbidigo r.log.Errorf("Could not update connection string secrets: %s", err) } @@ -515,8 +515,8 @@ func (r ReplicaSetReconciler) ensureAutomationConfig(mdb mdbv1.MongoDBCommunity, } func buildAutomationConfig(mdb mdbv1.MongoDBCommunity, isEnterprise bool, auth automationconfig.Auth, currentAc automationconfig.AutomationConfig, modifications ...automationconfig.Modification) (automationconfig.AutomationConfig, error) { - domain := getDomain(mdb.ServiceName(), mdb.Namespace, os.Getenv(clusterDomain)) - arbiterDomain := getDomain(mdb.ServiceName(), mdb.Namespace, os.Getenv(clusterDomain)) + domain := getDomain(mdb.ServiceName(), mdb.Namespace, os.Getenv(clusterDomain)) // nolint:forbidigo + arbiterDomain := getDomain(mdb.ServiceName(), mdb.Namespace, os.Getenv(clusterDomain)) // nolint:forbidigo zap.S().Debugw("AutomationConfigMembersThisReconciliation", "mdb.AutomationConfigMembersThisReconciliation()", mdb.AutomationConfigMembersThisReconciliation()) @@ -557,7 +557,7 @@ func buildAutomationConfig(mdb mdbv1.MongoDBCommunity, isEnterprise bool, auth a } func guessEnterprise(mdb mdbv1.MongoDBCommunity, mongodbImage string) bool { - overrideAssumption, err := strconv.ParseBool(os.Getenv(construct.MongoDBAssumeEnterpriseEnv)) + overrideAssumption, err := strconv.ParseBool(os.Getenv(construct.MongoDBAssumeEnterpriseEnv)) // nolint:forbidigo if err == nil { return overrideAssumption } diff --git a/pkg/kube/container/container_test.go b/pkg/kube/container/container_test.go index 5c08b14b9..a61a0be15 100644 --- a/pkg/kube/container/container_test.go +++ b/pkg/kube/container/container_test.go @@ -146,7 +146,7 @@ func TestMergeEnvs(t *testing.T) { }, } - merged := envvar.MergeWithOverride(existing, desired) + merged := envvar.MergeWithOverride(existing, desired) // nolint:forbidigo t.Run("EnvVars should be sorted", func(t *testing.T) { assert.Equal(t, "A_env", merged[0].Name) diff --git a/pkg/kube/container/containers.go b/pkg/kube/container/containers.go index debd4b115..687befc5b 100644 --- a/pkg/kube/container/containers.go +++ b/pkg/kube/container/containers.go @@ -129,7 +129,7 @@ func WithLifecycle(lifeCycleMod lifecycle.Modification) Modification { // WithEnvs ensures all of the provided envs exist in the container func WithEnvs(envs ...corev1.EnvVar) Modification { return func(container *corev1.Container) { - container.Env = envvar.MergeWithOverride(container.Env, envs) + container.Env = envvar.MergeWithOverride(container.Env, envs) // nolint:forbidigo } } diff --git a/pkg/kube/podtemplatespec/podspec_template.go b/pkg/kube/podtemplatespec/podspec_template.go index e79b4cf05..f908a214a 100644 --- a/pkg/kube/podtemplatespec/podspec_template.go +++ b/pkg/kube/podtemplatespec/podspec_template.go @@ -297,7 +297,7 @@ func FindContainerByName(name string, podTemplateSpec *corev1.PodTemplateSpec) * } func WithDefaultSecurityContextsModifications() (Modification, container.Modification) { - managedSecurityContext := envvar.ReadBool(ManagedSecurityContextEnv) + managedSecurityContext := envvar.ReadBool(ManagedSecurityContextEnv) // nolint:forbidigo configureContainerSecurityContext := container.NOOP() configurePodSpecSecurityContext := NOOP() if !managedSecurityContext { diff --git a/pkg/readiness/config/config.go b/pkg/readiness/config/config.go index 09b8ca50e..7f3e64714 100644 --- a/pkg/readiness/config/config.go +++ b/pkg/readiness/config/config.go @@ -43,15 +43,15 @@ func BuildFromEnvVariables(clientSet kubernetes.Interface, isHeadless bool, file var namespace, automationConfigName, hostname string if isHeadless { var ok bool - namespace, ok = os.LookupEnv(podNamespaceEnv) + namespace, ok = os.LookupEnv(podNamespaceEnv) // nolint:forbidigo if !ok { return Config{}, fmt.Errorf("the '%s' environment variable must be set", podNamespaceEnv) } - automationConfigName, ok = os.LookupEnv(automationConfigSecretEnv) + automationConfigName, ok = os.LookupEnv(automationConfigSecretEnv) // nolint:forbidigo if !ok { return Config{}, fmt.Errorf("the '%s' environment variable must be set", automationConfigSecretEnv) } - hostname, ok = os.LookupEnv(hostNameEnv) + hostname, ok = os.LookupEnv(hostNameEnv) // nolint:forbidigo if !ok { return Config{}, fmt.Errorf("the '%s' environment variable must be set", hostNameEnv) } @@ -85,7 +85,7 @@ func readinessProbeLogFilePath() string { } func GetEnvOrDefault(envVar, defaultValue string) string { - value := strings.TrimSpace(os.Getenv(envVar)) + value := strings.TrimSpace(os.Getenv(envVar)) // nolint:forbidigo if value == "" { return defaultValue } diff --git a/test/e2e/e2eutil.go b/test/e2e/e2eutil.go index 41f64c287..d29fd9abb 100644 --- a/test/e2e/e2eutil.go +++ b/test/e2e/e2eutil.go @@ -36,7 +36,7 @@ func TestAnnotations() map[string]string { } func TestDataDir() string { - return envvar.GetEnvOrDefault(testDataDirEnv, "/workspace/testdata") + return envvar.GetEnvOrDefault(testDataDirEnv, "/workspace/testdata") // nolint:forbidigo } func TlsTestDataDir() string { diff --git a/test/e2e/setup/setup.go b/test/e2e/setup/setup.go index 88769bf78..8bf9595bd 100644 --- a/test/e2e/setup/setup.go +++ b/test/e2e/setup/setup.go @@ -42,7 +42,7 @@ const ( ) func Setup(ctx context.Context, t *testing.T) *e2eutil.TestContext { - testCtx, err := e2eutil.NewContext(ctx, t, envvar.ReadBool(performCleanupEnv)) + testCtx, err := e2eutil.NewContext(ctx, t, envvar.ReadBool(performCleanupEnv)) // nolint:forbidigo if err != nil { t.Fatal(err) @@ -57,7 +57,7 @@ func Setup(ctx context.Context, t *testing.T) *e2eutil.TestContext { } func SetupWithTLS(ctx context.Context, t *testing.T, resourceName string, additionalHelmArgs ...HelmArg) (*e2eutil.TestContext, TestConfig) { - textCtx, err := e2eutil.NewContext(ctx, t, envvar.ReadBool(performCleanupEnv)) + textCtx, err := e2eutil.NewContext(ctx, t, envvar.ReadBool(performCleanupEnv)) // nolint:forbidigo if err != nil { t.Fatal(err) @@ -76,7 +76,7 @@ func SetupWithTLS(ctx context.Context, t *testing.T, resourceName string, additi } func SetupWithTestConfig(ctx context.Context, t *testing.T, testConfig TestConfig, withTLS, defaultOperator bool, resourceName string) *e2eutil.TestContext { - testCtx, err := e2eutil.NewContext(ctx, t, envvar.ReadBool(performCleanupEnv)) + testCtx, err := e2eutil.NewContext(ctx, t, envvar.ReadBool(performCleanupEnv)) // nolint:forbidigo if err != nil { t.Fatal(err) diff --git a/test/e2e/setup/test_config.go b/test/e2e/setup/test_config.go index d4b2ab8c1..1fc247021 100644 --- a/test/e2e/setup/test_config.go +++ b/test/e2e/setup/test_config.go @@ -34,18 +34,19 @@ type TestConfig struct { func LoadTestConfigFromEnv() TestConfig { return TestConfig{ - Namespace: envvar.GetEnvOrDefault(testNamespaceEnvName, "mongodb"), - CertManagerNamespace: envvar.GetEnvOrDefault(testCertManagerNamespaceEnvName, "cert-manager"), - CertManagerVersion: envvar.GetEnvOrDefault(testCertManagerVersionEnvName, "v1.5.3"), - OperatorImage: envvar.GetEnvOrDefault(operatorImageEnvName, "quay.io/mongodb/community-operator-dev:latest"), - MongoDBImage: envvar.GetEnvOrDefault(construct.MongodbImageEnv, "mongodb-community-server"), - MongoDBRepoUrl: envvar.GetEnvOrDefault(construct.MongodbRepoUrlEnv, "quay.io/mongodb"), - VersionUpgradeHookImage: envvar.GetEnvOrDefault(construct.VersionUpgradeHookImageEnv, "quay.io/mongodb/mongodb-kubernetes-operator-version-upgrade-post-start-hook:1.0.2"), - AgentImage: envvar.GetEnvOrDefault(construct.AgentImageEnv, "quay.io/mongodb/mongodb-agent-ubi:10.29.0.6830-1"), // TODO: better way to decide default agent image. - ClusterWide: envvar.ReadBool(clusterWideEnvName), - PerformCleanup: envvar.ReadBool(performCleanupEnvName), - ReadinessProbeImage: envvar.GetEnvOrDefault(construct.ReadinessProbeImageEnv, "quay.io/mongodb/mongodb-kubernetes-readinessprobe:1.0.3"), - HelmChartPath: envvar.GetEnvOrDefault(helmChartPathEnvName, "/workspace/helm-charts/charts/community-operator"), - LocalOperator: envvar.ReadBool(LocalOperatorEnvName), + Namespace: envvar.GetEnvOrDefault(testNamespaceEnvName, "mongodb"), // nolint:forbidigo + CertManagerNamespace: envvar.GetEnvOrDefault(testCertManagerNamespaceEnvName, "cert-manager"), // nolint:forbidigo + CertManagerVersion: envvar.GetEnvOrDefault(testCertManagerVersionEnvName, "v1.5.3"), // nolint:forbidigo + OperatorImage: envvar.GetEnvOrDefault(operatorImageEnvName, "quay.io/mongodb/community-operator-dev:latest"), // nolint:forbidigo + MongoDBImage: envvar.GetEnvOrDefault(construct.MongodbImageEnv, "mongodb-community-server"), // nolint:forbidigo + MongoDBRepoUrl: envvar.GetEnvOrDefault(construct.MongodbRepoUrlEnv, "quay.io/mongodb"), // nolint:forbidigo + VersionUpgradeHookImage: envvar.GetEnvOrDefault(construct.VersionUpgradeHookImageEnv, "quay.io/mongodb/mongodb-kubernetes-operator-version-upgrade-post-start-hook:1.0.2"), // nolint:forbidigo + // TODO: better way to decide default agent image. + AgentImage: envvar.GetEnvOrDefault(construct.AgentImageEnv, "quay.io/mongodb/mongodb-agent-ubi:10.29.0.6830-1"), // nolint:forbidigo + ClusterWide: envvar.ReadBool(clusterWideEnvName), // nolint:forbidigo + PerformCleanup: envvar.ReadBool(performCleanupEnvName), // nolint:forbidigo + ReadinessProbeImage: envvar.GetEnvOrDefault(construct.ReadinessProbeImageEnv, "quay.io/mongodb/mongodb-kubernetes-readinessprobe:1.0.3"), // nolint:forbidigo + HelmChartPath: envvar.GetEnvOrDefault(helmChartPathEnvName, "/workspace/helm-charts/charts/community-operator"), // nolint:forbidigo + LocalOperator: envvar.ReadBool(LocalOperatorEnvName), // nolint:forbidigo } }