From d95d4d39842fe7b262e8e7af3a2782c34a1c4fe5 Mon Sep 17 00:00:00 2001 From: Chris Hein Date: Sun, 5 Apr 2020 08:11:05 -0700 Subject: [PATCH] adding ComponentConfig type and Options parsing Signed-off-by: Chris Hein --- .golangci.yml | 2 + Makefile | 25 +++ alias.go | 3 + examples/config/example.yaml | 7 + hack/boilerplate.go.txt | 15 ++ hack/verify.sh | 5 +- pkg/api/config/v1alpha1/componentconfig.go | 205 +++++++++++++++++++ pkg/api/config/v1alpha1/groupversion_info.go | 34 +++ pkg/api/config/v1alpha1/types.go | 84 ++++++++ pkg/manager/manager.go | 144 +++++++++++++ pkg/manager/manager_test.go | 44 +++- 11 files changed, 566 insertions(+), 2 deletions(-) create mode 100644 examples/config/example.yaml create mode 100644 hack/boilerplate.go.txt create mode 100644 pkg/api/config/v1alpha1/componentconfig.go create mode 100644 pkg/api/config/v1alpha1/groupversion_info.go create mode 100644 pkg/api/config/v1alpha1/types.go diff --git a/.golangci.yml b/.golangci.yml index 44a915409d..2cae3826e1 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,5 +1,7 @@ run: deadline: 5m + skip-files: + - pkg/api/config/v1alpha1/zz_generated.deepcopy.go linters-settings: lll: line-length: 170 diff --git a/Makefile b/Makefile index fb356ee714..b9d1d0ea5c 100644 --- a/Makefile +++ b/Makefile @@ -34,6 +34,12 @@ export GOPROXY # Active module mode, as we use go modules to manage dependencies export GO111MODULE=on +ifeq (,$(shell go env GOBIN)) +GOBIN=$(shell go env GOPATH)/bin +else +GOBIN=$(shell go env GOBIN) +endif + # Tools. TOOLS_DIR := hack/tools TOOLS_BIN_DIR := $(TOOLS_DIR)/bin @@ -62,6 +68,25 @@ test: ## Run the script check-everything.sh which will check all. $(GOLANGCI_LINT): $(TOOLS_DIR)/go.mod # Build golangci-lint from tools folder. cd $(TOOLS_DIR); go build -tags=tools -o bin/golangci-lint github.com/golangci/golangci-lint/cmd/golangci-lint +controller-gen: +ifeq (, $(shell which controller-gen)) + @{ \ + set -e ;\ + CONTROLLER_GEN_TMP_DIR=$$(mktemp -d) ;\ + cd $$CONTROLLER_GEN_TMP_DIR ;\ + go mod init tmp ;\ + go get sigs.k8s.io/controller-tools/cmd/controller-gen@v0.2.5 ;\ + rm -rf $$CONTROLLER_GEN_TMP_DIR ;\ + } +CONTROLLER_GEN=$(GOBIN)/controller-gen +else +CONTROLLER_GEN=$(shell which controller-gen) +endif + +generate: controller-gen + $(CONTROLLER_GEN) object:headerFile=./hack/boilerplate.go.txt paths="./pkg/api/..." + + ## -------------------------------------- ## Linting ## -------------------------------------- diff --git a/alias.go b/alias.go index af955ad301..076ce2f2f6 100644 --- a/alias.go +++ b/alias.go @@ -100,6 +100,9 @@ var ( // NewManager returns a new Manager for creating Controllers. NewManager = manager.New + // UpdateOptionsFromComponentConfig returns an updated Options struct from a ComponentConfig type + UpdateOptionsFromComponentConfig = manager.UpdateOptionsFromComponentConfig + // CreateOrUpdate creates or updates the given object obj in the Kubernetes // cluster. The object's desired state should be reconciled with the existing // state using the passed in ReconcileFn. obj must be a struct pointer so that diff --git a/examples/config/example.yaml b/examples/config/example.yaml new file mode 100644 index 0000000000..4e75727cb4 --- /dev/null +++ b/examples/config/example.yaml @@ -0,0 +1,7 @@ +apiVersion: controller-runtime.config.sigs.k8s.io/v1alpha1 +kind: DefaultControllerConfiguration +spec: + port: 9443 + metricsBindAddress: ":8080" + leaderElection: + leaderElect: false \ No newline at end of file diff --git a/hack/boilerplate.go.txt b/hack/boilerplate.go.txt new file mode 100644 index 0000000000..86d7f0376b --- /dev/null +++ b/hack/boilerplate.go.txt @@ -0,0 +1,15 @@ +/* +The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ \ No newline at end of file diff --git a/hack/verify.sh b/hack/verify.sh index af02aad73f..f5189a7332 100755 --- a/hack/verify.sh +++ b/hack/verify.sh @@ -21,8 +21,11 @@ source $(dirname ${BASH_SOURCE})/common.sh REPO_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. cd "${REPO_ROOT}" +header_text "deepcopy gen" +make generate + header_text "running golangci-lint" make lint header_text "verifying modules" -make modules verify-modules +make modules verify-modules \ No newline at end of file diff --git a/pkg/api/config/v1alpha1/componentconfig.go b/pkg/api/config/v1alpha1/componentconfig.go new file mode 100644 index 0000000000..b8da8ef6c1 --- /dev/null +++ b/pkg/api/config/v1alpha1/componentconfig.go @@ -0,0 +1,205 @@ +/* +The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + "reflect" + "time" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + configv1alpha1 "k8s.io/component-base/config/v1alpha1" +) + +// Getters + +// GetSyncPeriod returns the sync period in time.Duration +func (in *DefaultControllerConfiguration) GetSyncPeriod() *time.Duration { + if in.Spec.SyncPeriod != nil { + return &in.Spec.SyncPeriod.Duration + } + return nil +} + +// GetLeaderElection returns the LeaderElection +func (in *DefaultControllerConfiguration) GetLeaderElection() *bool { + return in.Spec.LeaderElection.LeaderElect +} + +// GetLeaderElectionNamespace returns the LeaderElectionNamespace +func (in *DefaultControllerConfiguration) GetLeaderElectionNamespace() string { + return in.Spec.LeaderElection.ResourceNamespace +} + +// GetLeaderElectionID returns the LeaderElectionID +func (in *DefaultControllerConfiguration) GetLeaderElectionID() string { + return in.Spec.LeaderElection.ResourceName +} + +// GetLeaseDuration returns the LeaseDuration +func (in *DefaultControllerConfiguration) GetLeaseDuration() *time.Duration { + return &in.Spec.LeaderElection.LeaseDuration.Duration +} + +// GetRenewDeadline returns the RenewDeadline +func (in *DefaultControllerConfiguration) GetRenewDeadline() *time.Duration { + return &in.Spec.LeaderElection.RenewDeadline.Duration +} + +// GetRetryPeriod returns the RetryPeriod +func (in *DefaultControllerConfiguration) GetRetryPeriod() *time.Duration { + return &in.Spec.LeaderElection.RetryPeriod.Duration +} + +// GetNamespace returns the Namespace +func (in *DefaultControllerConfiguration) GetNamespace() string { + return in.Spec.Namespace +} + +// GetMetricsBindAddress returns the MetricsBindAddress +func (in *DefaultControllerConfiguration) GetMetricsBindAddress() string { + return in.Spec.MetricsBindAddress +} + +// GetHealthProbeBindAddress returns the HealthProbeBindAddress +func (in *DefaultControllerConfiguration) GetHealthProbeBindAddress() string { + return in.Spec.Health.HealthProbeBindAddress +} + +// GetReadinessEndpointName returns the ReadinessEndpointName +func (in *DefaultControllerConfiguration) GetReadinessEndpointName() string { + return in.Spec.Health.ReadinessEndpointName +} + +// GetLivenessEndpointName returns the LivenessEndpointName +func (in *DefaultControllerConfiguration) GetLivenessEndpointName() string { + return in.Spec.Health.LivenessEndpointName +} + +// GetPort returns the Port +func (in *DefaultControllerConfiguration) GetPort() *int { + return in.Spec.Port +} + +// GetHost returns the Host +func (in *DefaultControllerConfiguration) GetHost() string { + return in.Spec.Host +} + +// GetCertDir returns the CertDir +func (in *DefaultControllerConfiguration) GetCertDir() string { + return in.Spec.CertDir +} + +// Setters + +// SetSyncPeriod sets the sync period in time.Duration +func (in *DefaultControllerConfiguration) SetSyncPeriod(syncPeriod *metav1.Duration) { + in.Spec.SyncPeriod = syncPeriod +} + +// SetLeaderElectionConfiguration sets the leader election configuration +func (in *DefaultControllerConfiguration) SetLeaderElectionConfiguration(leaderElection configv1alpha1.LeaderElectionConfiguration) { + in.Spec.LeaderElection = leaderElection +} + +// SetLeaderElection sets the LeaderElection config +func (in *DefaultControllerConfiguration) SetLeaderElection(leaderElection bool) { + if reflect.DeepEqual(in.Spec.LeaderElection, configv1alpha1.LeaderElectionConfiguration{}) { + in.SetLeaderElectionConfiguration(configv1alpha1.LeaderElectionConfiguration{}) + } + in.Spec.LeaderElection.LeaderElect = &leaderElection +} + +// SetLeaderElectionNamespace returns the LeaderElectionNamespace +func (in *DefaultControllerConfiguration) SetLeaderElectionNamespace(resourceNamespace string) { + if reflect.DeepEqual(in.Spec.LeaderElection, configv1alpha1.LeaderElectionConfiguration{}) { + in.SetLeaderElectionConfiguration(configv1alpha1.LeaderElectionConfiguration{}) + } + in.Spec.LeaderElection.ResourceNamespace = resourceNamespace +} + +// SetLeaderElectionID returns the LeaderElectionID +func (in *DefaultControllerConfiguration) SetLeaderElectionID(resourceName string) { + if reflect.DeepEqual(in.Spec.LeaderElection, configv1alpha1.LeaderElectionConfiguration{}) { + in.SetLeaderElectionConfiguration(configv1alpha1.LeaderElectionConfiguration{}) + } + in.Spec.LeaderElection.ResourceName = resourceName +} + +// SetLeaseDuration returns the LeaseDuration +func (in *DefaultControllerConfiguration) SetLeaseDuration(leaseDuration metav1.Duration) { + if reflect.DeepEqual(in.Spec.LeaderElection, configv1alpha1.LeaderElectionConfiguration{}) { + in.SetLeaderElectionConfiguration(configv1alpha1.LeaderElectionConfiguration{}) + } + in.Spec.LeaderElection.LeaseDuration = leaseDuration +} + +// SetRenewDeadline returns the RenewDeadline +func (in *DefaultControllerConfiguration) SetRenewDeadline(renewDeadline metav1.Duration) { + if reflect.DeepEqual(in.Spec.LeaderElection, configv1alpha1.LeaderElectionConfiguration{}) { + in.SetLeaderElectionConfiguration(configv1alpha1.LeaderElectionConfiguration{}) + } + in.Spec.LeaderElection.RenewDeadline = renewDeadline +} + +// SetRetryPeriod returns the RetryPeriod +func (in *DefaultControllerConfiguration) SetRetryPeriod(retryPeriod metav1.Duration) { + if reflect.DeepEqual(in.Spec.LeaderElection, configv1alpha1.LeaderElectionConfiguration{}) { + in.SetLeaderElectionConfiguration(configv1alpha1.LeaderElectionConfiguration{}) + } + in.Spec.LeaderElection.RetryPeriod = retryPeriod +} + +// SetNamespace returns the Namespace +func (in *DefaultControllerConfiguration) SetNamespace(namespace string) { + in.Spec.Namespace = namespace +} + +// SetMetricsBindAddress returns the MetricsBindAddress +func (in *DefaultControllerConfiguration) SetMetricsBindAddress(metricsBindAddress string) { + in.Spec.MetricsBindAddress = metricsBindAddress +} + +// SetHealthProbeBindAddress returns the HealthProbeBindAddress +func (in *DefaultControllerConfiguration) SetHealthProbeBindAddress(healthProbeBindAddress string) { + in.Spec.Health.HealthProbeBindAddress = healthProbeBindAddress +} + +// SetReadinessEndpointName returns the ReadinessEndpointName +func (in *DefaultControllerConfiguration) SetReadinessEndpointName(readinessEndpointName string) { + in.Spec.Health.ReadinessEndpointName = readinessEndpointName +} + +// SetLivenessEndpointName returns the LivenessEndpointName +func (in *DefaultControllerConfiguration) SetLivenessEndpointName(livenessEndpointName string) { + in.Spec.Health.LivenessEndpointName = livenessEndpointName +} + +// SetPort returns the Port +func (in *DefaultControllerConfiguration) SetPort(port *int) { + in.Spec.Port = port +} + +// SetHost returns the Host +func (in *DefaultControllerConfiguration) SetHost(host string) { + in.Spec.Host = host +} + +// SetCertDir returns the CertDir +func (in *DefaultControllerConfiguration) SetCertDir(certDir string) { + in.Spec.CertDir = certDir +} diff --git a/pkg/api/config/v1alpha1/groupversion_info.go b/pkg/api/config/v1alpha1/groupversion_info.go new file mode 100644 index 0000000000..24c51319b5 --- /dev/null +++ b/pkg/api/config/v1alpha1/groupversion_info.go @@ -0,0 +1,34 @@ +/* +The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package v1alpha1 provides a default ComponentConfig type for configuring +// controller-runtime Options. +// +kubebuilder:object:generate=true +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "controller-runtime.sigs.k8s.io", Version: "v1alpha1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/pkg/api/config/v1alpha1/types.go b/pkg/api/config/v1alpha1/types.go new file mode 100644 index 0000000000..89436de2ed --- /dev/null +++ b/pkg/api/config/v1alpha1/types.go @@ -0,0 +1,84 @@ +/* +The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + configv1alpha1 "k8s.io/component-base/config/v1alpha1" +) + +// DefaultControllerConfigurationSpec defines the desired state of DefaultControllerConfiguration +type DefaultControllerConfigurationSpec struct { + // SyncPeriod returns the SyncPeriod + // +optional + SyncPeriod *metav1.Duration `json:"syncPeriod,omitempty"` + + // LeaderElection returns the LeaderElection config + // +optional + LeaderElection configv1alpha1.LeaderElectionConfiguration `json:"leaderElection,omitempty"` + + // Namespace returns the namespace for the controller + // +optional + Namespace string `json:"namespace,omitempty"` + + // MetricsBindAddress returns the bind address for the metrics server + // +optional + MetricsBindAddress string `json:"metricsBindAddress,omitempty"` + + // MetricsBindAddress returns the bind address for the metrics server + // +optional + Health DefaultControllerConfigurationHealth `json:"health,omitempty"` + + // Port returns the Port for the server + // +optional + Port *int `json:"port,omitempty"` + + // Host returns the Host for the server + // +optional + Host string `json:"host,omitempty"` + + // CertDir returns the CertDir + // +optional + CertDir string `json:"certDir,omitempty"` +} + +// DefaultControllerConfigurationHealth defines the health configs +type DefaultControllerConfigurationHealth struct { + // HealthProbeBindAddress returns the bind address for the health probe + // +optional + HealthProbeBindAddress string `json:"healthProbeBindAddress,omitempty"` + + // ReadinessEndpointName returns the readiness endpoint name + // +optional + ReadinessEndpointName string `json:"readinessEndpointName,omitempty"` + + // LivenessEndpointName returns the liveness endpoint name + // +optional + LivenessEndpointName string `json:"livenessEndpointName,omitempty"` +} + +// +kubebuilder:object:root=true + +// DefaultControllerConfiguration is the Schema for the DefaultControllerConfigurations API +type DefaultControllerConfiguration struct { + metav1.TypeMeta `json:",inline"` + + // Spec defines the default controller config + // +optional + Spec DefaultControllerConfigurationSpec `json:"spec,omitempty"` +} diff --git a/pkg/manager/manager.go b/pkg/manager/manager.go index 852eb787b9..c5ccdbbfa4 100644 --- a/pkg/manager/manager.go +++ b/pkg/manager/manager.go @@ -18,6 +18,7 @@ package manager import ( "fmt" + "io/ioutil" "net" "time" @@ -25,6 +26,7 @@ import ( "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/rest" "k8s.io/client-go/tools/leaderelection/resourcelock" @@ -97,6 +99,55 @@ type Manager interface { GetWebhookServer() *webhook.Server } +// Configuration defines what the ComponentConfig object for controller +// runtime needs in order to run +type Configuration interface { + runtime.Object + + // GetSyncPeriod returns the SyncPeriod + // Typically ComponentConfig types will store this as matav1.Duration + GetSyncPeriod() *time.Duration + + // GetSyncPeriod returns if LeaderElection is turned on + GetLeaderElection() *bool + // GetLeaderElectionNamespace returns the namespace for LeaderElection + GetLeaderElectionNamespace() string + // GetLeaderElectionID returns the LeaderElectionID + GetLeaderElectionID() string + + // GetLeaseDuration returns the LeaseDuration + // Typically ComponentConfig types will store this as matav1.Duration + GetLeaseDuration() *time.Duration + // GetRenewDeadline returns the RenewDeadline + // Typically ComponentConfig types will store this as matav1.Duration + GetRenewDeadline() *time.Duration + // GetRetryPeriod returns the RetryPeriod + // Typically ComponentConfig types will store this as matav1.Duration + GetRetryPeriod() *time.Duration + + // GetNamespace returns the Namespace + // TODO(christopherhein,joelan) explore adding Plural to support + GetNamespace() string + + // GetMetricsBindAddress returns the MetricsBindAddress + GetMetricsBindAddress() string + // GetHealthProbeBindAddress returns the HealthProbeBindAddress + GetHealthProbeBindAddress() string + + // GetReadinessEndpointName returns the ReadinessEndpointName + GetReadinessEndpointName() string + // GetLivenessEndpointName returns the LivenessEndpointName + GetLivenessEndpointName() string + + // GetPort returns the Port + GetPort() *int + // GetHost returns the Host + GetHost() string + + // GetCertDir returns the CertDir + GetCertDir() string +} + // Options are the arguments for creating a new Manager type Options struct { // Scheme is the scheme used to resolve runtime.Objects to GroupVersionKinds / Resources @@ -316,6 +367,99 @@ func New(config *rest.Config, options Options) (Manager, error) { }, nil } +// NewOptionsFromComponentConfig returns a populated Options based on the +// ManagerConfiguation object. +func NewOptionsFromComponentConfig(scheme *runtime.Scheme, filename string, managerconfig Configuration) (options Options, err error) { + // Check if Scheme is set + if scheme == nil { + return options, fmt.Errorf("must specify Scheme") + } + + // Check if Configuration is set + if managerconfig == nil { + return options, fmt.Errorf("must specify Configuration") + } + + content, err := ioutil.ReadFile(filename) + if err != nil { + return options, err + } + + // Set Scheme + options.Scheme = scheme + + // Setup codec factory + codecs := serializer.NewCodecFactory(scheme) + + // Regardless of if the bytes are of any external version, + // it will be read successfully and converted into the internal version + if err := runtime.DecodeInto(codecs.UniversalDecoder(), content, managerconfig); err != nil { + return options, err + } + + if managerconfig.GetSyncPeriod() != nil { + options.SyncPeriod = managerconfig.GetSyncPeriod() + } + + if managerconfig.GetLeaderElection() != nil { + options.LeaderElection = *managerconfig.GetLeaderElection() + } + + if managerconfig.GetLeaderElectionNamespace() != "" { + options.LeaderElectionNamespace = managerconfig.GetLeaderElectionNamespace() + } + + if managerconfig.GetLeaderElectionID() != "" { + options.LeaderElectionID = managerconfig.GetLeaderElectionID() + } + + if managerconfig.GetLeaseDuration() != nil { + options.LeaseDuration = managerconfig.GetLeaseDuration() + } + + if managerconfig.GetRenewDeadline() != nil { + options.RenewDeadline = managerconfig.GetRenewDeadline() + } + + if managerconfig.GetRetryPeriod() != nil { + options.RetryPeriod = managerconfig.GetRetryPeriod() + } + + if managerconfig.GetNamespace() != "" { + options.Namespace = managerconfig.GetNamespace() + } + + if managerconfig.GetMetricsBindAddress() != "" { + options.MetricsBindAddress = managerconfig.GetMetricsBindAddress() + } + + if managerconfig.GetHealthProbeBindAddress() != "" { + options.HealthProbeBindAddress = managerconfig.GetHealthProbeBindAddress() + } + + if managerconfig.GetReadinessEndpointName() != "" { + options.ReadinessEndpointName = managerconfig.GetReadinessEndpointName() + } + + if managerconfig.GetLivenessEndpointName() != "" { + options.LivenessEndpointName = managerconfig.GetLivenessEndpointName() + } + + if managerconfig.GetPort() != nil { + options.Port = *managerconfig.GetPort() + } + + if managerconfig.GetHost() != "" { + options.Host = managerconfig.GetHost() + } + + if managerconfig.GetCertDir() != "" { + options.CertDir = managerconfig.GetCertDir() + } + + return options, nil +} + // defaultNewClient creates the default caching client func defaultNewClient(cache cache.Cache, config *rest.Config, options client.Options) (client.Client, error) { // Create the Client for Write operations. diff --git a/pkg/manager/manager_test.go b/pkg/manager/manager_test.go index 9b291d80cc..2a02ad0dc1 100644 --- a/pkg/manager/manager_test.go +++ b/pkg/manager/manager_test.go @@ -27,12 +27,12 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "github.com/prometheus/client_golang/prometheus" - "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/rest" "k8s.io/client-go/tools/leaderelection/resourcelock" "k8s.io/client-go/tools/record" + v1alpha1 "sigs.k8s.io/controller-runtime/pkg/api/config/v1alpha1" "sigs.k8s.io/controller-runtime/pkg/cache" "sigs.k8s.io/controller-runtime/pkg/cache/informertest" "sigs.k8s.io/controller-runtime/pkg/client" @@ -239,6 +239,48 @@ var _ = Describe("manger.Manager", func() { }) }) + Describe("NewOptionsFromComponentConfig", func() { + It("should return an error if there is no Scheme", func() { + _, err := NewOptionsFromComponentConfig(nil, "configname", nil) + Expect(err.Error()).To(ContainSubstring("must specify Scheme")) + }) + + It("should return an error if there is no Configuration", func() { + _, err := NewOptionsFromComponentConfig(runtime.NewScheme(), "configname", nil) + Expect(err.Error()).To(ContainSubstring("must specify Configuration")) + }) + It("should return an error if there is not a file", func() { + _, err := NewOptionsFromComponentConfig(runtime.NewScheme(), "configname", &v1alpha1.DefaultControllerConfiguration{}) + Expect(err.Error()).To(ContainSubstring("no such file or directory")) + }) + + It("should return config files values for options values", func() { + scheme := runtime.NewScheme() + _ = v1alpha1.AddToScheme(scheme) + cfg := &v1alpha1.DefaultControllerConfiguration{} + + opts, err := NewOptionsFromComponentConfig(scheme, "../../examples/config/example.yaml", cfg) + Expect(err).To(BeNil()) + + Expect(opts.SyncPeriod).To(Equal(cfg.GetSyncPeriod())) + Expect(opts.LeaderElection).To(Equal(*cfg.GetLeaderElection())) + Expect(opts.LeaderElectionNamespace).To(Equal(cfg.GetLeaderElectionNamespace())) + Expect(opts.LeaderElectionID).To(Equal(cfg.GetLeaderElectionID())) + Expect(opts.LeaseDuration).To(Equal(cfg.GetLeaseDuration())) + Expect(opts.RenewDeadline).To(Equal(cfg.GetRenewDeadline())) + Expect(opts.RetryPeriod).To(Equal(cfg.GetRetryPeriod())) + Expect(opts.Namespace).To(Equal(cfg.GetNamespace())) + Expect(opts.MetricsBindAddress).To(Equal(cfg.GetMetricsBindAddress())) + Expect(opts.HealthProbeBindAddress).To(Equal(cfg.GetHealthProbeBindAddress())) + Expect(opts.ReadinessEndpointName).To(Equal(cfg.GetReadinessEndpointName())) + Expect(opts.LivenessEndpointName).To(Equal(cfg.GetLivenessEndpointName())) + Expect(opts.Port).To(Equal(*cfg.GetPort())) + Expect(opts.Host).To(Equal(cfg.GetHost())) + Expect(opts.CertDir).To(Equal(cfg.GetCertDir())) + }) + + }) + Describe("Start", func() { var startSuite = func(options Options) { It("should Start each Component", func(done Done) {