Skip to content

Commit

Permalink
fix: put annotations in deployment's pod template
Browse files Browse the repository at this point in the history
Signed-off-by: Joe Lanford <[email protected]>
  • Loading branch information
joelanford committed Nov 7, 2024
1 parent cfd4bec commit 3064fae
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 92 deletions.
8 changes: 4 additions & 4 deletions internal/rukpak/convert/registryv1.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,17 +195,17 @@ func Convert(in RegistryV1, installNamespace string, targetNamespaces []string)
for _, depSpec := range in.CSV.Spec.InstallStrategy.StrategySpec.DeploymentSpecs {
annotations := util.MergeMaps(in.CSV.Annotations, depSpec.Spec.Template.Annotations)
annotations["olm.targetNamespaces"] = strings.Join(targetNamespaces, ",")
depSpec.Spec.Template.Annotations = annotations
deployments = append(deployments, appsv1.Deployment{
TypeMeta: metav1.TypeMeta{
Kind: "Deployment",
APIVersion: appsv1.SchemeGroupVersion.String(),
},

ObjectMeta: metav1.ObjectMeta{
Namespace: installNamespace,
Name: depSpec.Name,
Labels: depSpec.Label,
Annotations: annotations,
Namespace: installNamespace,
Name: depSpec.Name,
Labels: depSpec.Label,
},
Spec: depSpec.Spec,
})
Expand Down
191 changes: 103 additions & 88 deletions internal/rukpak/convert/registryv1_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ package convert

import (
"fmt"
"strings"
"testing"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"

appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1"
schedulingv1 "k8s.io/api/scheduling/v1"
Expand Down Expand Up @@ -73,7 +75,7 @@ var _ = Describe("RegistryV1 Suite", func() {
Expect(plainBundle.Objects).To(HaveLen(1))

By("verifying if ns has been set correctly")
resObj := containsObject(unstructuredSvc, plainBundle.Objects)
resObj := findObjectByName(svc.Name, plainBundle.Objects)
Expect(resObj).NotTo(BeNil())
Expect(resObj.GetNamespace()).To(BeEquivalentTo(installNamespace))
})
Expand All @@ -99,7 +101,7 @@ var _ = Describe("RegistryV1 Suite", func() {
Expect(plainBundle.Objects).To(HaveLen(1))

By("verifying if ns has been set correctly")
resObj := containsObject(unstructuredSvc, plainBundle.Objects)
resObj := findObjectByName(svc.Name, plainBundle.Objects)
Expect(resObj).NotTo(BeNil())
Expect(resObj.GetNamespace()).To(BeEquivalentTo(installNamespace))
})
Expand Down Expand Up @@ -157,7 +159,7 @@ var _ = Describe("RegistryV1 Suite", func() {
Expect(plainBundle.Objects).To(HaveLen(1))

By("verifying if ns has been set correctly")
resObj := containsObject(unstructuredpriorityclass, plainBundle.Objects)
resObj := findObjectByName(pc.Name, plainBundle.Objects)
Expect(resObj).NotTo(BeNil())
Expect(resObj.GetNamespace()).To(BeEmpty())
})
Expand All @@ -167,22 +169,39 @@ var _ = Describe("RegistryV1 Suite", func() {
Context("Should generate objects successfully based on target namespaces", func() {
var (
svc corev1.Service
csv v1alpha1.ClusterServiceVersion
baseCSV v1alpha1.ClusterServiceVersion
watchNamespaces []string
)

BeforeEach(func() {
csv = v1alpha1.ClusterServiceVersion{
// base CSV definition that each test case will deep copy and modify
baseCSV = v1alpha1.ClusterServiceVersion{
ObjectMeta: metav1.ObjectMeta{
Name: "testCSV",
Annotations: map[string]string{
"olm.properties": fmt.Sprintf("[{\"type\": %s, \"value\": \"%s\"}]", property.TypeConstraint, "value"),
},
},
Spec: v1alpha1.ClusterServiceVersionSpec{
InstallModes: []v1alpha1.InstallMode{{Type: v1alpha1.InstallModeTypeMultiNamespace, Supported: true}},
InstallStrategy: v1alpha1.NamedInstallStrategy{
StrategySpec: v1alpha1.StrategyDetailsDeployment{
DeploymentSpecs: []v1alpha1.StrategyDeploymentSpec{
{
Name: "testDeployment",
Spec: appsv1.DeploymentSpec{
Template: corev1.PodTemplateSpec{
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "testContainer",
Image: "testImage",
},
},
},
},
},
},
},
Permissions: []v1alpha1.StrategyDeploymentPermissions{
{
ServiceAccountName: "testServiceAccount",
Expand All @@ -199,6 +218,7 @@ var _ = Describe("RegistryV1 Suite", func() {
},
},
}

svc = corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: "testService",
Expand All @@ -208,13 +228,16 @@ var _ = Describe("RegistryV1 Suite", func() {
installNamespace = "testInstallNamespace"
})

It("should convert into plain manifests successfully", func() {
It("should convert into plain manifests successfully with AllNamespaces", func() {
csv := baseCSV.DeepCopy()
csv.Spec.InstallModes = []v1alpha1.InstallMode{{Type: v1alpha1.InstallModeTypeAllNamespaces, Supported: true}}

By("creating a registry v1 bundle")
watchNamespaces = []string{"testWatchNs1", "testWatchNs2"}
watchNamespaces = []string{""}
unstructuredSvc := convertToUnstructured(svc)
registryv1Bundle = RegistryV1{
PackageName: "testPkg",
CSV: csv,
CSV: *csv,
Others: []unstructured.Unstructured{unstructuredSvc},
}

Expand All @@ -224,41 +247,51 @@ var _ = Describe("RegistryV1 Suite", func() {

By("verifying if plain bundle has required objects")
Expect(plainBundle).ShouldNot(BeNil())
Expect(plainBundle.Objects).To(HaveLen(6))
Expect(plainBundle.Objects).To(HaveLen(5))

By("verifying olm.targetNamespaces annotation in the deployment's pod template")
dep := findObjectByName("testDeployment", plainBundle.Objects)
Expect(dep).NotTo(BeNil())
Expect(dep.(*appsv1.Deployment).Spec.Template.Annotations).To(HaveKeyWithValue("olm.targetNamespaces", strings.Join(watchNamespaces, ",")))
})

It("should convert into plain manifests successfully with single namespace", func() {
csv = v1alpha1.ClusterServiceVersion{
ObjectMeta: metav1.ObjectMeta{
Name: "testCSV",
},
Spec: v1alpha1.ClusterServiceVersionSpec{
InstallModes: []v1alpha1.InstallMode{{Type: v1alpha1.InstallModeTypeSingleNamespace, Supported: true}},
InstallStrategy: v1alpha1.NamedInstallStrategy{
StrategySpec: v1alpha1.StrategyDetailsDeployment{
Permissions: []v1alpha1.StrategyDeploymentPermissions{
{
ServiceAccountName: "testServiceAccount",
Rules: []rbacv1.PolicyRule{
{
APIGroups: []string{"test"},
Resources: []string{"pods"},
Verbs: []string{"*"},
},
},
},
},
},
},
},
It("should convert into plain manifests successfully with MultiNamespace", func() {
csv := baseCSV.DeepCopy()
csv.Spec.InstallModes = []v1alpha1.InstallMode{{Type: v1alpha1.InstallModeTypeMultiNamespace, Supported: true}}

By("creating a registry v1 bundle")
watchNamespaces = []string{"testWatchNs1", "testWatchNs2"}
unstructuredSvc := convertToUnstructured(svc)
registryv1Bundle = RegistryV1{
PackageName: "testPkg",
CSV: *csv,
Others: []unstructured.Unstructured{unstructuredSvc},
}

By("converting to plain")
plainBundle, err := Convert(registryv1Bundle, installNamespace, watchNamespaces)
Expect(err).NotTo(HaveOccurred())

By("verifying if plain bundle has required objects")
Expect(plainBundle).ShouldNot(BeNil())
Expect(plainBundle.Objects).To(HaveLen(7))

By("verifying olm.targetNamespaces annotation in the deployment's pod template")
dep := findObjectByName("testDeployment", plainBundle.Objects)
Expect(dep).NotTo(BeNil())
Expect(dep.(*appsv1.Deployment).Spec.Template.Annotations).To(HaveKeyWithValue("olm.targetNamespaces", strings.Join(watchNamespaces, ",")))
})

It("should convert into plain manifests successfully with SingleNamespace", func() {
csv := baseCSV.DeepCopy()
csv.Spec.InstallModes = []v1alpha1.InstallMode{{Type: v1alpha1.InstallModeTypeSingleNamespace, Supported: true}}

By("creating a registry v1 bundle")
watchNamespaces = []string{"testWatchNs1"}
unstructuredSvc := convertToUnstructured(svc)
registryv1Bundle = RegistryV1{
PackageName: "testPkg",
CSV: csv,
CSV: *csv,
Others: []unstructured.Unstructured{unstructuredSvc},
}

Expand All @@ -268,41 +301,24 @@ var _ = Describe("RegistryV1 Suite", func() {

By("verifying if plain bundle has required objects")
Expect(plainBundle).ShouldNot(BeNil())
Expect(plainBundle.Objects).To(HaveLen(4))
Expect(plainBundle.Objects).To(HaveLen(5))

By("verifying olm.targetNamespaces annotation in the deployment's pod template")
dep := findObjectByName("testDeployment", plainBundle.Objects)
Expect(dep).NotTo(BeNil())
Expect(dep.(*appsv1.Deployment).Spec.Template.Annotations).To(HaveKeyWithValue("olm.targetNamespaces", strings.Join(watchNamespaces, ",")))
})

It("should convert into plain manifests successfully with own namespace", func() {
csv = v1alpha1.ClusterServiceVersion{
ObjectMeta: metav1.ObjectMeta{
Name: "testCSV",
},
Spec: v1alpha1.ClusterServiceVersionSpec{
InstallModes: []v1alpha1.InstallMode{{Type: v1alpha1.InstallModeTypeOwnNamespace, Supported: true}},
InstallStrategy: v1alpha1.NamedInstallStrategy{
StrategySpec: v1alpha1.StrategyDetailsDeployment{
Permissions: []v1alpha1.StrategyDeploymentPermissions{
{
ServiceAccountName: "testServiceAccount",
Rules: []rbacv1.PolicyRule{
{
APIGroups: []string{"test"},
Resources: []string{"pods"},
Verbs: []string{"*"},
},
},
},
},
},
},
},
}
csv := baseCSV.DeepCopy()
csv.Spec.InstallModes = []v1alpha1.InstallMode{{Type: v1alpha1.InstallModeTypeOwnNamespace, Supported: true}}

By("creating a registry v1 bundle")
watchNamespaces = []string{installNamespace}
unstructuredSvc := convertToUnstructured(svc)
registryv1Bundle = RegistryV1{
PackageName: "testPkg",
CSV: csv,
CSV: *csv,
Others: []unstructured.Unstructured{unstructuredSvc},
}

Expand All @@ -312,16 +328,24 @@ var _ = Describe("RegistryV1 Suite", func() {

By("verifying if plain bundle has required objects")
Expect(plainBundle).ShouldNot(BeNil())
Expect(plainBundle.Objects).To(HaveLen(4))
Expect(plainBundle.Objects).To(HaveLen(5))

By("verifying olm.targetNamespaces annotation in the deployment's pod template")
dep := findObjectByName("testDeployment", plainBundle.Objects)
Expect(dep).NotTo(BeNil())
Expect(dep.(*appsv1.Deployment).Spec.Template.Annotations).To(HaveKeyWithValue("olm.targetNamespaces", strings.Join(watchNamespaces, ",")))
})

It("should error when multinamespace mode is supported with an empty string in target namespaces", func() {
csv := baseCSV.DeepCopy()
csv.Spec.InstallModes = []v1alpha1.InstallMode{{Type: v1alpha1.InstallModeTypeMultiNamespace, Supported: true}}

By("creating a registry v1 bundle")
watchNamespaces = []string{"testWatchNs1", ""}
unstructuredSvc := convertToUnstructured(svc)
registryv1Bundle = RegistryV1{
PackageName: "testPkg",
CSV: csv,
CSV: *csv,
Others: []unstructured.Unstructured{unstructuredSvc},
}

Expand All @@ -332,21 +356,15 @@ var _ = Describe("RegistryV1 Suite", func() {
})

It("should error when single namespace mode is disabled with more than one target namespaces", func() {
csv = v1alpha1.ClusterServiceVersion{
ObjectMeta: metav1.ObjectMeta{
Name: "testCSV",
},
Spec: v1alpha1.ClusterServiceVersionSpec{
InstallModes: []v1alpha1.InstallMode{{Type: v1alpha1.InstallModeTypeSingleNamespace, Supported: false}},
},
}
csv := baseCSV.DeepCopy()
csv.Spec.InstallModes = []v1alpha1.InstallMode{{Type: v1alpha1.InstallModeTypeSingleNamespace, Supported: false}}

By("creating a registry v1 bundle")
watchNamespaces = []string{"testWatchNs1", "testWatchNs2"}
unstructuredSvc := convertToUnstructured(svc)
registryv1Bundle = RegistryV1{
PackageName: "testPkg",
CSV: csv,
CSV: *csv,
Others: []unstructured.Unstructured{unstructuredSvc},
}

Expand All @@ -357,26 +375,20 @@ var _ = Describe("RegistryV1 Suite", func() {
})

It("should error when all namespace mode is disabled with target namespace containing an empty string", func() {
csv = v1alpha1.ClusterServiceVersion{
ObjectMeta: metav1.ObjectMeta{
Name: "testCSV",
},
Spec: v1alpha1.ClusterServiceVersionSpec{
InstallModes: []v1alpha1.InstallMode{
{Type: v1alpha1.InstallModeTypeAllNamespaces, Supported: false},
{Type: v1alpha1.InstallModeTypeOwnNamespace, Supported: true},
{Type: v1alpha1.InstallModeTypeSingleNamespace, Supported: true},
{Type: v1alpha1.InstallModeTypeMultiNamespace, Supported: true},
},
},
csv := baseCSV.DeepCopy()
csv.Spec.InstallModes = []v1alpha1.InstallMode{
{Type: v1alpha1.InstallModeTypeAllNamespaces, Supported: false},
{Type: v1alpha1.InstallModeTypeOwnNamespace, Supported: true},
{Type: v1alpha1.InstallModeTypeSingleNamespace, Supported: true},
{Type: v1alpha1.InstallModeTypeMultiNamespace, Supported: true},
}

By("creating a registry v1 bundle")
watchNamespaces = []string{""}
unstructuredSvc := convertToUnstructured(svc)
registryv1Bundle = RegistryV1{
PackageName: "testPkg",
CSV: csv,
CSV: *csv,
Others: []unstructured.Unstructured{unstructuredSvc},
}

Expand All @@ -387,12 +399,15 @@ var _ = Describe("RegistryV1 Suite", func() {
})

It("should propagate csv annotations to chart metadata annotation", func() {
csv := baseCSV.DeepCopy()
csv.Spec.InstallModes = []v1alpha1.InstallMode{{Type: v1alpha1.InstallModeTypeMultiNamespace, Supported: true}}

By("creating a registry v1 bundle")
watchNamespaces = []string{"testWatchNs1", "testWatchNs2"}
unstructuredSvc := convertToUnstructured(svc)
registryv1Bundle = RegistryV1{
PackageName: "testPkg",
CSV: csv,
CSV: *csv,
Others: []unstructured.Unstructured{unstructuredSvc},
}

Expand Down Expand Up @@ -462,11 +477,11 @@ func convertToUnstructured(obj interface{}) unstructured.Unstructured {
return unstructured.Unstructured{Object: unstructuredObj}
}

func containsObject(obj unstructured.Unstructured, result []client.Object) client.Object {
func findObjectByName(name string, result []client.Object) client.Object {
for _, o := range result {
// Since this is a controlled env, comparing only the names is sufficient for now.
// In future, compare GVKs too by ensuring its set on the unstructuredObj.
if o.GetName() == obj.GetName() {
if o.GetName() == name {
return o
}
}
Expand Down

0 comments on commit 3064fae

Please sign in to comment.