diff --git a/Makefile b/Makefile index 0ee9da656..a01b72886 100644 --- a/Makefile +++ b/Makefile @@ -433,14 +433,15 @@ run: webhook-certs-dir manifests generate install-gateway-api-crds install _ensu # etc didn't change in between the runs. .PHONY: _run _run: - CONTROLLER_DEVELOPMENT_MODE=true go run ./main.go \ + GATEWAY_OPERATOR_DEVELOPMENT_MODE=true go run ./main.go \ --no-leader-election \ -cluster-ca-secret-namespace kong-system \ - -zap-time-encoding iso8601 \ -enable-controller-controlplane \ -enable-controller-gateway \ -enable-controller-aigateway \ - -zap-log-level 2 + -zap-time-encoding iso8601 \ + -zap-log-level 2 \ + -zap-devel true SKAFFOLD_RUN_PROFILE ?= dev @@ -458,7 +459,7 @@ run.skaffold: .PHONY: debug debug: webhook-certs-dir manifests generate install _ensure-kong-system-namespace - CONTROLLER_DEVELOPMENT_MODE=true dlv debug ./main.go -- \ + GATEWAY_OPERATOR_DEVELOPMENT_MODE=true dlv debug ./main.go -- \ --no-leader-election \ -cluster-ca-secret-namespace kong-system \ --enable-controller-aigateway \ diff --git a/config/debug/manager_debug.yaml b/config/debug/manager_debug.yaml index bac162756..b7fffd7d1 100644 --- a/config/debug/manager_debug.yaml +++ b/config/debug/manager_debug.yaml @@ -33,7 +33,7 @@ spec: - -zap-log-level=debug name: manager env: - - name: CONTROLLER_DEVELOPMENT_MODE + - name: GATEWAY_OPERATOR_DEVELOPMENT_MODE value: "true" resources: limits: diff --git a/config/dev/manager_dev.yaml b/config/dev/manager_dev.yaml index 3429b8b1c..00fa640cb 100644 --- a/config/dev/manager_dev.yaml +++ b/config/dev/manager_dev.yaml @@ -27,7 +27,7 @@ spec: - -enable-validating-webhook=true name: manager env: - - name: CONTROLLER_DEVELOPMENT_MODE + - name: GATEWAY_OPERATOR_DEVELOPMENT_MODE value: "true" resources: limits: diff --git a/main.go b/main.go index 640fa90e4..dba207d6a 100644 --- a/main.go +++ b/main.go @@ -32,7 +32,7 @@ func main() { cli := cli.New() cfg := cli.Parse(os.Args[1:]) - ctrl.SetLogger(zap.New(zap.UseFlagOptions(&cfg.LoggerOpts))) + ctrl.SetLogger(zap.New(zap.UseFlagOptions(cfg.LoggerOpts))) if err := manager.Run(cfg, scheme.Get(), manager.SetupControllersShim, admission.NewRequestHandler, nil); err != nil { ctrl.Log.Error(err, "failed to run manager") diff --git a/modules/cli/cli.go b/modules/cli/cli.go index 12aedefc9..eb476cf52 100644 --- a/modules/cli/cli.go +++ b/modules/cli/cli.go @@ -7,6 +7,9 @@ import ( "os" "strings" + "github.com/samber/lo" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + "github.com/kong/gateway-operator/modules/manager" "github.com/kong/gateway-operator/modules/manager/logging" "github.com/kong/gateway-operator/modules/manager/metadata" @@ -19,7 +22,7 @@ func New() *CLI { var cfg manager.Config var deferCfg flagsForFurtherEvaluation - flagSet.BoolVar(&cfg.AnonymousReports, "anonymous-reports", true, "Send anonymized usage data to help improve Kong") + flagSet.BoolVar(&cfg.AnonymousReports, "anonymous-reports", true, "Send anonymized usage data to help improve Kong.") flagSet.StringVar(&cfg.APIServerPath, "apiserver-host", "", "The Kubernetes API server URL. If not set, the operator will use cluster config discovery.") flagSet.StringVar(&cfg.KubeconfigPath, "kubeconfig", "", "Path to the kubeconfig file.") @@ -28,9 +31,9 @@ func New() *CLI { flagSet.BoolVar(&deferCfg.DisableLeaderElection, "no-leader-election", false, "Disable leader election for controller manager. Disabling this will not ensure there is only one active controller manager.") - flagSet.StringVar(&cfg.ControllerName, "controller-name", "", "a controller name to use if other than the default, only needed for multi-tenancy") - flagSet.StringVar(&cfg.ClusterCASecretName, "cluster-ca-secret", "kong-operator-ca", "name of the Secret containing the cluster CA certificate") - flagSet.StringVar(&deferCfg.ClusterCASecretNamespace, "cluster-ca-secret-namespace", "", "name of the namespace for Secret containing the cluster CA certificate") + flagSet.StringVar(&cfg.ControllerName, "controller-name", "", "Controller name to use if other than the default, only needed for multi-tenancy.") + flagSet.StringVar(&cfg.ClusterCASecretName, "cluster-ca-secret", "kong-operator-ca", "Name of the Secret containing the cluster CA certificate.") + flagSet.StringVar(&deferCfg.ClusterCASecretNamespace, "cluster-ca-secret-namespace", "", "Name of the namespace for Secret containing the cluster CA certificate.") // controllers for standard APIs and features flagSet.BoolVar(&cfg.GatewayControllerEnabled, "enable-controller-gateway", true, "Enable the Gateway controller.") @@ -39,23 +42,33 @@ func New() *CLI { flagSet.BoolVar(&cfg.DataPlaneBlueGreenControllerEnabled, "enable-controller-dataplane-bluegreen", true, "Enable the DataPlane BlueGreen controller. Mutually exclusive with DataPlane controller.") // controllers for specialized APIs and features - flagSet.BoolVar(&cfg.AIGatewayControllerEnabled, "enable-controller-aigateway", false, "Enable the AIGateway controller. (Experimental)") + flagSet.BoolVar(&cfg.AIGatewayControllerEnabled, "enable-controller-aigateway", false, "Enable the AIGateway controller. (Experimental).") // webhook and validation options flagSet.BoolVar(&deferCfg.ValidatingWebhookEnabled, "enable-validating-webhook", true, "Enable the validating webhook.") - flagSet.BoolVar(&deferCfg.Version, "version", false, "Print version information") + flagSet.BoolVar(&deferCfg.Version, "version", false, "Print version information.") + + developmentModeEnabled := manager.DefaultConfig().DevelopmentMode + if v := os.Getenv(envVarFlagPrefix + "DEVELOPMENT_MODE"); v == "true" { // TODO: clean env handling https://github.com/Kong/gateway-operator/issues/19 + developmentModeEnabled = true + } + loggerOpts := lo.ToPtr(*manager.DefaultConfig().LoggerOpts) + loggerOpts.Development = developmentModeEnabled + loggerOpts.BindFlags(flagSet) return &CLI{ flagSet: flagSet, cfg: &cfg, + loggerOpts: loggerOpts, deferFlagValues: &deferCfg, } } // CLI represents command line interface for the operator. type CLI struct { - flagSet *flag.FlagSet + flagSet *flag.FlagSet + loggerOpts *zap.Options // deferFlagValues contains values of flags that require additional // logic after parsing flagSet to determine desired configuration. @@ -103,7 +116,7 @@ func (c *CLI) bindEnvVarsToFlags() (err error) { // by the program. It returns config for controller manager. func (c *CLI) Parse(arguments []string) manager.Config { developmentModeEnabled := manager.DefaultConfig().DevelopmentMode - if v := os.Getenv("CONTROLLER_DEVELOPMENT_MODE"); v == "true" { // TODO: clean env handling https://github.com/Kong/gateway-operator/issues/19 + if v := os.Getenv(envVarFlagPrefix + "DEVELOPMENT_MODE"); v == "true" { // TODO: clean env handling https://github.com/Kong/gateway-operator/issues/19 developmentModeEnabled = true } @@ -112,10 +125,6 @@ func (c *CLI) Parse(arguments []string) manager.Config { webhookCertDir = certDir } - loggerOpts := manager.DefaultConfig().LoggerOpts - loggerOpts.Development = developmentModeEnabled - loggerOpts.BindFlags(c.flagSet) - // Flags take precedence over environment variables, // so we bind env vars first then parse aruments to override the values from flags. if err := c.bindEnvVarsToFlags(); err != nil { @@ -186,7 +195,7 @@ func (c *CLI) Parse(arguments []string) manager.Config { c.cfg.ClusterCASecretNamespace = clusterCASecretNamespace c.cfg.WebhookCertDir = webhookCertDir c.cfg.ValidatingWebhookEnabled = validatingWebhookEnabled - c.cfg.LoggerOpts = logging.SetupLogEncoder(c.cfg.DevelopmentMode, loggerOpts) + c.cfg.LoggerOpts = logging.SetupLogEncoder(c.cfg.DevelopmentMode || c.loggerOpts.Development, c.loggerOpts) c.cfg.WebhookPort = manager.DefaultConfig().WebhookPort c.cfg.LeaderElectionNamespace = controllerNamespace c.cfg.AnonymousReports = anonymousReportsEnabled diff --git a/modules/cli/cli_test.go b/modules/cli/cli_test.go index 54f10bf83..b7ea907be 100644 --- a/modules/cli/cli_test.go +++ b/modules/cli/cli_test.go @@ -6,6 +6,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/stretchr/testify/require" + "sigs.k8s.io/controller-runtime/pkg/log/zap" "github.com/kong/gateway-operator/modules/manager" "github.com/kong/gateway-operator/modules/manager/logging" @@ -41,15 +42,15 @@ func TestParse(t *testing.T) { name: "no command line arguments, many environment variables", args: []string{}, envVars: map[string]string{ - "POD_NAMESPACE": "test", - "CONTROLLER_DEVELOPMENT_MODE": "true", + "POD_NAMESPACE": "test", + "GATEWAY_OPERATOR_DEVELOPMENT_MODE": "true", }, expectedCfg: func() manager.Config { cfg := expectedDefaultCfg() cfg.LeaderElectionNamespace = "test" cfg.ClusterCASecretNamespace = "test" cfg.ControllerNamespace = "test" - // All the below config changes are the result of CONTROLLER_DEVELOPMENT_MODE=true. + // All the below config changes are the result of GATEWAY_OPERATOR_DEVELOPMENT_MODE=true. cfg.DevelopmentMode = true cfg.ValidatingWebhookEnabled = false loggerOpts := manager.DefaultConfig().LoggerOpts @@ -147,5 +148,6 @@ func expectedDefaultCfg() manager.Config { DataPlaneControllerEnabled: true, DataPlaneBlueGreenControllerEnabled: true, ValidatingWebhookEnabled: true, + LoggerOpts: &zap.Options{}, } } diff --git a/modules/manager/logging/encoding.go b/modules/manager/logging/encoding.go index 9f476f0c5..c81e83e87 100644 --- a/modules/manager/logging/encoding.go +++ b/modules/manager/logging/encoding.go @@ -30,7 +30,7 @@ var ( // SetupLogEncoder sets additional logger configuration options when development mode is enabled. // In this way, the log structure is lighter and more human-friendly when the development mode // is enabled. -func SetupLogEncoder(developmentMode bool, options zap.Options) zap.Options { +func SetupLogEncoder(developmentMode bool, options *zap.Options) *zap.Options { if developmentMode { options.TimeEncoder = defaultDevTimeEncoder options.EncoderConfigOptions = []zap.EncoderConfigOption{ diff --git a/modules/manager/run.go b/modules/manager/run.go index 9aaa5549f..427606c68 100644 --- a/modules/manager/run.go +++ b/modules/manager/run.go @@ -74,7 +74,7 @@ type Config struct { KubeconfigPath string ClusterCASecretName string ClusterCASecretNamespace string - LoggerOpts zap.Options + LoggerOpts *zap.Options // controllers for standard APIs and features GatewayControllerEnabled bool @@ -107,7 +107,7 @@ func DefaultConfig() Config { ClusterCASecretName: "kong-operator-ca", ClusterCASecretNamespace: defaultNamespace, ControllerNamespace: defaultNamespace, - LoggerOpts: zap.Options{}, + LoggerOpts: &zap.Options{}, GatewayControllerEnabled: true, ControlPlaneControllerEnabled: true, DataPlaneControllerEnabled: true,