Skip to content
This repository has been archived by the owner on Aug 12, 2024. It is now read-only.

Commit

Permalink
Add install mode validation
Browse files Browse the repository at this point in the history
New validation only allows AllNamespaces install mode to be used.

Signed-off-by: Mikalai Radchuk <[email protected]>
  • Loading branch information
m1kola committed Jun 12, 2024
1 parent ac1802e commit b64485c
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 124 deletions.
41 changes: 22 additions & 19 deletions pkg/convert/registryv1.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,26 +141,26 @@ func RegistryV1ToPlain(rv1 fs.FS, installNamespace string, watchNamespaces []str
return plainFS, nil
}

func validateTargetNamespaces(supportedInstallModes sets.Set[string], installNamespace string, targetNamespaces []string) error {
set := sets.New[string](targetNamespaces...)
switch {
case set.Len() == 0 || (set.Len() == 1 && set.Has("")):
func validateInstallModes(supportedInstallModes sets.Set[string]) error {
if !supportedInstallModes.Has(string(v1alpha1.InstallModeTypeAllNamespaces)) {
return fmt.Errorf(
"the bundle does not support required %q install mode. Supported install modes: %v",
v1alpha1.InstallModeTypeAllNamespaces,
sets.List(supportedInstallModes),
)
}

return nil
}

func validateTargetNamespaces(supportedInstallModes sets.Set[string], targetNamespaces []string) error {
set := sets.New(targetNamespaces...)
if set.Len() == 0 || (set.Len() == 1 && set.Has("")) {
if supportedInstallModes.Has(string(v1alpha1.InstallModeTypeAllNamespaces)) {
return nil
}
case set.Len() == 1 && !set.Has(""):
if supportedInstallModes.Has(string(v1alpha1.InstallModeTypeSingleNamespace)) {
return nil
}
if supportedInstallModes.Has(string(v1alpha1.InstallModeTypeOwnNamespace)) && targetNamespaces[0] == installNamespace {
return nil
}
default:
if supportedInstallModes.Has(string(v1alpha1.InstallModeTypeMultiNamespace)) && !set.Has("") {
return nil
}
}
return fmt.Errorf("supported install modes %v do not support target namespaces %v", sets.List[string](supportedInstallModes), targetNamespaces)
return fmt.Errorf("supported install modes %v do not support target namespaces %v", sets.List(supportedInstallModes), targetNamespaces)
}

func saNameOrDefault(saName string) string {
Expand All @@ -183,15 +183,18 @@ func Convert(in RegistryV1, installNamespace string, targetNamespaces []string)
supportedInstallModes.Insert(string(im.Type))
}
}

if err := validateInstallModes(supportedInstallModes); err != nil {
return nil, err
}

if len(targetNamespaces) == 0 {
if supportedInstallModes.Has(string(v1alpha1.InstallModeTypeAllNamespaces)) {
targetNamespaces = []string{""}
} else if supportedInstallModes.Has(string(v1alpha1.InstallModeTypeOwnNamespace)) {
targetNamespaces = []string{installNamespace}
}
}

if err := validateTargetNamespaces(supportedInstallModes, installNamespace, targetNamespaces); err != nil {
if err := validateTargetNamespaces(supportedInstallModes, targetNamespaces); err != nil {
return nil, err
}

Expand Down
114 changes: 9 additions & 105 deletions pkg/convert/registryv1_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ var _ = Describe("RegistryV1 Suite", func() {
Name: "testCSV",
},
Spec: v1alpha1.ClusterServiceVersionSpec{
InstallModes: []v1alpha1.InstallMode{{Type: v1alpha1.InstallModeTypeMultiNamespace, Supported: true}},
InstallModes: []v1alpha1.InstallMode{{Type: v1alpha1.InstallModeTypeAllNamespaces, Supported: true}},
InstallStrategy: v1alpha1.NamedInstallStrategy{
StrategySpec: v1alpha1.StrategyDetailsDeployment{
Permissions: []v1alpha1.StrategyDeploymentPermissions{
Expand Down Expand Up @@ -203,9 +203,8 @@ var _ = Describe("RegistryV1 Suite", func() {
installNamespace = "testInstallNamespace"
})

It("should convert into plain manifests successfully", func() {
It("should convert a bundle with AllNamespaces install mode and empty list of target namespaces successfully", func() {
By("creating a registry v1 bundle")
watchNamespaces = []string{"testWatchNs1", "testWatchNs2"}
unstructuredSvc := convertToUnstructured(svc)
registryv1Bundle = RegistryV1{
PackageName: "testPkg",
Expand All @@ -214,86 +213,17 @@ var _ = Describe("RegistryV1 Suite", func() {
}

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(6))
})

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{"*"},
},
},
},
},
},
},
},
}

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

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

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

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{"*"},
},
},
},
},
},
},
},
}

It("should convert a bundle with AllNamespaces install mode and one empty target namespace successfully", func() {
By("creating a registry v1 bundle")
watchNamespaces = []string{installNamespace}
watchNamespaces = []string{corev1.NamespaceAll}
unstructuredSvc := convertToUnstructured(svc)
registryv1Bundle = RegistryV1{
PackageName: "testPkg",
Expand All @@ -310,34 +240,9 @@ var _ = Describe("RegistryV1 Suite", func() {
Expect(plainBundle.Objects).To(HaveLen(4))
})

It("should error when multinamespace mode is supported with an empty string in target namespaces", func() {
By("creating a registry v1 bundle")
watchNamespaces = []string{"testWatchNs1", ""}
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).To(HaveOccurred())
Expect(plainBundle).To(BeNil())
})

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}},
},
}

It("should error when a bundle supports AllNamespaces install mode, but multiple target namespaces provided", func() {
By("creating a registry v1 bundle")
watchNamespaces = []string{"testWatchNs1", "testWatchNs2"}
watchNamespaces = []string{"testWatchNs1", corev1.NamespaceAll}
unstructuredSvc := convertToUnstructured(svc)
registryv1Bundle = RegistryV1{
PackageName: "testPkg",
Expand All @@ -351,7 +256,7 @@ var _ = Describe("RegistryV1 Suite", func() {
Expect(plainBundle).To(BeNil())
})

It("should error when all namespace mode is disabled with target namespace containing an empty string", func() {
It("should error when AllNamespaces install mode is not supported", func() {
csv = v1alpha1.ClusterServiceVersion{
ObjectMeta: metav1.ObjectMeta{
Name: "testCSV",
Expand All @@ -367,7 +272,6 @@ var _ = Describe("RegistryV1 Suite", func() {
}

By("creating a registry v1 bundle")
watchNamespaces = []string{""}
unstructuredSvc := convertToUnstructured(svc)
registryv1Bundle = RegistryV1{
PackageName: "testPkg",
Expand All @@ -376,7 +280,7 @@ var _ = Describe("RegistryV1 Suite", func() {
}

By("converting to plain")
plainBundle, err := Convert(registryv1Bundle, installNamespace, watchNamespaces)
plainBundle, err := Convert(registryv1Bundle, installNamespace, nil)
Expect(err).To(HaveOccurred())
Expect(plainBundle).To(BeNil())
})
Expand Down

0 comments on commit b64485c

Please sign in to comment.