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

Commit

Permalink
[Add] Support for other Install strategies
Browse files Browse the repository at this point in the history
This PR removes the requirement that AllNamespace mode should be supported always in a registry+v1 format.

It does so by:

1. Adding a field to specify watch namespaces in BundleDeployment Spec.
2. While converting from registryV1 to plain bundle, we now generate roles for all specified targetNamespaces which are being watched.

Signed-off-by: Varsha Prasad Narsing <[email protected]>
  • Loading branch information
varshaprasad96 committed Jan 17, 2024
1 parent 2320883 commit 1790528
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 19 deletions.
1 change: 0 additions & 1 deletion api/v1alpha2/bundle_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ const (
SourceTypeImage SourceType = "image"
SourceTypeGit SourceType = "git"
SourceTypeConfigMaps SourceType = "configMaps"
SourceTypeUpload SourceType = "upload"
SourceTypeHTTP SourceType = "http"

TypeUnpacked = "Unpacked"
Expand Down
3 changes: 3 additions & 0 deletions api/v1alpha2/bundledeployment_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ type BundleDeploymentSpec struct {
// Config is provisioner specific configurations
// +kubebuilder:pruning:PreserveUnknownFields
Config runtime.RawExtension `json:"config,omitempty"`
// +kubebuilder:validation:Optional
// watchNamespaces indicates which namespaces the operator should watch.
WatchNamespaces []string `json:"watchNamespaces,omitempty"`
}

// BundleDeploymentStatus defines the observed state of BundleDeployment
Expand Down
5 changes: 5 additions & 0 deletions api/v1alpha2/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 13 additions & 17 deletions internal/convert/registryv1.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ type Plain struct {
Objects []client.Object
}

func RegistryV1ToPlain(rv1 fs.FS) (fs.FS, error) {
func RegistryV1ToPlain(rv1 fs.FS, watchnamespaces []string) (fs.FS, error) {
reg := RegistryV1{}
fileData, err := fs.ReadFile(rv1, filepath.Join("metadata", "annotations.yaml"))
if err != nil {
Expand Down Expand Up @@ -102,7 +102,7 @@ func RegistryV1ToPlain(rv1 fs.FS) (fs.FS, error) {
}
}

plain, err := Simple(reg)
plain, err := Convert(reg, "", watchnamespaces)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -165,10 +165,6 @@ func validateTargetNamespaces(supportedInstallModes sets.Set[string], installNam
return fmt.Errorf("supported install modes %v do not support target namespaces %v", sets.List[string](supportedInstallModes), targetNamespaces)
}

func Simple(in RegistryV1) (*Plain, error) {
return Convert(in, "", nil)
}

func saNameOrDefault(saName string) string {
if saName == "" {
return "default"
Expand All @@ -189,10 +185,7 @@ func Convert(in RegistryV1, installNamespace string, targetNamespaces []string)
supportedInstallModes.Insert(string(im.Type))
}
}
if !supportedInstallModes.Has(string(v1alpha1.InstallModeTypeAllNamespaces)) {
return nil, fmt.Errorf("AllNamespace install mode must be enabled")
}
if targetNamespaces == nil {
if len(targetNamespaces) == 0 {
if supportedInstallModes.Has(string(v1alpha1.InstallModeTypeAllNamespaces)) {
targetNamespaces = []string{""}
} else if supportedInstallModes.Has(string(v1alpha1.InstallModeTypeOwnNamespace)) {
Expand Down Expand Up @@ -274,15 +267,18 @@ func Convert(in RegistryV1, installNamespace string, targetNamespaces []string)
permissions = nil
}

for _, permission := range permissions {
saName := saNameOrDefault(permission.ServiceAccountName)
name, err := generateName(fmt.Sprintf("%s-%s", in.CSV.Name, saName), permission)
if err != nil {
return nil, err
for _, ns := range targetNamespaces {
for _, permission := range permissions {
saName := saNameOrDefault(permission.ServiceAccountName)
name, err := generateName(fmt.Sprintf("%s-%s", in.CSV.Name, saName), permission)
if err != nil {
return nil, err
}
roles = append(roles, newRole(ns, name, permission.Rules))
roleBindings = append(roleBindings, newRoleBinding(ns, name, name, installNamespace, saName))
}
roles = append(roles, newRole(installNamespace, name, permission.Rules))
roleBindings = append(roleBindings, newRoleBinding(installNamespace, name, name, installNamespace, saName))
}

for _, permission := range clusterPermissions {
saName := saNameOrDefault(permission.ServiceAccountName)
name, err := generateName(fmt.Sprintf("%s-%s", in.CSV.Name, saName), permission)
Expand Down
62 changes: 62 additions & 0 deletions internal/convert/registryv1_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
. "github.com/onsi/gomega"
"github.com/operator-framework/api/pkg/operators/v1alpha1"
corev1 "k8s.io/api/core/v1"
v1 "k8s.io/api/rbac/v1"

Check failure on line 10 in internal/convert/registryv1_test.go

View workflow job for this annotation

GitHub Actions / lint

import "k8s.io/api/rbac/v1" imported as "v1" but must be "rbacv1" according to config (importas)
schedulingv1 "k8s.io/api/scheduling/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
Expand Down Expand Up @@ -159,6 +160,67 @@ var _ = Describe("RegistryV1 Suite", func() {
})
})

Context("Should generate objects successfully based on target namespaces", func() {
var (
svc corev1.Service
csv v1alpha1.ClusterServiceVersion
watchNamespaces []string
)

BeforeEach(func() {
csv = v1alpha1.ClusterServiceVersion{
ObjectMeta: metav1.ObjectMeta{
Name: "testCSV",
},
Spec: v1alpha1.ClusterServiceVersionSpec{
InstallModes: []v1alpha1.InstallMode{{Type: v1alpha1.InstallModeTypeMultiNamespace, Supported: true}},
InstallStrategy: v1alpha1.NamedInstallStrategy{
StrategySpec: v1alpha1.StrategyDetailsDeployment{
Permissions: []v1alpha1.StrategyDeploymentPermissions{
{
ServiceAccountName: "testServiceAccount",
Rules: []v1.PolicyRule{
{
APIGroups: []string{"test"},
Resources: []string{"pods"},
Verbs: []string{"*"},
},
},
},
},
},
},
},
}
svc = corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: "testService",
},
}
svc.SetGroupVersionKind(schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Service"})
installNamespace = "testInstallNamespace"
watchNamespaces = []string{"testWatchNs1", "testWatchNs2"}
})

It("should convert into plain manifests successfully", func() {
By("creating a registry v1 bundle")
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(len(plainBundle.Objects)).To(BeEquivalentTo(7))
})
})

})
})

Expand Down
2 changes: 1 addition & 1 deletion internal/provisioner/registry/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const (
)

func HandleBundleDeployment(ctx context.Context, fsys fs.FS, bd *rukpakv1alpha2.BundleDeployment) (*chart.Chart, chartutil.Values, error) {
plainFS, err := convert.RegistryV1ToPlain(fsys)
plainFS, err := convert.RegistryV1ToPlain(fsys, bd.Spec.WatchNamespaces)
if err != nil {
return nil, nil, fmt.Errorf("convert registry+v1 bundle to plain+v0 bundle: %v", err)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,12 @@ spec:
required:
- type
type: object
watchNamespaces:
description: watchNamespaces indicates which namespaces the operator
should watch.
items:
type: string
type: array
required:
- provisionerClassName
- source
Expand Down

0 comments on commit 1790528

Please sign in to comment.