Skip to content

Commit

Permalink
feat(meta): adds InNamespace and WithAnnotation setter funcs (opendat…
Browse files Browse the repository at this point in the history
…ahub-io#1072)

* feat(meta): adds InNamespace and WithAnnotion setter funcs

disclaimer: it is stacked PR coming from the authz work.

* Update pkg/cluster/meta.go

Co-authored-by: Wen Zhou <[email protected]>

---------

Co-authored-by: Wen Zhou <[email protected]>
  • Loading branch information
bartoszmajsak and zdtsw authored Jun 24, 2024
1 parent d8acb0b commit 17c29f6
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 32 deletions.
90 changes: 67 additions & 23 deletions pkg/cluster/cluster_operations_int_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,68 +31,112 @@ var _ = Describe("Creating cluster resources", func() {
objectCleaner = envtestutil.CreateCleaner(envTestClient, envTest.Config, timeout, interval)
})

It("should create namespace if it does not exist", func() {
It("should create namespace if it does not exist", func(ctx context.Context) {
// given
namespace := envtestutil.AppendRandomNameTo("new-ns")
defer objectCleaner.DeleteAll(&v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: namespace}})

// when
ns, err := cluster.CreateNamespace(context.Background(), envTestClient, namespace)
ns, err := cluster.CreateNamespace(ctx, envTestClient, namespace)

// then
Expect(err).ToNot(HaveOccurred())
Expect(ns.Status.Phase).To(Equal(v1.NamespaceActive))
Expect(ns.ObjectMeta.Generation).To(BeZero())
})

It("should not try to create namespace if it does already exist", func() {
It("should not try to create namespace if it does already exist", func(ctx context.Context) {
// given
namespace := envtestutil.AppendRandomNameTo("existing-ns")
newNamespace := &v1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: namespace,
},
}
Expect(envTestClient.Create(context.Background(), newNamespace)).To(Succeed())
Expect(envTestClient.Create(ctx, newNamespace)).To(Succeed())
defer objectCleaner.DeleteAll(newNamespace)

// when
existingNamespace, err := cluster.CreateNamespace(context.Background(), envTestClient, namespace)
existingNamespace, err := cluster.CreateNamespace(ctx, envTestClient, namespace)

// then
Expect(err).ToNot(HaveOccurred())
Expect(existingNamespace).To(Equal(newNamespace))
})

It("should set labels", func() {
It("should set labels", func(ctx context.Context) {
// given
namespace := envtestutil.AppendRandomNameTo("new-ns-with-labels")
defer objectCleaner.DeleteAll(&v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: namespace}})

// when
nsWithLabels, err := cluster.CreateNamespace(context.Background(), envTestClient, namespace, cluster.WithLabels("opendatahub.io/test-label", "true"))
nsWithLabels, err := cluster.CreateNamespace(ctx, envTestClient, namespace, cluster.WithLabels("opendatahub.io/test-label", "true"))

// then
Expect(err).ToNot(HaveOccurred())
Expect(nsWithLabels.Labels).To(HaveKeyWithValue("opendatahub.io/test-label", "true"))
})

It("should set annotations", func(ctx context.Context) {
// given
namespace := envtestutil.AppendRandomNameTo("new-ns-with-labels")
defer objectCleaner.DeleteAll(&v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: namespace}})

// when
nsWithLabels, err := cluster.CreateNamespace(ctx, envTestClient, namespace, cluster.WithAnnotations("opendatahub.io/test-annotation", "true"))

// then
Expect(err).ToNot(HaveOccurred())
Expect(nsWithLabels.Annotations).To(HaveKeyWithValue("opendatahub.io/test-annotation", "true"))
})

})

Context("config map manipulation", func() {

var objectCleaner *envtestutil.Cleaner
var (
objectCleaner *envtestutil.Cleaner
namespace string
configMapMeta metav1.ObjectMeta
)

BeforeEach(func() {
BeforeEach(func(ctx context.Context) {
objectCleaner = envtestutil.CreateCleaner(envTestClient, envTest.Config, timeout, interval)
namespace = envtestutil.AppendRandomNameTo("new-ns")
configMapMeta = metav1.ObjectMeta{
Name: "config-regs",
Namespace: namespace,
}
_, errNs := cluster.CreateNamespace(ctx, envTestClient, namespace)
Expect(errNs).ToNot(HaveOccurred())
})

configMapMeta := metav1.ObjectMeta{
Name: "config-regs",
Namespace: "default",
}
It("should create configmap with ns set through metaoptions", func(ctx context.Context) {
// given
configMap := &v1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{Name: "config-regs"},
Data: map[string]string{
"test-key": "test-value",
},
}

// when
err := cluster.CreateOrUpdateConfigMap(
ctx,
envTestClient,
configMap,
cluster.InNamespace(namespace),
)
Expect(err).ToNot(HaveOccurred())
defer objectCleaner.DeleteAll(configMap)

// then
actualConfigMap := &v1.ConfigMap{}
Expect(envTestClient.Get(ctx, ctrlruntime.ObjectKeyFromObject(configMap), actualConfigMap)).To(Succeed())
Expect(actualConfigMap.Namespace).To(Equal(namespace))
})

It("should create configmap with labels and owner reference", func() {
It("should create configmap with labels and owner reference", func(ctx context.Context) {
// given
configMap := &v1.ConfigMap{
ObjectMeta: configMapMeta,
Expand All @@ -103,34 +147,34 @@ var _ = Describe("Creating cluster resources", func() {

// when
err := cluster.CreateOrUpdateConfigMap(
context.Background(),
ctx,
envTestClient,
configMap,
cluster.WithLabels(labels.K8SCommon.PartOf, "opendatahub"),
cluster.WithOwnerReference(metav1.OwnerReference{
APIVersion: "v1",
Kind: "Namespace",
Name: "default",
UID: "default",
Name: namespace,
UID: "random",
}),
)
Expect(err).ToNot(HaveOccurred())
defer objectCleaner.DeleteAll(configMap)

// then
actualConfigMap := &v1.ConfigMap{}
Expect(envTestClient.Get(context.Background(), ctrlruntime.ObjectKeyFromObject(configMap), actualConfigMap)).To(Succeed())
Expect(envTestClient.Get(ctx, ctrlruntime.ObjectKeyFromObject(configMap), actualConfigMap)).To(Succeed())
Expect(actualConfigMap.Labels).To(HaveKeyWithValue(labels.K8SCommon.PartOf, "opendatahub"))
getOwnerRefName := func(reference metav1.OwnerReference) string {
return reference.Name
}
Expect(actualConfigMap.OwnerReferences[0]).To(WithTransform(getOwnerRefName, Equal("default")))
Expect(actualConfigMap.OwnerReferences[0]).To(WithTransform(getOwnerRefName, Equal(namespace)))
})

It("should be able to update existing config map", func() {
It("should be able to update existing config map", func(ctx context.Context) {
// given
createErr := cluster.CreateOrUpdateConfigMap(
context.Background(),
ctx,
envTestClient,
&v1.ConfigMap{
ObjectMeta: configMapMeta,
Expand All @@ -152,7 +196,7 @@ var _ = Describe("Creating cluster resources", func() {
}

updateErr := cluster.CreateOrUpdateConfigMap(
context.Background(),
ctx,
envTestClient,
updatedConfigMap,
cluster.WithLabels("test-step", "update-existing-configmap"),
Expand All @@ -162,7 +206,7 @@ var _ = Describe("Creating cluster resources", func() {

// then
actualConfigMap := &v1.ConfigMap{}
Expect(envTestClient.Get(context.Background(), ctrlruntime.ObjectKeyFromObject(updatedConfigMap), actualConfigMap)).To(Succeed())
Expect(envTestClient.Get(ctx, ctrlruntime.ObjectKeyFromObject(updatedConfigMap), actualConfigMap)).To(Succeed())
Expect(actualConfigMap.Data).To(HaveKeyWithValue("test-key", "new-value"))
Expect(actualConfigMap.Data).To(HaveKeyWithValue("new-key", "sth-new"))
Expect(actualConfigMap.Labels).To(HaveKeyWithValue("test-step", "update-existing-configmap"))
Expand Down
6 changes: 0 additions & 6 deletions pkg/cluster/cluster_operations_suite_int_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package cluster_test

import (
"context"
"testing"

v1 "k8s.io/api/core/v1"
Expand All @@ -19,8 +18,6 @@ import (
var (
envTestClient client.Client
envTest *envtest.Environment
ctx context.Context
cancel context.CancelFunc
)

var testScheme = runtime.NewScheme()
Expand All @@ -31,8 +28,6 @@ func TestClusterOperationsIntegration(t *testing.T) {
}

var _ = BeforeSuite(func() {
ctx, cancel = context.WithCancel(context.TODO())

opts := zap.Options{Development: true}
logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseFlagOptions(&opts)))

Expand All @@ -53,6 +48,5 @@ var _ = BeforeSuite(func() {

var _ = AfterSuite(func() {
By("Tearing down the test environment")
cancel()
Expect(envTest.Stop()).To(Succeed())
})
20 changes: 20 additions & 0 deletions pkg/cluster/meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,26 @@ func WithLabels(labels ...string) MetaOptions {
}
}

func InNamespace(ns string) MetaOptions {
return func(obj metav1.Object) error {
obj.SetNamespace(ns)
return nil
}
}

func WithAnnotations(annotationKeyValue ...string) MetaOptions {
return func(obj metav1.Object) error {
annotationsMap, err := extractKeyValues(annotationKeyValue)
if err != nil {
return fmt.Errorf("failed to set labels: %w", err)
}

obj.SetAnnotations(annotationsMap)

return nil
}
}

func extractKeyValues(kv []string) (map[string]string, error) {
lenKV := len(kv)
if lenKV%2 != 0 {
Expand Down
7 changes: 4 additions & 3 deletions pkg/cluster/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ func CreateSecret(ctx context.Context, cli client.Client, name, namespace string
// If the configmap already exists, it will be updated with the merged Data and MetaOptions, if any.
// ConfigMap.ObjectMeta.Name and ConfigMap.ObjectMeta.Namespace are both required, it returns an error otherwise.
func CreateOrUpdateConfigMap(ctx context.Context, c client.Client, desiredCfgMap *corev1.ConfigMap, metaOptions ...MetaOptions) error {
if applyErr := ApplyMetaOptions(desiredCfgMap, metaOptions...); applyErr != nil {
return applyErr
}

if desiredCfgMap.GetName() == "" || desiredCfgMap.GetNamespace() == "" {
return errors.New("configmap name and namespace must be set")
}
Expand All @@ -100,9 +104,6 @@ func CreateOrUpdateConfigMap(ctx context.Context, c client.Client, desiredCfgMap
}, existingCfgMap)

if apierrs.IsNotFound(err) {
if applyErr := ApplyMetaOptions(desiredCfgMap, metaOptions...); applyErr != nil {
return applyErr
}
return c.Create(ctx, desiredCfgMap)
} else if err != nil {
return err
Expand Down

0 comments on commit 17c29f6

Please sign in to comment.