From 869ce1da6ac4d4d1d8b7d97a566941d3a396837f Mon Sep 17 00:00:00 2001 From: Dominik Rosiek Date: Wed, 15 Feb 2023 09:43:09 +0100 Subject: [PATCH 1/4] feat(operator): add support for configuration file Signed-off-by: Dominik Rosiek --- operator/Dockerfile | 2 +- operator/Makefile | 4 +- operator/config.go | 42 +++++++++++++++++++++ operator/config_test.go | 81 +++++++++++++++++++++++++++++++++++++++++ operator/go.mod | 5 ++- operator/main.go | 29 ++++++++++++++- 6 files changed, 157 insertions(+), 6 deletions(-) create mode 100644 operator/config.go create mode 100644 operator/config_test.go diff --git a/operator/Dockerfile b/operator/Dockerfile index 4e9dc3cd..ed8a8496 100644 --- a/operator/Dockerfile +++ b/operator/Dockerfile @@ -11,7 +11,7 @@ COPY . . RUN go mod download # Build -RUN CGO_ENABLED=0 GOOS=linux GO111MODULE=on go build -a -o manager main.go +RUN CGO_ENABLED=0 GOOS=linux GO111MODULE=on go build -a -o manager main.go config.go # Use distroless as minimal base image to package the manager binary # Refer to https://github.com/GoogleContainerTools/distroless for more details diff --git a/operator/Makefile b/operator/Makefile index 1aa9dce6..16f14ab4 100755 --- a/operator/Makefile +++ b/operator/Makefile @@ -46,11 +46,11 @@ clean: # Build manager binary manager: generate fmt vet - go build -o bin/manager main.go + go build -o bin/manager main.go ./config.go # Run against the configured Kubernetes cluster in ~/.kube/config run: generate fmt vet manifests - go run ./main.go + go run ./main.go ./config.go # Install CRDs into a cluster install: manifests kustomize diff --git a/operator/config.go b/operator/config.go new file mode 100644 index 00000000..dff55c07 --- /dev/null +++ b/operator/config.go @@ -0,0 +1,42 @@ +package main + +import ( + "os" + + "gopkg.in/yaml.v3" +) + +type Config struct { + Sidecar SidecarConfig `yaml:"sidecar,omitempty"` +} + +type SidecarConfig struct { + Image string `yaml:"image,omitempty"` +} + +func ReadConfig(configPath string) (Config, error) { + // Set default values + config := Config{ + Sidecar: SidecarConfig{ + Image: "sumologic/tailing-sidecar:latest", + }, + } + + f, err := os.Open(configPath) + if err != nil { + return config, err + } + defer f.Close() + + decoder := yaml.NewDecoder(f) + err = decoder.Decode(&config) + + if err != nil && err.Error() == "EOF" { + return config, nil + } + return config, err +} + +func (c *Config) Validate() error { + return nil +} diff --git a/operator/config_test.go b/operator/config_test.go new file mode 100644 index 00000000..fc33d2d5 --- /dev/null +++ b/operator/config_test.go @@ -0,0 +1,81 @@ +package main + +import ( + "io/ioutil" + "os" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestReadConfig(t *testing.T) { + testCases := []struct { + name string + content string + expected Config + expectedError error + }{ + { + name: "empty file", + content: ``, + expected: Config{ + Sidecar: SidecarConfig{ + Image: "sumologic/tailing-sidecar:latest", + }, + }, + expectedError: nil, + }, + { + name: "defaults", + content: ` +sidecar: + commands: + - test + - command`, + expected: Config{ + Sidecar: SidecarConfig{ + Image: "sumologic/tailing-sidecar:latest", + }, + }, + expectedError: nil, + }, + { + name: "overwrite defaults", + content: ` +sidecar: + image: my-new-image`, + expected: Config{ + Sidecar: SidecarConfig{ + Image: "my-new-image", + }, + }, + expectedError: nil, + }, + } + + for _, tt := range testCases { + t.Run(tt.name, func(t *testing.T) { + file, err := ioutil.TempFile(".", "prefix") + require.NoError(t, err) + defer os.Remove(file.Name()) + + _, err = file.WriteString(tt.content) + require.NoError(t, err) + config, err := ReadConfig(file.Name()) + + if tt.expectedError != nil { + require.Error(t, tt.expectedError, err) + return + } + + require.NoError(t, err) + require.Equal(t, tt.expected, config) + }) + } +} + +func TestReadConfigInvalidFile(t *testing.T) { + _, err := ReadConfig("non-existing-file") + require.Error(t, err) + require.EqualError(t, err, "open non-existing-file: no such file or directory") +} diff --git a/operator/go.mod b/operator/go.mod index 16b169c8..17f0ef2f 100644 --- a/operator/go.mod +++ b/operator/go.mod @@ -7,13 +7,17 @@ require ( github.com/nsf/jsondiff v0.0.0-20200515183724-f29ed568f4ce github.com/onsi/ginkgo v1.16.5 github.com/onsi/gomega v1.27.6 + github.com/stretchr/testify v1.8.1 gomodules.xyz/jsonpatch/v2 v2.2.0 + gopkg.in/yaml.v3 v3.0.1 k8s.io/api v0.26.3 k8s.io/apimachinery v0.27.1 k8s.io/client-go v0.26.3 sigs.k8s.io/controller-runtime v0.14.6 ) +require github.com/pmezard/go-difflib v1.0.0 // indirect + require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect @@ -63,7 +67,6 @@ require ( gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/apiextensions-apiserver v0.26.1 // indirect k8s.io/component-base v0.26.1 // indirect k8s.io/klog/v2 v2.90.1 // indirect diff --git a/operator/main.go b/operator/main.go index b6920985..568de469 100644 --- a/operator/main.go +++ b/operator/main.go @@ -50,15 +50,40 @@ func main() { var metricsAddr string var enableLeaderElection bool var tailingSidecarImage string + var configPath string + var config Config + var err error + flag.StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.") flag.BoolVar(&enableLeaderElection, "enable-leader-election", false, "Enable leader election for controller manager. "+ "Enabling this will ensure there is only one active controller manager.") - flag.StringVar(&tailingSidecarImage, "tailing-sidecar-image", "sumologic/tailing-sidecar:latest", "tailing sidecar image") + flag.StringVar(&tailingSidecarImage, "tailing-sidecar-image", "", "tailing sidecar image") + flag.StringVar(&configPath, "config", "", "Path to the configuration file") flag.Parse() ctrl.SetLogger(zap.New(zap.UseDevMode(true))) + if configPath != "" { + config, err = ReadConfig(configPath) + + if err != nil { + setupLog.Error(err, "unable to read configuration", "configPath", configPath) + os.Exit(1) + } + } else { + config = Config{} + } + + if err := config.Validate(); err != nil { + setupLog.Error(err, "configuration error", "configPath", configPath) + os.Exit(1) + } + + if tailingSidecarImage != "" { + config.Sidecar.Image = tailingSidecarImage + } + mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ Scheme: scheme, MetricsBindAddress: metricsAddr, @@ -84,7 +109,7 @@ func main() { mgr.GetWebhookServer().Register("/add-tailing-sidecars-v1-pod", &webhook.Admission{ Handler: &handler.PodExtender{ Client: mgr.GetClient(), - TailingSidecarImage: tailingSidecarImage, + TailingSidecarImage: config.Sidecar.Image, }, }) From c913b24bef16e35c5ba5e90976cc470ee7f7ee36 Mon Sep 17 00:00:00 2001 From: Dominik Rosiek <58699848+sumo-drosiek@users.noreply.github.com> Date: Wed, 17 May 2023 10:35:56 +0200 Subject: [PATCH 2/4] Update operator/config.go MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Mikołaj Świątek --- operator/config.go | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/operator/config.go b/operator/config.go index dff55c07..3004dcc4 100644 --- a/operator/config.go +++ b/operator/config.go @@ -22,17 +22,13 @@ func ReadConfig(configPath string) (Config, error) { }, } - f, err := os.Open(configPath) + content, err := os.Readfile(configPath) if err != nil { return config, err } - defer f.Close() - - decoder := yaml.NewDecoder(f) - err = decoder.Decode(&config) - - if err != nil && err.Error() == "EOF" { - return config, nil + err = yaml.Unmarshal(content, &config) + if err != nil { + return config, err } return config, err } From fe2a7ddff390c774307ad3ecdd6a415f866e499a Mon Sep 17 00:00:00 2001 From: Dominik Rosiek Date: Wed, 17 May 2023 11:41:29 +0200 Subject: [PATCH 3/4] fix: syntax Signed-off-by: Dominik Rosiek --- operator/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/operator/config.go b/operator/config.go index 3004dcc4..1a92e1c9 100644 --- a/operator/config.go +++ b/operator/config.go @@ -22,7 +22,7 @@ func ReadConfig(configPath string) (Config, error) { }, } - content, err := os.Readfile(configPath) + content, err := os.ReadFile(configPath) if err != nil { return config, err } From 1fa01c45009a0d8a212d75a1ba990cc17350fd4c Mon Sep 17 00:00:00 2001 From: Dominik Rosiek Date: Thu, 18 May 2023 08:18:57 +0200 Subject: [PATCH 4/4] chore: lint Signed-off-by: Dominik Rosiek --- operator/config_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/operator/config_test.go b/operator/config_test.go index fc33d2d5..8e36e6bd 100644 --- a/operator/config_test.go +++ b/operator/config_test.go @@ -34,7 +34,7 @@ sidecar: - command`, expected: Config{ Sidecar: SidecarConfig{ - Image: "sumologic/tailing-sidecar:latest", + Image: "sumologic/tailing-sidecar:latest", }, }, expectedError: nil,