From 859c9e34628a4ecbf459ac5aa1a3c121ad6d63e2 Mon Sep 17 00:00:00 2001 From: Simon Barendse Date: Fri, 14 May 2021 14:09:33 +0200 Subject: [PATCH 1/3] Watch all namespaces by default When nothing is configured, watch all namespaces by default. This makes it easier to get started. It also makes configuring to watch all namespaces less akward (currently you have to set the WATCH_NAMESPACE environment variable to the empty string to configure the operator to watch all namespaces. --- README.md | 4 ++-- cmd/manager/main.go | 6 +----- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 62153cf..a2ec464 100644 --- a/README.md +++ b/README.md @@ -84,9 +84,9 @@ An sample Deployment yaml can be found at `/deploy/operator.yaml`. To further configure the 1Password Kubernetes Operator the Following Environment variables can be set in the operator yaml: -- **WATCH_NAMESPACE:** comma separated list of what Namespaces to watch for changes. - **OP_CONNECT_HOST** (required): Specifies the host name within Kubernetes in which to access the 1Password Connect. -- **POLLING_INTERVAL** (default: 600)**:** The number of seconds the 1Password Kubernetes Operator will wait before checking for updates from 1Password Connect. +- **WATCH_NAMESPACE:** (default: watch all namespaces): Comma separated list of what Namespaces to watch for changes. +- **POLLING_INTERVAL** (default: 600): The number of seconds the 1Password Kubernetes Operator will wait before checking for updates from 1Password Connect. - **MANAGE_CONNECT** (default: false): If set to true, on deployment of the operator, a default configuration of the OnePassword Connect Service will be deployed to the `default` namespace. - **AUTO_RESTART** (default: false): If set to true, the operator will restart any deployment using a secret from 1Password Connect. This can be overwritten by namespace, deployment, or individual secret. More details on AUTO_RESTART can be found in the ["Configuring Automatic Rolling Restarts of Deployments"](#configuring-automatic-rolling-restarts-of-deployments) section. diff --git a/cmd/manager/main.go b/cmd/manager/main.go index 66c57a9..9e62460 100644 --- a/cmd/manager/main.go +++ b/cmd/manager/main.go @@ -83,11 +83,7 @@ func main() { printVersion() - namespace, err := k8sutil.GetWatchNamespace() - if err != nil { - log.Error(err, "Failed to get watch namespace") - os.Exit(1) - } + namespace := os.Getenv(k8sutil.WatchNamespaceEnvVar) // Get a config to talk to the apiserver cfg, err := config.GetConfig() From 7e4e98881313ccd48925318f34d0d9b5954116c5 Mon Sep 17 00:00:00 2001 From: Eddy Filip Date: Wed, 9 Jun 2021 16:02:05 +0300 Subject: [PATCH 2/3] Add missing argument for docker build `make build` and `make build/local` would fail because the docker build commands were incomplete. --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index dc31151..137656d 100644 --- a/Makefile +++ b/Makefile @@ -20,12 +20,12 @@ test/coverage: ## Run test suite with coverage report go test -v ./... -cover build: ## Build operator Docker image - @docker build -f Dockerfile --build-arg operator_version=$(curVersion) -t $(DOCKER_IMG_TAG) + @docker build -f Dockerfile --build-arg operator_version=$(curVersion) -t $(DOCKER_IMG_TAG) . @echo "Successfully built and tagged image." @echo "Tag: $(DOCKER_IMG_TAG)" build/local: ## Build local version of the operator Docker image - @docker build -f Dockerfile -t local/$(DOCKER_IMG_TAG) + @docker build -f Dockerfile -t local/$(DOCKER_IMG_TAG) . build/binary: clean ## Build operator binary @mkdir -p dist From 9441214733e472fdb229d282cfc133dc19265659 Mon Sep 17 00:00:00 2001 From: Eddy Filip Date: Wed, 9 Jun 2021 20:45:33 +0300 Subject: [PATCH 3/3] Add support custom namespace for connect deployment Now when the operator is deployed with the `MANAGE_CONNECT` env var set to true, the connect instance is deployed in the same namespace as the operator. --- cmd/manager/main.go | 8 +++++- deploy/connect/deployment.yaml | 1 - deploy/connect/service.yaml | 1 - pkg/onepassword/connect_setup.go | 39 ++++++++++++++++----------- pkg/onepassword/connect_setup_test.go | 4 +-- 5 files changed, 33 insertions(+), 20 deletions(-) diff --git a/cmd/manager/main.go b/cmd/manager/main.go index 9e62460..2d7904c 100644 --- a/cmd/manager/main.go +++ b/cmd/manager/main.go @@ -85,6 +85,12 @@ func main() { namespace := os.Getenv(k8sutil.WatchNamespaceEnvVar) + deploymentNamespace, err := k8sutil.GetOperatorNamespace() + if err != nil { + log.Error(err, "Failed to get namespace") + os.Exit(1) + } + // Get a config to talk to the apiserver cfg, err := config.GetConfig() if err != nil { @@ -135,7 +141,7 @@ func main() { go func() { connectStarted := false for connectStarted == false { - err := op.SetupConnect(mgr.GetClient()) + err := op.SetupConnect(mgr.GetClient(), deploymentNamespace) // Cache Not Started is an acceptable error. Retry until cache is started. if err != nil && !errors.Is(err, &cache.ErrCacheNotStarted{}) { log.Error(err, "") diff --git a/deploy/connect/deployment.yaml b/deploy/connect/deployment.yaml index b0d3869..a68d624 100644 --- a/deploy/connect/deployment.yaml +++ b/deploy/connect/deployment.yaml @@ -2,7 +2,6 @@ apiVersion: apps/v1 kind: Deployment metadata: name: onepassword-connect - namespace: default spec: selector: matchLabels: diff --git a/deploy/connect/service.yaml b/deploy/connect/service.yaml index 441d77b..8b154ac 100644 --- a/deploy/connect/service.yaml +++ b/deploy/connect/service.yaml @@ -2,7 +2,6 @@ apiVersion: v1 kind: Service metadata: name: onepassword-connect - namespace: default spec: type: NodePort selector: diff --git a/pkg/onepassword/connect_setup.go b/pkg/onepassword/connect_setup.go index 37c5751..ade8caa 100644 --- a/pkg/onepassword/connect_setup.go +++ b/pkg/onepassword/connect_setup.go @@ -2,6 +2,7 @@ package onepassword import ( "context" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "os" appsv1 "k8s.io/api/apps/v1" @@ -17,13 +18,13 @@ var logConnectSetup = logf.Log.WithName("ConnectSetup") var deploymentPath = "deploy/connect/deployment.yaml" var servicePath = "deploy/connect/service.yaml" -func SetupConnect(kubeClient client.Client) error { - err := setupService(kubeClient, servicePath) +func SetupConnect(kubeClient client.Client, deploymentNamespace string) error { + err := setupService(kubeClient, servicePath, deploymentNamespace) if err != nil { return err } - err = setupDeployment(kubeClient, deploymentPath) + err = setupDeployment(kubeClient, deploymentPath, deploymentNamespace) if err != nil { return err } @@ -31,22 +32,22 @@ func SetupConnect(kubeClient client.Client) error { return nil } -func setupDeployment(kubeClient client.Client, deploymentPath string) error { +func setupDeployment(kubeClient client.Client, deploymentPath string, deploymentNamespace string) error { existingDeployment := &appsv1.Deployment{} // check if deployment has already been created - err := kubeClient.Get(context.Background(), types.NamespacedName{Name: "onepassword-connect", Namespace: "default"}, existingDeployment) + err := kubeClient.Get(context.Background(), types.NamespacedName{Name: "onepassword-connect", Namespace: deploymentNamespace}, existingDeployment) if err != nil { if errors.IsNotFound(err) { logConnectSetup.Info("No existing Connect deployment found. Creating Deployment") - return createDeployment(kubeClient, deploymentPath) + return createDeployment(kubeClient, deploymentPath, deploymentNamespace) } } return err } -func createDeployment(kubeClient client.Client, deploymentPath string) error { - deployment, err := getDeploymentToCreate(deploymentPath) +func createDeployment(kubeClient client.Client, deploymentPath string, deploymentNamespace string) error { + deployment, err := getDeploymentToCreate(deploymentPath, deploymentNamespace) if err != nil { return err } @@ -59,12 +60,16 @@ func createDeployment(kubeClient client.Client, deploymentPath string) error { return nil } -func getDeploymentToCreate(deploymentPath string) (*appsv1.Deployment, error) { +func getDeploymentToCreate(deploymentPath string, deploymentNamespace string) (*appsv1.Deployment, error) { f, err := os.Open(deploymentPath) if err != nil { return nil, err } - deployment := &appsv1.Deployment{} + deployment := &appsv1.Deployment{ + ObjectMeta: v1.ObjectMeta{ + Namespace: deploymentNamespace, + }, + } err = yaml.NewYAMLOrJSONDecoder(f, 4096).Decode(deployment) if err != nil { @@ -73,26 +78,30 @@ func getDeploymentToCreate(deploymentPath string) (*appsv1.Deployment, error) { return deployment, nil } -func setupService(kubeClient client.Client, servicePath string) error { +func setupService(kubeClient client.Client, servicePath string, deploymentNamespace string) error { existingService := &corev1.Service{} //check if service has already been created - err := kubeClient.Get(context.Background(), types.NamespacedName{Name: "onepassword-connect", Namespace: "default"}, existingService) + err := kubeClient.Get(context.Background(), types.NamespacedName{Name: "onepassword-connect", Namespace: deploymentNamespace}, existingService) if err != nil { if errors.IsNotFound(err) { logConnectSetup.Info("No existing Connect service found. Creating Service") - return createService(kubeClient, servicePath) + return createService(kubeClient, servicePath, deploymentNamespace) } } return err } -func createService(kubeClient client.Client, servicePath string) error { +func createService(kubeClient client.Client, servicePath string, deploymentNamespace string) error { f, err := os.Open(servicePath) if err != nil { return err } - service := &corev1.Service{} + service := &corev1.Service{ + ObjectMeta: v1.ObjectMeta{ + Namespace: deploymentNamespace, + }, + } err = yaml.NewYAMLOrJSONDecoder(f, 4096).Decode(service) if err != nil { diff --git a/pkg/onepassword/connect_setup_test.go b/pkg/onepassword/connect_setup_test.go index d917e46..03e9daa 100644 --- a/pkg/onepassword/connect_setup_test.go +++ b/pkg/onepassword/connect_setup_test.go @@ -25,7 +25,7 @@ func TestServiceSetup(t *testing.T) { // Create a fake client to mock API calls. client := fake.NewFakeClientWithScheme(s, objs...) - err := setupService(client, "../../deploy/connect/service.yaml") + err := setupService(client, "../../deploy/connect/service.yaml", defaultNamespacedName.Namespace) if err != nil { t.Errorf("Error Setting Up Connect: %v", err) @@ -50,7 +50,7 @@ func TestDeploymentSetup(t *testing.T) { // Create a fake client to mock API calls. client := fake.NewFakeClientWithScheme(s, objs...) - err := setupDeployment(client, "../../deploy/connect/deployment.yaml") + err := setupDeployment(client, "../../deploy/connect/deployment.yaml", defaultNamespacedName.Namespace) if err != nil { t.Errorf("Error Setting Up Connect: %v", err)