From 5b0e2ea66de1a5cf453af241c950b01aed0882b9 Mon Sep 17 00:00:00 2001 From: Sergey Dudoladov Date: Tue, 13 Feb 2018 13:39:49 +0100 Subject: [PATCH 01/11] Fetch operator configmap from operator's namespace --- cmd/main.go | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/cmd/main.go b/cmd/main.go index 7bb501885..6a6fdc163 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -4,6 +4,7 @@ import ( "flag" "log" "os" + "os/exec" "os/signal" "sync" "syscall" @@ -27,13 +28,26 @@ func init() { flag.BoolVar(&config.NoTeamsAPI, "noteamsapi", false, "Disable all access to the teams API") flag.Parse() + cmd := exec.Command("cat", "/var/run/secrets/kubernetes.io/serviceaccount/namespace") + operatorNamespaceBytes, err := cmd.Output() + if err != nil { + log.Fatalf("Unable to detect operator namespace from within its pod due to %v", err) + } + configMapRawName := os.Getenv("CONFIG_MAP_NAME") if configMapRawName != "" { - err := config.ConfigMapName.Decode(configMapRawName) + + operatorNamespace := string(operatorNamespaceBytes) + namespacedConfigMapName := operatorNamespace + "/" + configMapRawName + log.Printf("Looking for the operator configmap at the same namespace the operator resides. Fully qualified configmap name: %v", namespacedConfigMapName) + + err := config.ConfigMapName.Decode(namespacedConfigMapName) if err != nil { log.Fatalf("incorrect config map name") } + } + } func main() { From dc4229e84d25f86b297c4b14daf2b9fe48435769 Mon Sep 17 00:00:00 2001 From: Sergey Dudoladov Date: Tue, 13 Feb 2018 15:51:12 +0100 Subject: [PATCH 02/11] Include review comments --- cmd/main.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index 6a6fdc163..0ac5817bb 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -2,9 +2,9 @@ package main import ( "flag" + "io/ioutil" "log" "os" - "os/exec" "os/signal" "sync" "syscall" @@ -28,8 +28,7 @@ func init() { flag.BoolVar(&config.NoTeamsAPI, "noteamsapi", false, "Disable all access to the teams API") flag.Parse() - cmd := exec.Command("cat", "/var/run/secrets/kubernetes.io/serviceaccount/namespace") - operatorNamespaceBytes, err := cmd.Output() + operatorNamespaceBytes, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace") if err != nil { log.Fatalf("Unable to detect operator namespace from within its pod due to %v", err) } @@ -43,7 +42,7 @@ func init() { err := config.ConfigMapName.Decode(namespacedConfigMapName) if err != nil { - log.Fatalf("incorrect config map name") + log.Fatalf("incorrect config map name: %v", namespacedConfigMapName) } } From 06fd9e33f5e7a9ff8b9483729d66aa935c9653f1 Mon Sep 17 00:00:00 2001 From: Sergey Dudoladov Date: Tue, 13 Feb 2018 18:17:47 +0100 Subject: [PATCH 03/11] Watch the namespace where operator deploys to unless told otherwise --- cmd/main.go | 3 +++ pkg/controller/controller.go | 9 +++++++-- pkg/util/k8sutil/k8sutil.go | 2 ++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index 0ac5817bb..0805e08b4 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -37,7 +37,10 @@ func init() { if configMapRawName != "" { operatorNamespace := string(operatorNamespaceBytes) + config.Namespace = operatorNamespace + namespacedConfigMapName := operatorNamespace + "/" + configMapRawName + log.Printf("Looking for the operator configmap at the same namespace the operator resides. Fully qualified configmap name: %v", namespacedConfigMapName) err := config.ConfigMapName.Decode(namespacedConfigMapName) diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index c697217e4..00f9bb21c 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -105,8 +105,13 @@ func (c *Controller) initOperatorConfig() { } if configMapData["watched_namespace"] == "" { - c.logger.Infoln("No namespace to watch specified. Fall back to watching the 'default' namespace.") - configMapData["watched_namespace"] = v1.NamespaceDefault + c.logger.Infof("No namespace to watch specified. By convention, the operator falls back to watching the namespace it is deployed to: '%v' \n", c.config.Namespace) + configMapData["watched_namespace"] = c.config.Namespace + } + + _, err := c.KubeClient.ServiceAccounts(configMapData["watched_namespace"]).Get("operator", metav1.GetOptions{}) + if err != nil { + c.logger.Warnf("Cannot find the 'operator' service account in the watched namepsace %q. Pods will not be able to start. Error: %v", c.opConfig.WatchedNamespace, err) } if c.config.NoDatabaseAccess { diff --git a/pkg/util/k8sutil/k8sutil.go b/pkg/util/k8sutil/k8sutil.go index 1b4dc9a00..5db47c76b 100644 --- a/pkg/util/k8sutil/k8sutil.go +++ b/pkg/util/k8sutil/k8sutil.go @@ -32,6 +32,7 @@ type KubernetesClient struct { v1core.PersistentVolumeClaimsGetter v1core.ConfigMapsGetter v1core.NodesGetter + v1core.ServiceAccountsGetter v1beta1.StatefulSetsGetter policyv1beta1.PodDisruptionBudgetsGetter apiextbeta1.CustomResourceDefinitionsGetter @@ -72,6 +73,7 @@ func NewFromConfig(cfg *rest.Config) (KubernetesClient, error) { kubeClient.ServicesGetter = client.CoreV1() kubeClient.EndpointsGetter = client.CoreV1() kubeClient.SecretsGetter = client.CoreV1() + kubeClient.ServiceAccountsGetter = client.CoreV1() kubeClient.ConfigMapsGetter = client.CoreV1() kubeClient.PersistentVolumeClaimsGetter = client.CoreV1() kubeClient.PersistentVolumesGetter = client.CoreV1() From 5837015b3c2c981e4005021494aeedc6da847a11 Mon Sep 17 00:00:00 2001 From: Sergey Dudoladov Date: Wed, 14 Feb 2018 11:43:09 +0100 Subject: [PATCH 04/11] Add the fileWithNamespace const --- cmd/main.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cmd/main.go b/cmd/main.go index 0805e08b4..d398ada11 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -14,6 +14,11 @@ import ( "github.com/zalando-incubator/postgres-operator/pkg/util/k8sutil" ) +const ( + // assumes serviceaccount secret is mounted by kubernetes + fileWithNamespace = "/var/run/secrets/kubernetes.io/serviceaccount/namespace" +) + var ( kubeConfigFile string outOfCluster bool @@ -28,7 +33,7 @@ func init() { flag.BoolVar(&config.NoTeamsAPI, "noteamsapi", false, "Disable all access to the teams API") flag.Parse() - operatorNamespaceBytes, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace") + operatorNamespaceBytes, err := ioutil.ReadFile(fileWithNamespace) if err != nil { log.Fatalf("Unable to detect operator namespace from within its pod due to %v", err) } From d5d15b7546e3a030ac2dadf42771b064d89b95d4 Mon Sep 17 00:00:00 2001 From: Sergey Dudoladov Date: Wed, 14 Feb 2018 15:37:30 +0100 Subject: [PATCH 05/11] Look for secrets in the deployed namespace --- README.md | 17 +++++++++++++++++ cmd/main.go | 13 +------------ pkg/controller/controller.go | 19 +++++++++++++------ pkg/spec/types.go | 22 +++++++++++++++++++--- 4 files changed, 50 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index aba0bd183..de68f03ac 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,23 @@ to test your that your setup is working. Note: if you use multiple Kubernetes clusters, you can switch to Minikube with `kubectl config use-context minikube` +### Select the namespace to deploy to + +The operator can run in a namespace other than `default`. For example, to deploy it to the `test` namespace, run the following: + + kubectl create namespace test + kubectl config set-context minikube --namespace=test + +All subsequent `kubectl` commands will work with the `test` namespace. The operator will run in this namespace and look up needed resources - such as its config map - there. + +### Specify the namespace to watch + +Watching a namespace for an operator means tracking requests to change Postgresql clusters in the namespace such as "increase the number of Postgresql replicas to 5" and reacting to the requests, in this example by actually scaling up. + +By default, the operator watches the namespace it is deployed to. You can change this by altering the `WATCHED_NAMESPACE` env var in the operator deployment manifest or the `watched_namespace` field in the operator configmap. In the case both are set, the env var takes the preference. + +Note that for an operator to create pods in the watched namespace, one needs to create the `operator` service account in the namespace. + ### Create ConfigMap ConfigMap is used to store the configuration of the operator diff --git a/cmd/main.go b/cmd/main.go index d398ada11..bdfdf862c 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -2,7 +2,6 @@ package main import ( "flag" - "io/ioutil" "log" "os" "os/signal" @@ -14,11 +13,6 @@ import ( "github.com/zalando-incubator/postgres-operator/pkg/util/k8sutil" ) -const ( - // assumes serviceaccount secret is mounted by kubernetes - fileWithNamespace = "/var/run/secrets/kubernetes.io/serviceaccount/namespace" -) - var ( kubeConfigFile string outOfCluster bool @@ -33,15 +27,10 @@ func init() { flag.BoolVar(&config.NoTeamsAPI, "noteamsapi", false, "Disable all access to the teams API") flag.Parse() - operatorNamespaceBytes, err := ioutil.ReadFile(fileWithNamespace) - if err != nil { - log.Fatalf("Unable to detect operator namespace from within its pod due to %v", err) - } - configMapRawName := os.Getenv("CONFIG_MAP_NAME") if configMapRawName != "" { - operatorNamespace := string(operatorNamespaceBytes) + operatorNamespace := spec.GetOperatorNamespace() config.Namespace = operatorNamespace namespacedConfigMapName := operatorNamespace + "/" + configMapRawName diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index 00f9bb21c..b697ce42c 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -105,15 +105,10 @@ func (c *Controller) initOperatorConfig() { } if configMapData["watched_namespace"] == "" { - c.logger.Infof("No namespace to watch specified. By convention, the operator falls back to watching the namespace it is deployed to: '%v' \n", c.config.Namespace) + c.logger.Infof("No namespace to watch specified. By convention, the operator falls back to watching the namespace it is deployed to: '%v' \n", c.config.Namespace) configMapData["watched_namespace"] = c.config.Namespace } - _, err := c.KubeClient.ServiceAccounts(configMapData["watched_namespace"]).Get("operator", metav1.GetOptions{}) - if err != nil { - c.logger.Warnf("Cannot find the 'operator' service account in the watched namepsace %q. Pods will not be able to start. Error: %v", c.opConfig.WatchedNamespace, err) - } - if c.config.NoDatabaseAccess { configMapData["enable_database_access"] = "false" } @@ -136,6 +131,11 @@ func (c *Controller) initController() { c.logger.Infof("config: %s", c.opConfig.MustMarshal()) + c.mustHaveOperatorServiceAccountInNamespace(c.config.Namespace) + if c.config.Namespace != c.opConfig.WatchedNamespace { + c.mustHaveOperatorServiceAccountInNamespace(c.opConfig.WatchedNamespace) + } + if c.opConfig.DebugLogging { c.logger.Logger.Level = logrus.DebugLevel } @@ -261,3 +261,10 @@ func (c *Controller) kubeNodesInformer(stopCh <-chan struct{}, wg *sync.WaitGrou c.nodesInformer.Run(stopCh) } + +func (c *Controller) mustHaveOperatorServiceAccountInNamespace(namespace string) { + _, err := c.KubeClient.ServiceAccounts(namespace).Get(c.opConfig.ServiceAccountName, metav1.GetOptions{}) + if err != nil { + c.logger.Warnf("Cannot find the '%v' service account in the namepsace %q. Pods will not be able to start. Error: %v", c.opConfig.ServiceAccountName, namespace, err) + } +} diff --git a/pkg/spec/types.go b/pkg/spec/types.go index 3eb6e7fa7..7694e4ca2 100644 --- a/pkg/spec/types.go +++ b/pkg/spec/types.go @@ -3,6 +3,8 @@ package spec import ( "database/sql" "fmt" + "io/ioutil" + "log" "strings" "time" @@ -26,6 +28,8 @@ const ( EventUpdate EventType = "UPDATE" EventDelete EventType = "DELETE" EventSync EventType = "SYNC" + + fileWithNamespace = "/var/run/secrets/kubernetes.io/serviceaccount/namespace" ) // ClusterEvent carries the payload of the Cluster TPR events. @@ -165,16 +169,28 @@ func (n *NamespacedName) Decode(value string) error { if strings.Trim(value, string(types.Separator)) != "" && name == (types.NamespacedName{}) { name.Name = value - name.Namespace = v1.NamespaceDefault + name.Namespace = GetOperatorNamespace() } else if name.Namespace == "" { - name.Namespace = v1.NamespaceDefault + name.Namespace = GetOperatorNamespace() } if name.Name == "" { - return fmt.Errorf("incorrect namespaced name") + return fmt.Errorf("incorrect namespaced name: %v", value) } *n = NamespacedName(name) return nil } + +// GetOperatorNamespace assumes serviceaccount secret is mounted by kubernetes +// Placing this func here instead of pgk/util avoids circular import +func GetOperatorNamespace() string { + + operatorNamespaceBytes, err := ioutil.ReadFile(fileWithNamespace) + if err != nil { + log.Fatalf("Unable to detect operator namespace from within its pod due to: %v", err) + } + + return string(operatorNamespaceBytes) +} From fab1e3418289485595149cfad4d2f783d4671178 Mon Sep 17 00:00:00 2001 From: Sergey Dudoladov Date: Thu, 15 Feb 2018 10:43:06 +0100 Subject: [PATCH 06/11] Respond to code review comments --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index de68f03ac..517db4cb9 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ Note: if you use multiple Kubernetes clusters, you can switch to Minikube with ` ### Select the namespace to deploy to -The operator can run in a namespace other than `default`. For example, to deploy it to the `test` namespace, run the following: +The operator can run in a namespace other than `default`. For example, to use the `test` namespace, run the following before deploying the operator's manifests: kubectl create namespace test kubectl config set-context minikube --namespace=test @@ -74,7 +74,7 @@ All subsequent `kubectl` commands will work with the `test` namespace. The opera Watching a namespace for an operator means tracking requests to change Postgresql clusters in the namespace such as "increase the number of Postgresql replicas to 5" and reacting to the requests, in this example by actually scaling up. -By default, the operator watches the namespace it is deployed to. You can change this by altering the `WATCHED_NAMESPACE` env var in the operator deployment manifest or the `watched_namespace` field in the operator configmap. In the case both are set, the env var takes the preference. +By default, the operator watches the namespace it is deployed to. You can change this by altering the `WATCHED_NAMESPACE` env var in the operator deployment manifest or the `watched_namespace` field in the operator configmap. In the case both are set, the env var takes the precedence. Note that for an operator to create pods in the watched namespace, one needs to create the `operator` service account in the namespace. From 155ae8d50ff791998bc397812f7d56e504e1fcd7 Mon Sep 17 00:00:00 2001 From: Sergey Dudoladov Date: Thu, 15 Feb 2018 11:14:13 +0100 Subject: [PATCH 07/11] Rename the function that checks service account existence --- pkg/controller/controller.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index b697ce42c..2abc4a6c6 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -131,9 +131,9 @@ func (c *Controller) initController() { c.logger.Infof("config: %s", c.opConfig.MustMarshal()) - c.mustHaveOperatorServiceAccountInNamespace(c.config.Namespace) + c.checkOperatorServiceAccount(c.config.Namespace) if c.config.Namespace != c.opConfig.WatchedNamespace { - c.mustHaveOperatorServiceAccountInNamespace(c.opConfig.WatchedNamespace) + c.checkOperatorServiceAccount(c.opConfig.WatchedNamespace) } if c.opConfig.DebugLogging { @@ -262,9 +262,10 @@ func (c *Controller) kubeNodesInformer(stopCh <-chan struct{}, wg *sync.WaitGrou c.nodesInformer.Run(stopCh) } -func (c *Controller) mustHaveOperatorServiceAccountInNamespace(namespace string) { +// Check that a namespace has the service account that the operator needs +func (c *Controller) checkOperatorServiceAccount(namespace string) { _, err := c.KubeClient.ServiceAccounts(namespace).Get(c.opConfig.ServiceAccountName, metav1.GetOptions{}) if err != nil { - c.logger.Warnf("Cannot find the '%v' service account in the namepsace %q. Pods will not be able to start. Error: %v", c.opConfig.ServiceAccountName, namespace, err) + c.logger.Warnf("Cannot find the '%v' service account needed for operator in the namespace %q. Pods will not be able to start. Error: %v", c.opConfig.ServiceAccountName, namespace, err) } } From 44a2812f5a5f58e938e380d5e04ec534de78963c Mon Sep 17 00:00:00 2001 From: Sergey Dudoladov Date: Thu, 15 Feb 2018 15:48:35 +0100 Subject: [PATCH 08/11] Update docs to clarify different service accounts --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 517db4cb9..fdb9ec708 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ Watching a namespace for an operator means tracking requests to change Postgresq By default, the operator watches the namespace it is deployed to. You can change this by altering the `WATCHED_NAMESPACE` env var in the operator deployment manifest or the `watched_namespace` field in the operator configmap. In the case both are set, the env var takes the precedence. -Note that for an operator to create pods in the watched namespace, one needs to create the `operator` service account in the namespace. +Note that for an operator to manage pods in the watched namespace, the operator's service account (as specified in the operator deployment manifest) has to have appropriate privileges to access the watched namespace. The watched namespace also needs to have a (possibly different) service account that allows database pods to talk to the Kubernetes API. ### Create ConfigMap From 5e9a21456ec3a3922f78c287e284aafd9bb3f91a Mon Sep 17 00:00:00 2001 From: Sergey Dudoladov Date: Thu, 15 Feb 2018 16:33:53 +0100 Subject: [PATCH 09/11] Remove the incorrect service account check --- pkg/controller/controller.go | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index 2abc4a6c6..3b63b068b 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -131,11 +131,6 @@ func (c *Controller) initController() { c.logger.Infof("config: %s", c.opConfig.MustMarshal()) - c.checkOperatorServiceAccount(c.config.Namespace) - if c.config.Namespace != c.opConfig.WatchedNamespace { - c.checkOperatorServiceAccount(c.opConfig.WatchedNamespace) - } - if c.opConfig.DebugLogging { c.logger.Logger.Level = logrus.DebugLevel } @@ -261,11 +256,3 @@ func (c *Controller) kubeNodesInformer(stopCh <-chan struct{}, wg *sync.WaitGrou c.nodesInformer.Run(stopCh) } - -// Check that a namespace has the service account that the operator needs -func (c *Controller) checkOperatorServiceAccount(namespace string) { - _, err := c.KubeClient.ServiceAccounts(namespace).Get(c.opConfig.ServiceAccountName, metav1.GetOptions{}) - if err != nil { - c.logger.Warnf("Cannot find the '%v' service account needed for operator in the namespace %q. Pods will not be able to start. Error: %v", c.opConfig.ServiceAccountName, namespace, err) - } -} From 0a9e6bd8d218b4753354dbcf9ae75e2e6b955373 Mon Sep 17 00:00:00 2001 From: Sergey Dudoladov Date: Thu, 15 Feb 2018 16:40:07 +0100 Subject: [PATCH 10/11] Clarify when a separate account for database pods may be needed --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fdb9ec708..27cb2e5b3 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ Watching a namespace for an operator means tracking requests to change Postgresq By default, the operator watches the namespace it is deployed to. You can change this by altering the `WATCHED_NAMESPACE` env var in the operator deployment manifest or the `watched_namespace` field in the operator configmap. In the case both are set, the env var takes the precedence. -Note that for an operator to manage pods in the watched namespace, the operator's service account (as specified in the operator deployment manifest) has to have appropriate privileges to access the watched namespace. The watched namespace also needs to have a (possibly different) service account that allows database pods to talk to the Kubernetes API. +Note that for an operator to manage pods in the watched namespace, the operator's service account (as specified in the operator deployment manifest) has to have appropriate privileges to access the watched namespace. The watched namespace also needs to have a (possibly different) service account in the case database pods need to talk to the Kubernetes API (e.g. when using Kubernetes-native configuration of Patroni). ### Create ConfigMap From bbe2801d6985a7140c1e8235275edd6140b93630 Mon Sep 17 00:00:00 2001 From: Sergey Dudoladov Date: Fri, 16 Feb 2018 11:13:08 +0100 Subject: [PATCH 11/11] Adjust unit tests for namespace decoding --- pkg/spec/types.go | 10 ++++++++-- pkg/spec/types_test.go | 16 +++++++++++----- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/pkg/spec/types.go b/pkg/spec/types.go index 7694e4ca2..7a3078674 100644 --- a/pkg/spec/types.go +++ b/pkg/spec/types.go @@ -165,13 +165,19 @@ func (n NamespacedName) MarshalJSON() ([]byte, error) { // Decode converts a (possibly unqualified) string into the namespaced name object. func (n *NamespacedName) Decode(value string) error { + return n.DecodeWorker(value, GetOperatorNamespace()) +} + +// DecodeWorker separates the decode logic to (unit) test +// from obtaining the operator namespace that depends on k8s mounting files at runtime +func (n *NamespacedName) DecodeWorker(value, operatorNamespace string) error { name := types.NewNamespacedNameFromString(value) if strings.Trim(value, string(types.Separator)) != "" && name == (types.NamespacedName{}) { name.Name = value - name.Namespace = GetOperatorNamespace() + name.Namespace = operatorNamespace } else if name.Namespace == "" { - name.Namespace = GetOperatorNamespace() + name.Namespace = operatorNamespace } if name.Name == "" { diff --git a/pkg/spec/types_test.go b/pkg/spec/types_test.go index 05045445b..7611501ad 100644 --- a/pkg/spec/types_test.go +++ b/pkg/spec/types_test.go @@ -5,22 +5,27 @@ import ( "testing" ) +const ( + mockOperatorNamespace = "acid" +) + var nnTests = []struct { s string expected NamespacedName expectedMarshal []byte }{ - {`acid/cluster`, NamespacedName{Namespace: "acid", Name: "cluster"}, []byte(`"acid/cluster"`)}, - {`/name`, NamespacedName{Namespace: "default", Name: "name"}, []byte(`"default/name"`)}, - {`test`, NamespacedName{Namespace: "default", Name: "test"}, []byte(`"default/test"`)}, + {`acid/cluster`, NamespacedName{Namespace: mockOperatorNamespace, Name: "cluster"}, []byte(`"acid/cluster"`)}, + {`/name`, NamespacedName{Namespace: mockOperatorNamespace, Name: "name"}, []byte(`"acid/name"`)}, + {`test`, NamespacedName{Namespace: mockOperatorNamespace, Name: "test"}, []byte(`"acid/test"`)}, } var nnErr = []string{"test/", "/", "", "//"} func TestNamespacedNameDecode(t *testing.T) { + for _, tt := range nnTests { var actual NamespacedName - err := actual.Decode(tt.s) + err := actual.DecodeWorker(tt.s, mockOperatorNamespace) if err != nil { t.Errorf("decode error: %v", err) } @@ -28,6 +33,7 @@ func TestNamespacedNameDecode(t *testing.T) { t.Errorf("expected: %v, got %#v", tt.expected, actual) } } + } func TestNamespacedNameMarshal(t *testing.T) { @@ -47,7 +53,7 @@ func TestNamespacedNameMarshal(t *testing.T) { func TestNamespacedNameError(t *testing.T) { for _, tt := range nnErr { var actual NamespacedName - err := actual.Decode(tt) + err := actual.DecodeWorker(tt, mockOperatorNamespace) if err == nil { t.Errorf("error expected for %q, got: %#v", tt, actual) }