diff --git a/api/v3/commonservice_types.go b/api/v3/commonservice_types.go index c37daed55..018c0e697 100644 --- a/api/v3/commonservice_types.go +++ b/api/v3/commonservice_types.go @@ -129,6 +129,10 @@ type OperatorConfig struct { // zero and not specified. Defaults to 1. // +optional Replicas *int32 `json:"replicas,omitempty" protobuf:"varint,1,opt,name=replicas"` + // UserManaged is a flag that indicates whether the operator is managed by + // user or not. If set the value will propagate down to UserManaged field + // in the OperandRegistry + UserManaged bool `json:"userManaged,omitempty"` } // LicenseList defines the license specification in CSV diff --git a/bundle/manifests/ibm-common-service-operator.clusterserviceversion.yaml b/bundle/manifests/ibm-common-service-operator.clusterserviceversion.yaml index a7969a185..6585888e8 100644 --- a/bundle/manifests/ibm-common-service-operator.clusterserviceversion.yaml +++ b/bundle/manifests/ibm-common-service-operator.clusterserviceversion.yaml @@ -23,7 +23,7 @@ metadata: capabilities: Seamless Upgrades cloudPakThemesVersion: styles470.css containerImage: icr.io/cpopen/common-service-operator:latest - createdAt: "2024-04-11T02:45:28Z" + createdAt: "2024-09-09T21:00:30Z" description: The IBM Cloud Pak foundational services operator is used to deploy IBM foundational services. nss.operator.ibm.com/managed-operators: ibm-common-service-operator nss.operator.ibm.com/managed-webhooks: "" @@ -395,8 +395,6 @@ spec: ephemeral-storage: 256Mi memory: 200Mi securityContext: - seccompProfile: - type: RuntimeDefault allowPrivilegeEscalation: false capabilities: drop: @@ -404,6 +402,8 @@ spec: privileged: false readOnlyRootFilesystem: true runAsNonRoot: true + seccompProfile: + type: RuntimeDefault volumeMounts: - mountPath: /tmp/k8s-webhook-server/serving-certs name: cert diff --git a/bundle/manifests/operator.ibm.com_commonservices.yaml b/bundle/manifests/operator.ibm.com_commonservices.yaml index 9218355a0..acccabc54 100644 --- a/bundle/manifests/operator.ibm.com_commonservices.yaml +++ b/bundle/manifests/operator.ibm.com_commonservices.yaml @@ -150,6 +150,12 @@ spec: zero and not specified. Defaults to 1. format: int32 type: integer + userManaged: + description: |- + UserManaged is a flag that indicates whether the operator is managed by + user or not. If set the value will propagate down to UserManaged field + in the OperandRegistry + type: boolean type: object type: array x-kubernetes-preserve-unknown-fields: true diff --git a/config/crd/bases/operator.ibm.com_commonservices.yaml b/config/crd/bases/operator.ibm.com_commonservices.yaml index a8ff3337a..a22e401e0 100644 --- a/config/crd/bases/operator.ibm.com_commonservices.yaml +++ b/config/crd/bases/operator.ibm.com_commonservices.yaml @@ -147,6 +147,12 @@ spec: zero and not specified. Defaults to 1. format: int32 type: integer + userManaged: + description: |- + UserManaged is a flag that indicates whether the operator is managed by + user or not. If set the value will propagate down to UserManaged field + in the OperandRegistry + type: boolean type: object type: array x-kubernetes-preserve-unknown-fields: true diff --git a/controllers/common/util.go b/controllers/common/util.go index 0c428a3a3..b83bb8613 100644 --- a/controllers/common/util.go +++ b/controllers/common/util.go @@ -50,6 +50,7 @@ import ( apiv3 "github.com/IBM/ibm-common-service-operator/v4/api/v3" "github.com/IBM/ibm-common-service-operator/v4/controllers/constant" nssv1 "github.com/IBM/ibm-namespace-scope-operator/v4/api/v1" + odlm "github.com/IBM/operand-deployment-lifecycle-manager/v4/api/v1alpha1" ) type CsMaps struct { @@ -871,3 +872,29 @@ func SanitizeData(data interface{}, valueType string, isEmpty bool) interface{} return nil } } + +func UpdateOpRegUserManaged(opreg *odlm.OperandRegistry, operatorName string, value bool) error { + packageName := GetPackageNameByServiceName(opreg, operatorName) + if packageName == "" { + return fmt.Errorf("failed to find package name while updating OperandRegistry with user managed field") + } + for i := range opreg.Spec.Operators { + i := i + if opreg.Spec.Operators[i].PackageName != packageName { + continue + } + + opreg.Spec.Operators[i].UserManaged = value + } + return nil +} + +func GetPackageNameByServiceName(opreg *odlm.OperandRegistry, operatorName string) string { + for _, v := range opreg.Spec.Operators { + v := v + if v.Name == operatorName { + return v.PackageName + } + } + return "" +} diff --git a/controllers/operatorconfig.go b/controllers/operatorconfig.go index 3b64cbab3..f973b194a 100644 --- a/controllers/operatorconfig.go +++ b/controllers/operatorconfig.go @@ -27,6 +27,7 @@ import ( "k8s.io/klog" v3 "github.com/IBM/ibm-common-service-operator/v4/api/v3" + util "github.com/IBM/ibm-common-service-operator/v4/controllers/common" "github.com/IBM/ibm-common-service-operator/v4/controllers/constant" odlm "github.com/IBM/operand-deployment-lifecycle-manager/v4/api/v1alpha1" ) @@ -35,6 +36,9 @@ func (r *CommonServiceReconciler) updateOperatorConfig(ctx context.Context, conf klog.Info("Applying OperatorConfig") if configList == nil { + if err := r.clearAllUserManaged(ctx); err != nil { + return false, err + } return true, nil } @@ -48,6 +52,9 @@ func (r *CommonServiceReconciler) updateOperatorConfig(ctx context.Context, conf if packageName != "cloud-native-postgresql" { return false, errors.New("failed to update OperatorConfig. This feature is only available for cloud-native-postgresql operator") } + if err := r.updateUserManaged(ctx, config.Name, config.UserManaged); err != nil { + return false, err + } if config.Replicas == nil { return true, nil } @@ -88,3 +95,29 @@ func (r *CommonServiceReconciler) fetchPackageNameFromOpReg(ctx context.Context, } return "", nil } + +func (r *CommonServiceReconciler) updateUserManaged(ctx context.Context, operatorName string, value bool) error { + opreg := &odlm.OperandRegistry{} + if err := r.Reader.Get(ctx, types.NamespacedName{Namespace: util.GetServicesNamespace(r.Reader), Name: "common-service"}, opreg); err != nil { + return err + } + if err := util.UpdateOpRegUserManaged(opreg, operatorName, value); err != nil { + return err + } + if err := r.Client.Update(ctx, opreg); err != nil { + return err + } + return nil +} + +func (r *CommonServiceReconciler) clearAllUserManaged(ctx context.Context) error { + opreg := &odlm.OperandRegistry{} + if err := r.Reader.Get(ctx, types.NamespacedName{Namespace: util.GetServicesNamespace(r.Reader), Name: "common-service"}, opreg); err != nil { + return err + } + for i := range opreg.Spec.Operators { + i := i + opreg.Spec.Operators[i].UserManaged = false + } + return r.Client.Update(ctx, opreg) +}