From e3572d3d4b68b62f62ba01dcfa738265c7bb1763 Mon Sep 17 00:00:00 2001 From: Seshachalam Yerasala Venkata Date: Mon, 27 Feb 2023 19:23:07 +0530 Subject: [PATCH 1/6] Add rolebinding component - Add utils function `GetRoleBindingName` - Add unit tests for RoleBinding component --- pkg/component/etcd/rolebinding/rolebinding.go | 80 ++++++++++ .../rolebinding/rolebinding_suite_test.go | 27 ++++ .../etcd/rolebinding/rolebinding_test.go | 145 ++++++++++++++++++ .../etcd/rolebinding/value_helper_test.go | 67 ++++++++ pkg/component/etcd/rolebinding/values.go | 32 ++++ .../etcd/rolebinding/values_helper.go | 32 ++++ 6 files changed, 383 insertions(+) create mode 100644 pkg/component/etcd/rolebinding/rolebinding.go create mode 100644 pkg/component/etcd/rolebinding/rolebinding_suite_test.go create mode 100644 pkg/component/etcd/rolebinding/rolebinding_test.go create mode 100644 pkg/component/etcd/rolebinding/value_helper_test.go create mode 100644 pkg/component/etcd/rolebinding/values.go create mode 100644 pkg/component/etcd/rolebinding/values_helper.go diff --git a/pkg/component/etcd/rolebinding/rolebinding.go b/pkg/component/etcd/rolebinding/rolebinding.go new file mode 100644 index 000000000..2b4b9cd72 --- /dev/null +++ b/pkg/component/etcd/rolebinding/rolebinding.go @@ -0,0 +1,80 @@ +// Copyright (c) 2023 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file +// +// 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 rolebinding + +import ( + "context" + + "github.com/gardener/gardener/pkg/controllerutils" + + gardenercomponent "github.com/gardener/gardener/pkg/operation/botanist/component" + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +type component struct { + client client.Client + values *Values +} + +func (c *component) Deploy(ctx context.Context) error { + roleBinding := c.emptyRoleBinding() + _, err := controllerutils.GetAndCreateOrStrategicMergePatch(ctx, c.client, roleBinding, func() error { + roleBinding.Name = c.values.Name + roleBinding.Namespace = c.values.Namespace + roleBinding.Labels = c.values.Labels + roleBinding.OwnerReferences = c.values.OwnerReferences + roleBinding.RoleRef = rbacv1.RoleRef{ + APIGroup: "rbac.authorization.k8s.io", + Kind: "Role", + Name: c.values.RoleName, + } + roleBinding.Subjects = []rbacv1.Subject{ + { + Kind: "ServiceAccount", + Name: c.values.ServiceAccountName, + Namespace: c.values.Namespace, + }, + } + return nil + }) + return err +} + +func (c *component) Destroy(ctx context.Context) error { + roleBinding := c.emptyRoleBinding() + if err := client.IgnoreNotFound(c.client.Delete(ctx, roleBinding)); err != nil { + return err + } + return nil +} + +func (c *component) emptyRoleBinding() *rbacv1.RoleBinding { + return &rbacv1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: c.values.Name, + Namespace: c.values.Namespace, + }, + } +} + +// New creates a new role binding deployer instance. +func New(c client.Client, value *Values) gardenercomponent.Deployer { + return &component{ + client: c, + values: value, + } +} diff --git a/pkg/component/etcd/rolebinding/rolebinding_suite_test.go b/pkg/component/etcd/rolebinding/rolebinding_suite_test.go new file mode 100644 index 000000000..5fb0a766e --- /dev/null +++ b/pkg/component/etcd/rolebinding/rolebinding_suite_test.go @@ -0,0 +1,27 @@ +// Copyright (c) 2023 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file +// +// 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 rolebinding + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestService(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "RoleBinding Component Suite") +} diff --git a/pkg/component/etcd/rolebinding/rolebinding_test.go b/pkg/component/etcd/rolebinding/rolebinding_test.go new file mode 100644 index 000000000..987a4ad0a --- /dev/null +++ b/pkg/component/etcd/rolebinding/rolebinding_test.go @@ -0,0 +1,145 @@ +// Copyright (c) 2023 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file +// +// 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 rolebinding_test + +import ( + "context" + + "github.com/gardener/etcd-druid/pkg/client/kubernetes" + "github.com/gardener/etcd-druid/pkg/component/etcd/rolebinding" + + "github.com/gardener/gardener/pkg/operation/botanist/component" + . "github.com/gardener/gardener/pkg/utils/test/matchers" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + rbacv1 "k8s.io/api/rbac/v1" + "k8s.io/apimachinery/pkg/types" + + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/fake" +) + +var _ = Describe("RoleBinding Component", func() { + var ( + ctx context.Context + c client.Client + value *rolebinding.Values + roleBindingComponent component.Deployer + ) + + BeforeEach(func() { + ctx = context.TODO() + c = fake.NewClientBuilder().WithScheme(kubernetes.Scheme).Build() + value = getTestValue() + roleBindingComponent = rolebinding.New(c, value) + }) + + Describe("#Deploy", func() { + AfterEach(func() { + Expect(roleBindingComponent.Destroy(ctx)).NotTo(HaveOccurred()) + }) + + It("should create and update the RoleBinding with the expected values", func() { + By("creating a RoleBinding") + err := roleBindingComponent.Deploy(ctx) + Expect(err).NotTo(HaveOccurred()) + + By("verifying that the RoleBinding is created on the K8s cluster as expected") + created := &rbacv1.RoleBinding{} + err = c.Get(ctx, getRoleBindingKeyFromValue(value), created) + Expect(err).NotTo(HaveOccurred()) + verifyRoleBindingValues(created, value) + + By("updating the RoleBinding") + err = roleBindingComponent.Deploy(ctx) + Expect(err).NotTo(HaveOccurred()) + + By("verifying that the RoleBinding is updated on the K8s cluster as expected") + updated := &rbacv1.RoleBinding{} + err = c.Get(ctx, getRoleBindingKeyFromValue(value), updated) + Expect(err).NotTo(HaveOccurred()) + verifyRoleBindingValues(updated, value) + + By("returning nil when there is nothing to update the RoleBinding") + err = roleBindingComponent.Deploy(ctx) + Expect(err).NotTo(HaveOccurred()) + updated = &rbacv1.RoleBinding{} + err = c.Get(ctx, getRoleBindingKeyFromValue(value), updated) + Expect(err).NotTo(HaveOccurred()) + verifyRoleBindingValues(updated, value) + + By("returning an error when the update fails") + value.Name = "" + err = roleBindingComponent.Deploy(ctx) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("Required value: name is required")) + }) + }) + + Describe("#Destroy", func() { + BeforeEach(func() { + Expect(roleBindingComponent.Deploy(ctx)).NotTo(HaveOccurred()) + }) + + It("should delete the RoleBinding", func() { + roleBinding := &rbacv1.RoleBinding{} + By("checking that the RoleBinding exists before deleting it") + Expect(c.Get(ctx, getRoleBindingKeyFromValue(value), roleBinding)).NotTo(HaveOccurred()) + + By("deleting the RoleBinding") + err := roleBindingComponent.Destroy(ctx) + Expect(err).NotTo(HaveOccurred()) + + By("verifying that the RoleBinding is deleted from the K8s cluster as expected") + Expect(c.Get(ctx, getRoleBindingKeyFromValue(value), roleBinding)).To(BeNotFoundError()) + + By("returning nil when there is nothing to delete") + err = roleBindingComponent.Destroy(ctx) + Expect(err).To(BeNil()) + }) + }) +}) + +func verifyRoleBindingValues(expected *rbacv1.RoleBinding, values *rolebinding.Values) { + Expect(expected.Name).To(Equal(values.Name)) + Expect(expected.Labels).To(Equal(values.Labels)) + Expect(expected.Namespace).To(Equal(values.Namespace)) + Expect(expected.Namespace).To(Equal(values.Namespace)) + Expect(expected.Subjects).To(Equal([]rbacv1.Subject{ + { + Kind: "ServiceAccount", + Name: values.ServiceAccountName, + Namespace: values.Namespace, + }, + })) + Expect(expected.RoleRef).To(Equal(rbacv1.RoleRef{ + APIGroup: "rbac.authorization.k8s.io", + Kind: "Role", + Name: values.RoleName, + })) +} +func getRoleBindingKeyFromValue(value *rolebinding.Values) types.NamespacedName { + return client.ObjectKey{Name: value.Name, Namespace: value.Namespace} +} + +func getTestValue() *rolebinding.Values { + return &rolebinding.Values{ + Name: "test-rolebinding", + Namespace: "test-namespace", + Labels: map[string]string{ + "foo": "bar", + }, + } +} diff --git a/pkg/component/etcd/rolebinding/value_helper_test.go b/pkg/component/etcd/rolebinding/value_helper_test.go new file mode 100644 index 000000000..58243e365 --- /dev/null +++ b/pkg/component/etcd/rolebinding/value_helper_test.go @@ -0,0 +1,67 @@ +// Copyright (c) 2023 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file +// +// 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 rolebinding_test + +import ( + "github.com/gardener/etcd-druid/api/v1alpha1" + "github.com/gardener/etcd-druid/pkg/component/etcd/rolebinding" + "github.com/gardener/etcd-druid/pkg/utils" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/utils/pointer" +) + +var _ = Describe("RoleBindig", func() { + var ( + etcd = &v1alpha1.Etcd{ + ObjectMeta: v1.ObjectMeta{ + Name: "etcd-name", + Namespace: "etcd-namespace", + UID: "etcd-uid", + }, + Spec: v1alpha1.EtcdSpec{ + Labels: map[string]string{ + "key1": "value1", + "key2": "value2", + }, + }, + } + expected = &rolebinding.Values{ + Name: utils.GetRoleBindingName(etcd), + Namespace: etcd.Namespace, + Labels: etcd.Spec.Labels, + RoleName: utils.GetRoleName(etcd), + ServiceAccountName: utils.GetServiceAccountName(etcd), + OwnerReferences: []v1.OwnerReference{ + { + APIVersion: v1alpha1.GroupVersion.String(), + Kind: etcd.Kind, + Name: etcd.Name, + UID: etcd.UID, + Controller: pointer.BoolPtr(true), + BlockOwnerDeletion: pointer.BoolPtr(true), + }, + }, + } + ) + + Context("Generate Values", func() { + It("should generate correct values", func() { + values := rolebinding.GenerateValues(etcd) + Expect(values).To(Equal(expected)) + }) + }) +}) diff --git a/pkg/component/etcd/rolebinding/values.go b/pkg/component/etcd/rolebinding/values.go new file mode 100644 index 000000000..7b1b9056d --- /dev/null +++ b/pkg/component/etcd/rolebinding/values.go @@ -0,0 +1,32 @@ +// Copyright (c) 2023 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file +// +// 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 rolebinding + +import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + +type Values struct { + // Name is the name of the RoleBinding. + Name string + // Namespace is the namespace of the RoleBinding. + Namespace string + // RoleName is the role name of the RoleBinding. + RoleName string + // ServiceAccountName is the service account name of the RoleBinding. + ServiceAccountName string + // OwnerReferences are the OwnerReferences of the RoleBinding. + OwnerReferences []metav1.OwnerReference + // Labels are the labels of the RoleBinding. + Labels map[string]string +} diff --git a/pkg/component/etcd/rolebinding/values_helper.go b/pkg/component/etcd/rolebinding/values_helper.go new file mode 100644 index 000000000..8e563a030 --- /dev/null +++ b/pkg/component/etcd/rolebinding/values_helper.go @@ -0,0 +1,32 @@ +// Copyright (c) 2023 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file +// +// 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 rolebinding + +import ( + druidv1alpha1 "github.com/gardener/etcd-druid/api/v1alpha1" + "github.com/gardener/etcd-druid/pkg/utils" +) + +// GenerateValues generates `serviceaccount.Values` for the serviceaccount component with the given `etcd` object. +func GenerateValues(etcd *druidv1alpha1.Etcd) *Values { + return &Values{ + Name: utils.GetRoleBindingName(etcd), + Namespace: etcd.Namespace, + Labels: etcd.Spec.Labels, + OwnerReferences: utils.GenerateEtcdOwnerReference(etcd), + RoleName: utils.GetRoleName(etcd), + ServiceAccountName: utils.GetServiceAccountName(etcd), + } +} From f2cefbacab5a77cdd1e80f250e087abfb013fd8c Mon Sep 17 00:00:00 2001 From: Seshachalam Yerasala Venkata Date: Mon, 27 Feb 2023 19:26:10 +0530 Subject: [PATCH 2/6] Remove RoleBinding from template yaml from chart --- api/v1alpha1/types_etcd.go | 5 + charts/etcd/templates/etcd-rolebinding.yaml | 26 ----- pkg/component/etcd/rolebinding/rolebinding.go | 10 +- .../etcd/rolebinding/rolebinding_test.go | 103 +++++++++--------- pkg/component/etcd/rolebinding/values.go | 1 + .../etcd/rolebinding/values_helper.go | 16 +-- ...e_helper_test.go => values_helper_test.go} | 32 +++--- 7 files changed, 82 insertions(+), 111 deletions(-) delete mode 100644 charts/etcd/templates/etcd-rolebinding.yaml rename pkg/component/etcd/rolebinding/{value_helper_test.go => values_helper_test.go} (66%) diff --git a/api/v1alpha1/types_etcd.go b/api/v1alpha1/types_etcd.go index 8c2bf2e97..e0af377f3 100644 --- a/api/v1alpha1/types_etcd.go +++ b/api/v1alpha1/types_etcd.go @@ -475,3 +475,8 @@ func (e *Etcd) GetAsOwnerReference() metav1.OwnerReference { func (e *Etcd) GetRoleName() string { return fmt.Sprintf("druid.gardener.cloud:etcd:%s", e.Name) } + +// GetRoleBindingName returns the rolebinding name for the Etcd +func (e *Etcd) GetRoleBindingName() string { + return fmt.Sprintf("druid.gardener.cloud:etcd:%s", e.Name) +} diff --git a/charts/etcd/templates/etcd-rolebinding.yaml b/charts/etcd/templates/etcd-rolebinding.yaml deleted file mode 100644 index 790aa8a30..000000000 --- a/charts/etcd/templates/etcd-rolebinding.yaml +++ /dev/null @@ -1,26 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: {{ .Values.roleBindingName }} - namespace: {{ .Release.Namespace }} - ownerReferences: - - apiVersion: druid.gardener.cloud/v1alpha1 - blockOwnerDeletion: true - controller: true - kind: Etcd - name: {{ .Values.name }} - uid: {{ .Values.uid }} - labels: - name: etcd - instance: {{ .Values.name }} -{{- if .Values.labels }} -{{ toYaml .Values.labels | indent 4 }} -{{- end }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: {{ .Values.roleName }} -subjects: -- kind: ServiceAccount - name: {{ .Values.serviceAccountName }} - namespace: {{ .Release.Namespace }} \ No newline at end of file diff --git a/pkg/component/etcd/rolebinding/rolebinding.go b/pkg/component/etcd/rolebinding/rolebinding.go index 2b4b9cd72..bab8bc6c0 100644 --- a/pkg/component/etcd/rolebinding/rolebinding.go +++ b/pkg/component/etcd/rolebinding/rolebinding.go @@ -30,7 +30,7 @@ type component struct { values *Values } -func (c *component) Deploy(ctx context.Context) error { +func (c component) Deploy(ctx context.Context) error { roleBinding := c.emptyRoleBinding() _, err := controllerutils.GetAndCreateOrStrategicMergePatch(ctx, c.client, roleBinding, func() error { roleBinding.Name = c.values.Name @@ -54,12 +54,8 @@ func (c *component) Deploy(ctx context.Context) error { return err } -func (c *component) Destroy(ctx context.Context) error { - roleBinding := c.emptyRoleBinding() - if err := client.IgnoreNotFound(c.client.Delete(ctx, roleBinding)); err != nil { - return err - } - return nil +func (c component) Destroy(ctx context.Context) error { + return client.IgnoreNotFound(c.client.Delete(ctx, c.emptyRoleBinding())) } func (c *component) emptyRoleBinding() *rbacv1.RoleBinding { diff --git a/pkg/component/etcd/rolebinding/rolebinding_test.go b/pkg/component/etcd/rolebinding/rolebinding_test.go index 987a4ad0a..ab2d0ebc0 100644 --- a/pkg/component/etcd/rolebinding/rolebinding_test.go +++ b/pkg/component/etcd/rolebinding/rolebinding_test.go @@ -17,97 +17,83 @@ package rolebinding_test import ( "context" + "github.com/gardener/etcd-druid/api/v1alpha1" "github.com/gardener/etcd-druid/pkg/client/kubernetes" "github.com/gardener/etcd-druid/pkg/component/etcd/rolebinding" - "github.com/gardener/gardener/pkg/operation/botanist/component" . "github.com/gardener/gardener/pkg/utils/test/matchers" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" + "k8s.io/utils/pointer" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/fake" ) -var _ = Describe("RoleBinding Component", func() { +var _ = Describe("RoleBinding Component", Ordered, func() { var ( - ctx context.Context - c client.Client - value *rolebinding.Values - roleBindingComponent component.Deployer + ctx = context.TODO() + c = fake.NewClientBuilder().WithScheme(kubernetes.Scheme).Build() + values = getTestRoleBindingValues() + roleBindingComponent = rolebinding.New(c, values) ) - BeforeEach(func() { - ctx = context.TODO() - c = fake.NewClientBuilder().WithScheme(kubernetes.Scheme).Build() - value = getTestValue() - roleBindingComponent = rolebinding.New(c, value) - }) - - Describe("#Deploy", func() { - AfterEach(func() { - Expect(roleBindingComponent.Destroy(ctx)).NotTo(HaveOccurred()) - }) - - It("should create and update the RoleBinding with the expected values", func() { + Context("#Deploy", func() { + It("should create the RoleBinding with the expected values", func() { By("creating a RoleBinding") err := roleBindingComponent.Deploy(ctx) Expect(err).NotTo(HaveOccurred()) By("verifying that the RoleBinding is created on the K8s cluster as expected") created := &rbacv1.RoleBinding{} - err = c.Get(ctx, getRoleBindingKeyFromValue(value), created) + err = c.Get(ctx, getRoleBindingKeyFromValue(values), created) Expect(err).NotTo(HaveOccurred()) - verifyRoleBindingValues(created, value) - + verifyRoleBindingValues(created, values) + }) + It("should update the RoleBinding with the expected values", func() { By("updating the RoleBinding") - err = roleBindingComponent.Deploy(ctx) + values.Labels["new"] = "label" + err := roleBindingComponent.Deploy(ctx) Expect(err).NotTo(HaveOccurred()) By("verifying that the RoleBinding is updated on the K8s cluster as expected") updated := &rbacv1.RoleBinding{} - err = c.Get(ctx, getRoleBindingKeyFromValue(value), updated) + err = c.Get(ctx, getRoleBindingKeyFromValue(values), updated) Expect(err).NotTo(HaveOccurred()) - verifyRoleBindingValues(updated, value) - - By("returning nil when there is nothing to update the RoleBinding") - err = roleBindingComponent.Deploy(ctx) + verifyRoleBindingValues(updated, values) + }) + It("should not return an error when there is nothing to update the RoleBinding", func() { + err := roleBindingComponent.Deploy(ctx) Expect(err).NotTo(HaveOccurred()) - updated = &rbacv1.RoleBinding{} - err = c.Get(ctx, getRoleBindingKeyFromValue(value), updated) + updated := &rbacv1.RoleBinding{} + err = c.Get(ctx, getRoleBindingKeyFromValue(values), updated) Expect(err).NotTo(HaveOccurred()) - verifyRoleBindingValues(updated, value) - - By("returning an error when the update fails") - value.Name = "" - err = roleBindingComponent.Deploy(ctx) + verifyRoleBindingValues(updated, values) + }) + It("should return an error when the update fails", func() { + values.Name = "" + err := roleBindingComponent.Deploy(ctx) Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("Required value: name is required")) }) }) - Describe("#Destroy", func() { - BeforeEach(func() { - Expect(roleBindingComponent.Deploy(ctx)).NotTo(HaveOccurred()) - }) - + Context("#Destroy", func() { It("should delete the RoleBinding", func() { - roleBinding := &rbacv1.RoleBinding{} - By("checking that the RoleBinding exists before deleting it") - Expect(c.Get(ctx, getRoleBindingKeyFromValue(value), roleBinding)).NotTo(HaveOccurred()) - By("deleting the RoleBinding") err := roleBindingComponent.Destroy(ctx) Expect(err).NotTo(HaveOccurred()) + roleBinding := &rbacv1.RoleBinding{} By("verifying that the RoleBinding is deleted from the K8s cluster as expected") - Expect(c.Get(ctx, getRoleBindingKeyFromValue(value), roleBinding)).To(BeNotFoundError()) - - By("returning nil when there is nothing to delete") - err = roleBindingComponent.Destroy(ctx) - Expect(err).To(BeNil()) + Expect(c.Get(ctx, getRoleBindingKeyFromValue(values), roleBinding)).To(BeNotFoundError()) + }) + It("should not return an error when there is nothing to delete", func() { + err := roleBindingComponent.Destroy(ctx) + Expect(err).NotTo(HaveOccurred()) }) }) }) @@ -117,6 +103,7 @@ func verifyRoleBindingValues(expected *rbacv1.RoleBinding, values *rolebinding.V Expect(expected.Labels).To(Equal(values.Labels)) Expect(expected.Namespace).To(Equal(values.Namespace)) Expect(expected.Namespace).To(Equal(values.Namespace)) + Expect(expected.OwnerReferences).To(Equal(values.OwnerReferences)) Expect(expected.Subjects).To(Equal([]rbacv1.Subject{ { Kind: "ServiceAccount", @@ -130,16 +117,28 @@ func verifyRoleBindingValues(expected *rbacv1.RoleBinding, values *rolebinding.V Name: values.RoleName, })) } -func getRoleBindingKeyFromValue(value *rolebinding.Values) types.NamespacedName { - return client.ObjectKey{Name: value.Name, Namespace: value.Namespace} +func getRoleBindingKeyFromValue(values *rolebinding.Values) types.NamespacedName { + return client.ObjectKey{Name: values.Name, Namespace: values.Namespace} } -func getTestValue() *rolebinding.Values { +func getTestRoleBindingValues() *rolebinding.Values { return &rolebinding.Values{ Name: "test-rolebinding", Namespace: "test-namespace", Labels: map[string]string{ "foo": "bar", }, + RoleName: "test-role", + ServiceAccountName: "test-serviceaccount", + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: v1alpha1.GroupVersion.String(), + Kind: "etcd", + Name: "test-etcd", + UID: "123-456-789", + Controller: pointer.Bool(true), + BlockOwnerDeletion: pointer.Bool(true), + }, + }, } } diff --git a/pkg/component/etcd/rolebinding/values.go b/pkg/component/etcd/rolebinding/values.go index 7b1b9056d..4f6040d1c 100644 --- a/pkg/component/etcd/rolebinding/values.go +++ b/pkg/component/etcd/rolebinding/values.go @@ -16,6 +16,7 @@ package rolebinding import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +// Values defines the fields used to create a RoleBinding for Etcd. type Values struct { // Name is the name of the RoleBinding. Name string diff --git a/pkg/component/etcd/rolebinding/values_helper.go b/pkg/component/etcd/rolebinding/values_helper.go index 8e563a030..a6c35a716 100644 --- a/pkg/component/etcd/rolebinding/values_helper.go +++ b/pkg/component/etcd/rolebinding/values_helper.go @@ -16,17 +16,19 @@ package rolebinding import ( druidv1alpha1 "github.com/gardener/etcd-druid/api/v1alpha1" - "github.com/gardener/etcd-druid/pkg/utils" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) // GenerateValues generates `serviceaccount.Values` for the serviceaccount component with the given `etcd` object. func GenerateValues(etcd *druidv1alpha1.Etcd) *Values { return &Values{ - Name: utils.GetRoleBindingName(etcd), - Namespace: etcd.Namespace, - Labels: etcd.Spec.Labels, - OwnerReferences: utils.GenerateEtcdOwnerReference(etcd), - RoleName: utils.GetRoleName(etcd), - ServiceAccountName: utils.GetServiceAccountName(etcd), + Name: etcd.GetRoleBindingName(), + Namespace: etcd.Namespace, + Labels: etcd.GetDefaultLabels(), + OwnerReferences: []metav1.OwnerReference{ + etcd.GetAsOwnerReference(), + }, + RoleName: etcd.GetRoleName(), + ServiceAccountName: etcd.GetServiceAccountName(), } } diff --git a/pkg/component/etcd/rolebinding/value_helper_test.go b/pkg/component/etcd/rolebinding/values_helper_test.go similarity index 66% rename from pkg/component/etcd/rolebinding/value_helper_test.go rename to pkg/component/etcd/rolebinding/values_helper_test.go index 58243e365..6e8b83eff 100644 --- a/pkg/component/etcd/rolebinding/value_helper_test.go +++ b/pkg/component/etcd/rolebinding/values_helper_test.go @@ -17,17 +17,15 @@ package rolebinding_test import ( "github.com/gardener/etcd-druid/api/v1alpha1" "github.com/gardener/etcd-druid/pkg/component/etcd/rolebinding" - "github.com/gardener/etcd-druid/pkg/utils" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/utils/pointer" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -var _ = Describe("RoleBindig", func() { +var _ = Describe("RoleBinding", func() { var ( etcd = &v1alpha1.Etcd{ - ObjectMeta: v1.ObjectMeta{ + ObjectMeta: metav1.ObjectMeta{ Name: "etcd-name", Namespace: "etcd-namespace", UID: "etcd-uid", @@ -40,20 +38,16 @@ var _ = Describe("RoleBindig", func() { }, } expected = &rolebinding.Values{ - Name: utils.GetRoleBindingName(etcd), - Namespace: etcd.Namespace, - Labels: etcd.Spec.Labels, - RoleName: utils.GetRoleName(etcd), - ServiceAccountName: utils.GetServiceAccountName(etcd), - OwnerReferences: []v1.OwnerReference{ - { - APIVersion: v1alpha1.GroupVersion.String(), - Kind: etcd.Kind, - Name: etcd.Name, - UID: etcd.UID, - Controller: pointer.BoolPtr(true), - BlockOwnerDeletion: pointer.BoolPtr(true), - }, + Name: etcd.GetRoleBindingName(), + Namespace: etcd.Namespace, + Labels: map[string]string{ + "name": "etcd", + "instance": etcd.Name, + }, + RoleName: etcd.GetRoleName(), + ServiceAccountName: etcd.GetServiceAccountName(), + OwnerReferences: []metav1.OwnerReference{ + etcd.GetAsOwnerReference(), }, } ) From 2a84d8219f0933df7514c14bc5efb8f63780fb42 Mon Sep 17 00:00:00 2001 From: Seshachalam Yerasala Venkata Date: Wed, 12 Apr 2023 11:02:22 +0530 Subject: [PATCH 3/6] Addressed review feeback --- api/v1alpha1/types_etcd_test.go | 7 ++ controllers/etcd/reconciler.go | 73 +++---------------- pkg/component/etcd/role/role_suite_test.go | 2 +- .../rolebinding/rolebinding_suite_test.go | 2 +- .../etcd/rolebinding/rolebinding_test.go | 49 +++++++++++-- .../serviceaccount_suite_test.go | 2 +- 6 files changed, 63 insertions(+), 72 deletions(-) diff --git a/api/v1alpha1/types_etcd_test.go b/api/v1alpha1/types_etcd_test.go index 396c715cf..e750422a4 100644 --- a/api/v1alpha1/types_etcd_test.go +++ b/api/v1alpha1/types_etcd_test.go @@ -148,6 +148,13 @@ var _ = Describe("Etcd", func() { Expect(created.GetRoleName()).To(Equal(expected)) }) }) + + Context("GetRoleBindingName", func() { + It("should return the rolebinding name for the Etcd", func() { + expected := "druid.gardener.cloud:etcd:foo" + Expect(created.GetRoleName()).To(Equal(expected)) + }) + }) }) func getEtcd(name, namespace string) *Etcd { diff --git a/controllers/etcd/reconciler.go b/controllers/etcd/reconciler.go index 8b7bd5bec..c5f36a267 100644 --- a/controllers/etcd/reconciler.go +++ b/controllers/etcd/reconciler.go @@ -18,7 +18,6 @@ import ( "context" "fmt" "path/filepath" - "reflect" druidv1alpha1 "github.com/gardener/etcd-druid/api/v1alpha1" "github.com/gardener/etcd-druid/controllers/utils" @@ -27,6 +26,7 @@ import ( componentlease "github.com/gardener/etcd-druid/pkg/component/etcd/lease" componentpdb "github.com/gardener/etcd-druid/pkg/component/etcd/poddisruptionbudget" componentrole "github.com/gardener/etcd-druid/pkg/component/etcd/role" + componentrolebinding "github.com/gardener/etcd-druid/pkg/component/etcd/rolebinding" componentservice "github.com/gardener/etcd-druid/pkg/component/etcd/service" componentserviceaccount "github.com/gardener/etcd-druid/pkg/component/etcd/serviceaccount" componentsts "github.com/gardener/etcd-druid/pkg/component/etcd/statefulset" @@ -40,7 +40,6 @@ import ( "github.com/go-logr/logr" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" - rbac "k8s.io/api/rbac/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/sets" @@ -280,6 +279,14 @@ func (r *Reconciler) delete(ctx context.Context, etcd *druidv1alpha1.Etcd) (ctrl }, err } + roleBindingValues := componentrolebinding.GenerateValues(etcd) + roleBindingDeployer := componentrolebinding.New(r.Client, roleBindingValues) + if err := roleBindingDeployer.Destroy(ctx); err != nil { + return ctrl.Result{ + Requeue: true, + }, err + } + if sets.NewString(etcd.Finalizers...).Has(common.FinalizerName) { logger.Info("Removing finalizer") if err := controllerutils.RemoveFinalizers(ctx, r.Client, etcd, common.FinalizerName); client.IgnoreNotFound(err) != nil { @@ -292,40 +299,6 @@ func (r *Reconciler) delete(ctx context.Context, etcd *druidv1alpha1.Etcd) (ctrl return ctrl.Result{}, nil } -func (r *Reconciler) reconcileRoleBinding(ctx context.Context, logger logr.Logger, etcd *druidv1alpha1.Etcd, values map[string]interface{}) error { - logger.Info("Reconciling rolebinding") - var err error - - decoded, err := r.chart.decodeRoleBinding(etcd.Name, etcd.Namespace, values) - if err != nil { - return err - } - - roleBindingObj := &rbac.RoleBinding{} - key := client.ObjectKeyFromObject(decoded) - if err := r.Get(ctx, key, roleBindingObj); err != nil { - if !apierrors.IsNotFound(err) { - return err - } - if err := r.Create(ctx, decoded); err != nil { - return err - } - logger.Info("Creating rolebinding", "rolebinding", kutil.Key(decoded.Namespace, decoded.Name).String()) - return nil - } - - if !reflect.DeepEqual(decoded.RoleRef, roleBindingObj.RoleRef) || !reflect.DeepEqual(decoded.Subjects, roleBindingObj.Subjects) { - roleBindingObjCopy := roleBindingObj.DeepCopy() - roleBindingObjCopy.RoleRef = decoded.RoleRef - roleBindingObjCopy.Subjects = decoded.Subjects - if err := r.Patch(ctx, roleBindingObjCopy, client.MergeFrom(roleBindingObj)); err != nil { - return err - } - } - - return err -} - func (r *Reconciler) reconcileEtcd(ctx context.Context, logger logr.Logger, etcd *druidv1alpha1.Etcd) reconcileResult { // Check if Spec.Replicas is odd or even. // TODO(timuthy): The following checks should rather be part of a validation. Also re-enqueuing doesn't make sense in case the values are invalid. @@ -381,11 +354,9 @@ func (r *Reconciler) reconcileEtcd(ctx context.Context, logger logr.Logger, etcd return reconcileResult{err: err} } - roleBindingValues, err := r.getMapFromEtcd(etcd, r.config.DisableEtcdServiceAccountAutomount) - if err != nil { - return reconcileResult{err: err} - } - err = r.reconcileRoleBinding(ctx, logger, etcd, roleBindingValues) + roleBindingValues := componentrolebinding.GenerateValues(etcd) + roleBindingDeployer := componentrolebinding.New(r.Client, roleBindingValues) + err = roleBindingDeployer.Deploy(ctx) if err != nil { return reconcileResult{err: err} } @@ -420,26 +391,6 @@ func (r *Reconciler) reconcileEtcd(ctx context.Context, logger logr.Logger, etcd return reconcileResult{svcName: &serviceValues.ClientServiceName, sts: sts, err: err} } -func (r *Reconciler) getMapFromEtcd(etcd *druidv1alpha1.Etcd, disableEtcdServiceAccountAutomount bool) (map[string]interface{}, error) { - pdbMinAvailable := 0 - if etcd.Spec.Replicas > 1 { - pdbMinAvailable = int(etcd.Spec.Replicas) - } - - values := map[string]interface{}{ - "name": etcd.Name, - "uid": etcd.UID, - "labels": etcd.Spec.Labels, - "pdbMinAvailable": pdbMinAvailable, - "serviceAccountName": etcd.GetServiceAccountName(), - "disableEtcdServiceAccountAutomount": disableEtcdServiceAccountAutomount, - "roleName": fmt.Sprintf("druid.gardener.cloud:etcd:%s", etcd.Name), - "roleBindingName": fmt.Sprintf("druid.gardener.cloud:etcd:%s", etcd.Name), - } - - return values, nil -} - func isPeerTLSChangedToEnabled(peerTLSEnabledStatusFromMembers bool, configMapValues *componentconfigmap.Values) bool { if peerTLSEnabledStatusFromMembers { return false diff --git a/pkg/component/etcd/role/role_suite_test.go b/pkg/component/etcd/role/role_suite_test.go index 98656d090..5bd426235 100644 --- a/pkg/component/etcd/role/role_suite_test.go +++ b/pkg/component/etcd/role/role_suite_test.go @@ -21,7 +21,7 @@ import ( . "github.com/onsi/gomega" ) -func TestService(t *testing.T) { +func TestRole(t *testing.T) { RegisterFailHandler(Fail) RunSpecs(t, "Role Component Suite") } diff --git a/pkg/component/etcd/rolebinding/rolebinding_suite_test.go b/pkg/component/etcd/rolebinding/rolebinding_suite_test.go index 5fb0a766e..e46726e0a 100644 --- a/pkg/component/etcd/rolebinding/rolebinding_suite_test.go +++ b/pkg/component/etcd/rolebinding/rolebinding_suite_test.go @@ -21,7 +21,7 @@ import ( . "github.com/onsi/gomega" ) -func TestService(t *testing.T) { +func TestRoleBinding(t *testing.T) { RegisterFailHandler(Fail) RunSpecs(t, "RoleBinding Component Suite") } diff --git a/pkg/component/etcd/rolebinding/rolebinding_test.go b/pkg/component/etcd/rolebinding/rolebinding_test.go index ab2d0ebc0..3ad2045b1 100644 --- a/pkg/component/etcd/rolebinding/rolebinding_test.go +++ b/pkg/component/etcd/rolebinding/rolebinding_test.go @@ -21,6 +21,7 @@ import ( "github.com/gardener/etcd-druid/pkg/client/kubernetes" "github.com/gardener/etcd-druid/pkg/component/etcd/rolebinding" + "github.com/gardener/gardener/pkg/operation/botanist/component" . "github.com/gardener/gardener/pkg/utils/test/matchers" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -33,26 +34,39 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client/fake" ) -var _ = Describe("RoleBinding Component", Ordered, func() { +var _ = Describe("RoleBinding Component", func() { var ( - ctx = context.TODO() - c = fake.NewClientBuilder().WithScheme(kubernetes.Scheme).Build() - values = getTestRoleBindingValues() - roleBindingComponent = rolebinding.New(c, values) + ctx context.Context + c client.Client + values *rolebinding.Values + roleBindingComponent component.Deployer ) Context("#Deploy", func() { - It("should create the RoleBinding with the expected values", func() { - By("creating a RoleBinding") + + BeforeEach(func() { + ctx = context.Background() + c = fake.NewClientBuilder().WithScheme(kubernetes.Scheme).Build() + values = getTestRoleBindingValues() + roleBindingComponent = rolebinding.New(c, values) + err := roleBindingComponent.Deploy(ctx) Expect(err).NotTo(HaveOccurred()) + }) + AfterEach(func() { + err := roleBindingComponent.Destroy(ctx) + Expect(err).NotTo(HaveOccurred()) + }) + + It("should create the RoleBinding with the expected values", func() { By("verifying that the RoleBinding is created on the K8s cluster as expected") created := &rbacv1.RoleBinding{} - err = c.Get(ctx, getRoleBindingKeyFromValue(values), created) + err := c.Get(ctx, getRoleBindingKeyFromValue(values), created) Expect(err).NotTo(HaveOccurred()) verifyRoleBindingValues(created, values) }) + It("should update the RoleBinding with the expected values", func() { By("updating the RoleBinding") values.Labels["new"] = "label" @@ -65,6 +79,7 @@ var _ = Describe("RoleBinding Component", Ordered, func() { Expect(err).NotTo(HaveOccurred()) verifyRoleBindingValues(updated, values) }) + It("should not return an error when there is nothing to update the RoleBinding", func() { err := roleBindingComponent.Deploy(ctx) Expect(err).NotTo(HaveOccurred()) @@ -73,6 +88,7 @@ var _ = Describe("RoleBinding Component", Ordered, func() { Expect(err).NotTo(HaveOccurred()) verifyRoleBindingValues(updated, values) }) + It("should return an error when the update fails", func() { values.Name = "" err := roleBindingComponent.Deploy(ctx) @@ -82,6 +98,17 @@ var _ = Describe("RoleBinding Component", Ordered, func() { }) Context("#Destroy", func() { + + BeforeEach(func() { + ctx = context.Background() + c = fake.NewClientBuilder().WithScheme(kubernetes.Scheme).Build() + values = getTestRoleBindingValues() + + roleBindingComponent = rolebinding.New(c, values) + err := roleBindingComponent.Deploy(ctx) + Expect(err).NotTo(HaveOccurred()) + }) + It("should delete the RoleBinding", func() { By("deleting the RoleBinding") err := roleBindingComponent.Destroy(ctx) @@ -91,9 +118,15 @@ var _ = Describe("RoleBinding Component", Ordered, func() { By("verifying that the RoleBinding is deleted from the K8s cluster as expected") Expect(c.Get(ctx, getRoleBindingKeyFromValue(values), roleBinding)).To(BeNotFoundError()) }) + It("should not return an error when there is nothing to delete", func() { + By("deleting the RoleBinding") err := roleBindingComponent.Destroy(ctx) Expect(err).NotTo(HaveOccurred()) + + By("verifying that attempting to delete the RoleBinding again returns no error") + err = roleBindingComponent.Destroy(ctx) + Expect(err).NotTo(HaveOccurred()) }) }) }) diff --git a/pkg/component/etcd/serviceaccount/serviceaccount_suite_test.go b/pkg/component/etcd/serviceaccount/serviceaccount_suite_test.go index 45f446bd4..4d6f55269 100644 --- a/pkg/component/etcd/serviceaccount/serviceaccount_suite_test.go +++ b/pkg/component/etcd/serviceaccount/serviceaccount_suite_test.go @@ -21,7 +21,7 @@ import ( . "github.com/onsi/gomega" ) -func TestService(t *testing.T) { +func TestServiceAccount(t *testing.T) { RegisterFailHandler(Fail) RunSpecs(t, "ServiceAccount Component Suite") } From be6e26dbc169c85e1703f36e1071b9f515ed1a66 Mon Sep 17 00:00:00 2001 From: Seshachalam <104052572+seshachalam-yv@users.noreply.github.com> Date: Fri, 14 Apr 2023 10:49:32 +0530 Subject: [PATCH 4/6] Apply suggestions from code review Co-authored-by: Madhav Bhargava --- pkg/component/etcd/rolebinding/values.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/component/etcd/rolebinding/values.go b/pkg/component/etcd/rolebinding/values.go index 4f6040d1c..936933bf0 100644 --- a/pkg/component/etcd/rolebinding/values.go +++ b/pkg/component/etcd/rolebinding/values.go @@ -22,9 +22,10 @@ type Values struct { Name string // Namespace is the namespace of the RoleBinding. Namespace string - // RoleName is the role name of the RoleBinding. + // RoleName is the role name of the RoleBinding. It is assumed that the role exists in the namespace where the etcd custom resource is created. RoleName string - // ServiceAccountName is the service account name of the RoleBinding. + // ServiceAccountName is the service account subject name for the RoleBinding. + // It is assumed that the ServiceAccount exists in the namespace where the etcd custom resource is created. ServiceAccountName string // OwnerReferences are the OwnerReferences of the RoleBinding. OwnerReferences []metav1.OwnerReference From d4ffa49c3eab49cb83a58e2b31fab75c064fe1ee Mon Sep 17 00:00:00 2001 From: Seshachalam Yerasala Venkata Date: Fri, 14 Apr 2023 10:54:12 +0530 Subject: [PATCH 5/6] Revert the changes which are not related to this PR's scope. --- pkg/component/etcd/role/role_suite_test.go | 2 +- pkg/component/etcd/serviceaccount/serviceaccount_suite_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/component/etcd/role/role_suite_test.go b/pkg/component/etcd/role/role_suite_test.go index 5bd426235..98656d090 100644 --- a/pkg/component/etcd/role/role_suite_test.go +++ b/pkg/component/etcd/role/role_suite_test.go @@ -21,7 +21,7 @@ import ( . "github.com/onsi/gomega" ) -func TestRole(t *testing.T) { +func TestService(t *testing.T) { RegisterFailHandler(Fail) RunSpecs(t, "Role Component Suite") } diff --git a/pkg/component/etcd/serviceaccount/serviceaccount_suite_test.go b/pkg/component/etcd/serviceaccount/serviceaccount_suite_test.go index 4d6f55269..45f446bd4 100644 --- a/pkg/component/etcd/serviceaccount/serviceaccount_suite_test.go +++ b/pkg/component/etcd/serviceaccount/serviceaccount_suite_test.go @@ -21,7 +21,7 @@ import ( . "github.com/onsi/gomega" ) -func TestServiceAccount(t *testing.T) { +func TestService(t *testing.T) { RegisterFailHandler(Fail) RunSpecs(t, "ServiceAccount Component Suite") } From 670e1c7e091137f19c138e6f5d7215236bb71d99 Mon Sep 17 00:00:00 2001 From: Seshachalam Yerasala Venkata Date: Fri, 14 Apr 2023 11:11:51 +0530 Subject: [PATCH 6/6] Use Etcd Druid group from types_etcd GroupVersion.Group --- api/v1alpha1/types_etcd.go | 4 ++-- api/v1alpha1/types_etcd_test.go | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/api/v1alpha1/types_etcd.go b/api/v1alpha1/types_etcd.go index e0af377f3..c6685d56d 100644 --- a/api/v1alpha1/types_etcd.go +++ b/api/v1alpha1/types_etcd.go @@ -473,10 +473,10 @@ func (e *Etcd) GetAsOwnerReference() metav1.OwnerReference { // GetRoleName returns the role name for the Etcd func (e *Etcd) GetRoleName() string { - return fmt.Sprintf("druid.gardener.cloud:etcd:%s", e.Name) + return fmt.Sprintf("%s:etcd:%s", GroupVersion.Group, e.Name) } // GetRoleBindingName returns the rolebinding name for the Etcd func (e *Etcd) GetRoleBindingName() string { - return fmt.Sprintf("druid.gardener.cloud:etcd:%s", e.Name) + return fmt.Sprintf("%s:etcd:%s", GroupVersion.Group, e.Name) } diff --git a/api/v1alpha1/types_etcd_test.go b/api/v1alpha1/types_etcd_test.go index e750422a4..9af6b79a6 100644 --- a/api/v1alpha1/types_etcd_test.go +++ b/api/v1alpha1/types_etcd_test.go @@ -144,15 +144,13 @@ var _ = Describe("Etcd", func() { Context("GetRoleName", func() { It("should return the role name for the Etcd", func() { - expected := "druid.gardener.cloud:etcd:foo" - Expect(created.GetRoleName()).To(Equal(expected)) + Expect(created.GetRoleName()).To(Equal(GroupVersion.Group + ":etcd:foo")) }) }) Context("GetRoleBindingName", func() { It("should return the rolebinding name for the Etcd", func() { - expected := "druid.gardener.cloud:etcd:foo" - Expect(created.GetRoleName()).To(Equal(expected)) + Expect(created.GetRoleName()).To(Equal(GroupVersion.Group + ":etcd:foo")) }) }) })