diff --git a/api/v1alpha1/bundle_types.go b/api/v1alpha1/bundle_types.go index d09db9ab..5684be6a 100644 --- a/api/v1alpha1/bundle_types.go +++ b/api/v1alpha1/bundle_types.go @@ -56,6 +56,9 @@ type BundleSpec struct { ProvisionerClassName string `json:"provisionerClassName"` // Source defines the configuration for the underlying Bundle content. Source BundleSource `json:"source"` + // +kubebuilder:validation:Optional + // watchNamespaces indicates which namespaces the operator should watch. + WatchNamespaces []string `json:"watchNamespaces,omitempty"` } type BundleSource struct { diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 25fdf03f..5f130da8 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -243,6 +243,11 @@ func (in *BundleSource) DeepCopy() *BundleSource { func (in *BundleSpec) DeepCopyInto(out *BundleSpec) { *out = *in in.Source.DeepCopyInto(&out.Source) + if in.WatchNamespaces != nil { + in, out := &in.WatchNamespaces, &out.WatchNamespaces + *out = make([]string, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BundleSpec. diff --git a/internal/convert/registryv1.go b/internal/convert/registryv1.go index c9ef7095..95d113bc 100644 --- a/internal/convert/registryv1.go +++ b/internal/convert/registryv1.go @@ -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 { @@ -102,7 +102,7 @@ func RegistryV1ToPlain(rv1 fs.FS) (fs.FS, error) { } } - plain, err := Simple(reg) + plain, err := Simple(reg, watchNamespaces) if err != nil { return nil, err } @@ -165,8 +165,8 @@ 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 Simple(in RegistryV1, watchNamespaces []string) (*Plain, error) { + return Convert(in, "", watchNamespaces) } func saNameOrDefault(saName string) string { @@ -189,9 +189,6 @@ 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 supportedInstallModes.Has(string(v1alpha1.InstallModeTypeAllNamespaces)) { targetNamespaces = []string{""} @@ -274,15 +271,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) diff --git a/internal/provisioner/registry/registry.go b/internal/provisioner/registry/registry.go index f9e058d5..887bb544 100644 --- a/internal/provisioner/registry/registry.go +++ b/internal/provisioner/registry/registry.go @@ -15,8 +15,8 @@ const ( ProvisionerID = "core-rukpak-io-registry" ) -func HandleBundle(_ context.Context, fsys fs.FS, _ *rukpakv1alpha1.Bundle) (fs.FS, error) { - plainFS, err := convert.RegistryV1ToPlain(fsys) +func HandleBundle(_ context.Context, fsys fs.FS, bundle *rukpakv1alpha1.Bundle) (fs.FS, error) { + plainFS, err := convert.RegistryV1ToPlain(fsys, bundle.Spec.WatchNamespaces) if err != nil { return nil, fmt.Errorf("convert registry+v1 bundle to plain+v0 bundle: %v", err) } diff --git a/manifests/base/apis/crds/core.rukpak.io_bundledeployments.yaml b/manifests/base/apis/crds/core.rukpak.io_bundledeployments.yaml index f604455b..30ee3bc4 100644 --- a/manifests/base/apis/crds/core.rukpak.io_bundledeployments.yaml +++ b/manifests/base/apis/crds/core.rukpak.io_bundledeployments.yaml @@ -281,6 +281,12 @@ spec: required: - type type: object + watchNamespaces: + description: watchNamespaces indicates which namespaces the + operator should watch. + items: + type: string + type: array required: - provisionerClassName - source diff --git a/manifests/base/apis/crds/core.rukpak.io_bundles.yaml b/manifests/base/apis/crds/core.rukpak.io_bundles.yaml index da7951bb..54fc3c87 100644 --- a/manifests/base/apis/crds/core.rukpak.io_bundles.yaml +++ b/manifests/base/apis/crds/core.rukpak.io_bundles.yaml @@ -230,6 +230,12 @@ spec: required: - type type: object + watchNamespaces: + description: watchNamespaces indicates which namespaces the operator + should watch. + items: + type: string + type: array required: - provisionerClassName - source