diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..9fab9fa35 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,13 @@ +**What this PR does / why we need it**: + +**Which issue(s) this PR fixes**: +Fixes # + +**Special notes for your reviewer**: + +1. How the test is done? + +**How to backport this PR to other branch**: +1. Add label to this PR with the target branch name `backport ` +2. The PR will be automatically created in the target branch after merging this PR +3. If this PR is already merged, you can still add the label with the target branch name `backport ` and leave a comment `/backport` to trigger the backport action \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml index e56d49520..982f0fe71 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -9,9 +9,4 @@ updates: directory: "/" schedule: interval: daily - target-branch: "release-ltsr" - - package-ecosystem: docker - directory: "/" - schedule: - interval: daily - target-branch: "release-323" + target-branch: "release-sc2" diff --git a/.github/workflows/cherry-pick.yaml b/.github/workflows/cherry-pick.yaml new file mode 100644 index 000000000..02c49e8e5 --- /dev/null +++ b/.github/workflows/cherry-pick.yaml @@ -0,0 +1,32 @@ +name: cherry pick merged pull request +on: + pull_request_target: + types: [closed] + issue_comment: + types: [created] +permissions: + contents: write # so it can comment + pull-requests: write # so it can create pull requests +jobs: + backport: + name: Backport pull request + runs-on: ubuntu-latest + + # Only run when pull request is merged + # or when a comment starting with `/backport` is created by someone other than the + # https://github.com/backport-action bot user (user id: 97796249). Note that if you use your + # own PAT as `github_token`, that you should replace this id with yours. + if: > + ( + github.event_name == 'pull_request_target' && + github.event.pull_request.merged + ) || ( + github.event_name == 'issue_comment' && + github.event.issue.pull_request && + github.event.comment.user.id != 97796249 && + startsWith(github.event.comment.body, '/backport') + ) + steps: + - uses: actions/checkout@v4 + - name: Create backport pull requests + uses: korthout/backport-action@v2 \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 58016d737..fb738b600 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Build the manager binary -FROM docker.io/golang:1.21.3-bullseye as builder +FROM docker-na-public.artifactory.swg-devops.com/hyc-cloud-private-dockerhub-docker-remote/golang:1.23.2 as builder ARG GOARCH WORKDIR /workspace @@ -21,7 +21,7 @@ RUN CGO_ENABLED=0 GOOS=linux GO111MODULE=on go build -a -o manager main.go # Use distroless as minimal base image to package the manager binary # Refer to https://github.com/GoogleContainerTools/distroless for more details # FROM gcr.io/distroless/static:nonroot -FROM docker-na-public.artifactory.swg-devops.com/hyc-cloud-private-edge-docker-local/build-images/ubi8-minimal:latest +FROM docker-na-public.artifactory.swg-devops.com/hyc-cloud-private-edge-docker-local/build-images/ubi9-minimal:latest ARG VCS_REF ARG VCS_URL @@ -40,6 +40,7 @@ LABEL org.label-schema.vendor="IBM" \ WORKDIR / COPY --from=builder /workspace/manager . +COPY hack/keycloak-themes/cloudpak-theme.jar /hack/keycloak-themes/cloudpak-theme.jar # copy licenses RUN mkdir /licenses diff --git a/Makefile b/Makefile index 21c126ae4..6e4ff2a3b 100644 --- a/Makefile +++ b/Makefile @@ -20,9 +20,9 @@ OPERATOR_SDK ?= $(shell which operator-sdk) CONTROLLER_GEN ?= $(shell which controller-gen) KUSTOMIZE ?= $(shell which kustomize) YQ_VERSION=v4.27.3 -KUSTOMIZE_VERSION=v3.8.7 -OPERATOR_SDK_VERSION=v1.31.0 -CONTROLLER_TOOLS_VERSION ?= v0.6.1 +KUSTOMIZE_VERSION=v5.0.0 +OPERATOR_SDK_VERSION=v1.38.0 +CONTROLLER_TOOLS_VERSION ?= v0.14.0 CSV_PATH=bundle/manifests/ibm-common-service-operator.clusterserviceversion.yaml @@ -79,9 +79,11 @@ REGISTRY ?= "docker-na-public.artifactory.swg-devops.com/hyc-cloud-private-scrat OPERATOR_IMAGE_NAME ?= common-service-operator # Current Operator bundle image name BUNDLE_IMAGE_NAME ?= common-service-operator-bundle +# Current Operator image with registry +IMG ?= icr.io/cpopen/common-service-operator:latest -CHANNELS := v4.3 -DEFAULT_CHANNEL := v4.3 +CHANNELS := v4.11 +DEFAULT_CHANNEL := v4.11 # Options for 'bundle-build' ifneq ($(origin CHANNELS), undefined) @@ -92,18 +94,21 @@ BUNDLE_DEFAULT_CHANNEL := --default-channel=$(DEFAULT_CHANNEL) endif BUNDLE_METADATA_OPTS ?= $(BUNDLE_CHANNELS) $(BUNDLE_DEFAULT_CHANNEL) -# Produce CRDs that work back to Kubernetes 1.11 (no version conversion) -CRD_OPTIONS ?= "crd:trivialVersions=true" - ifeq ($(BUILD_LOCALLY),0) export CONFIG_DOCKER_TARGET = config-docker export CONFIG_DOCKER_TARGET_QUAY = config-docker-quay endif include common/Makefile.common.mk +include hack/keycloak-themes/Makefile ##@ Development +## Location to install dependencies to +LOCALBIN ?= $(shell pwd)/bin +$(LOCALBIN): + mkdir -p $(LOCALBIN) + clis: yq kustomize operator-sdk yq: ## Install yq, a yaml processor @@ -179,7 +184,7 @@ deploy: manifests ## Deploy controller in the configured Kubernetes cluster in ~ cd config/manager && $(KUSTOMIZE) edit set image quay.io/opencloudio/common-service-operator=$(QUAY_REGISTRY)/$(OPERATOR_IMAGE_NAME):$(RELEASE_VERSION) $(KUSTOMIZE) build config/default | kubectl apply -f - -build-dev-image: +build-dev-image: cloudpak-theme.jar @echo "Building the $(OPERATOR_IMAGE_NAME) docker dev image for $(LOCAL_ARCH)..." @docker build -t $(REGISTRY)/$(OPERATOR_IMAGE_NAME)-$(LOCAL_ARCH):dev \ --build-arg VCS_REF=$(VCS_REF) --build-arg VCS_URL=$(VCS_URL) \ @@ -224,7 +229,7 @@ test-profile: yq ##@ Generate code and manifests manifests: controller-gen ## Generate manifests e.g. CRD, RBAC etc. - $(CONTROLLER_GEN) $(CRD_OPTIONS) rbac:roleName=ibm-common-service-operator webhook paths="./..." output:crd:artifacts:config=config/crd/bases + $(CONTROLLER_GEN) crd rbac:roleName=ibm-common-service-operator webhook paths="./..." output:crd:artifacts:config=config/crd/bases generate: controller-gen ## Generate code e.g. API etc. $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..." @@ -237,9 +242,34 @@ bundle-manifests: clis $(YQ) eval -i '.spec.webhookdefinitions[0].deploymentName = "ibm-common-service-operator" | .spec.webhookdefinitions[1].deploymentName = "ibm-common-service-operator"' ${CSV_PATH} $(YQ) eval-all -i '.spec.relatedImages = load("config/manifests/bases/ibm-common-service-operator.clusterserviceversion.yaml").spec.relatedImages' bundle/manifests/ibm-common-service-operator.clusterserviceversion.yaml -generate-all: yq kustomize operator-sdk generate manifests ## Generate bundle manifests, metadata and package manifests +generate-all: yq kustomize operator-sdk generate manifests cloudpak-theme-version ## Generate bundle manifests, metadata and package manifests $(OPERATOR_SDK) generate kustomize manifests -q - - make bundle-manifests CHANNELS=v4.3 DEFAULT_CHANNEL=v4.3 + - make bundle-manifests CHANNELS=v4.11 DEFAULT_CHANNEL=v4.11 + +##@ Helm Chart Generation + +.PHONY: deploy-dryrun +deploy-dryrun: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config. + cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG} + $(KUSTOMIZE) build config/default --output config/ibm-common-service-operator.yaml + +.PHONY: helm +helm: deploy-dryrun kustohelmize + $(KUSTOHELMIZE) create --from=config/ibm-common-service-operator.yaml helm/ibm-common-service-operator + helm lint helm/ibm-common-service-operator + +KUBERNETES-SPLIT-YAML ?= $(LOCALBIN)/kubernetes-split-yaml +KUSTOHELMIZE ?= $(LOCALBIN)/kustohelmize + +.PHONY: kubernetes-split-yaml +kubernetes-split-yaml: $(KUBERNETES-SPLIT-YAML) ## Download kubernetes-split-yaml locally if necessary. +$(KUBERNETES-SPLIT-YAML): $(LOCALBIN) + GOBIN=$(LOCALBIN) go install github.com/mogensen/kubernetes-split-yaml@v0.4.0 + +.PHONY: kustohelmize +kustohelmize: $(KUSTOHELMIZE) ## Download kustohelmize locally if necessary. +$(KUSTOHELMIZE): $(LOCALBIN) kubernetes-split-yaml + GOBIN=$(LOCALBIN) go install github.com/yeahdongcn/kustohelmize@v0.4.0 ##@ Test @@ -255,7 +285,7 @@ e2e-test: ## Run e2e test ##@ Build -build-operator-image: $(CONFIG_DOCKER_TARGET) ## Build the operator image. +build-operator-image: $(CONFIG_DOCKER_TARGET) cloudpak-theme.jar ## Build the operator image. @echo "Building the $(OPERATOR_IMAGE_NAME) docker image for $(LOCAL_ARCH)..." @docker build -t $(OPERATOR_IMAGE_NAME)-$(LOCAL_ARCH):$(VERSION) \ --build-arg VCS_REF=$(VCS_REF) --build-arg VCS_URL=$(VCS_URL) \ diff --git a/OWNERS b/OWNERS index dc89fb098..84a5dfc3d 100644 --- a/OWNERS +++ b/OWNERS @@ -4,9 +4,13 @@ approvers: - qpdpQ - bluzarraga - YCShen1010 +- pgodowski +- Jeremy-Cheng-stack reviewers: - bitscuit - Daniel-Fan - qpdpQ - bluzarraga - YCShen1010 +- pgodowski +- Jeremy-Cheng-stack diff --git a/README.md b/README.md index 8e08ba0b5..d86630ef2 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,8 @@ The `ibm-common-service-operator` is a bridge to connect IBM Cloud Paks and Oper When you install this operator, the operator completes the following tasks: -- Installs ODLM in all namespaces mode -- Creates the `ibm-common-services` namespace -- Creates the Common Services `OperandRegistry` and `OperandConfig` in the `ibm-common-services` namespace +- Installs ODLM operator namespace +- Creates the Common Services `OperandRegistry` and `OperandConfig` in the service namespace For more information about installing this operator and other Common Services operators, see [Installer documentation](http://ibm.biz/cpcs_opinstall). If you are using this operator as part of an IBM Cloud Pak, see the documentation for that IBM Cloud Pak to learn more about how to install and use the operator service. For more information about IBM Cloud Paks, see [IBM Cloud Paks that use Common Services](http://ibm.biz/cpcs_cloudpaks). @@ -21,7 +20,7 @@ Red Hat OpenShift Container Platform 4.3 or newer installed on one of the follow ## Operator versions - - 4.3.1 + - 4.11.0 ## Prerequisites diff --git a/api/v3/commonservice_types.go b/api/v3/commonservice_types.go index 545786b02..5986823e0 100644 --- a/api/v3/commonservice_types.go +++ b/api/v3/commonservice_types.go @@ -17,35 +17,49 @@ package v3 import ( + "time" + olmv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - "github.com/IBM/ibm-common-service-operator/controllers/constant" + "github.com/IBM/ibm-common-service-operator/v4/controllers/constant" ) // EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! // NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. type CSData struct { - Channel string - Version string - CPFSNs string - ServicesNs string - OperatorNs string - CatalogSourceName string - CatalogSourceNs string - IsolatedModeEnable string - ApprovalMode string - OnPremMultiEnable string - ZenOperatorImage string - WatchNamespaces string + Channel string + Version string + CPFSNs string + ServicesNs string + OperatorNs string + CatalogSourceName string + CatalogSourceNs string + IsolatedModeEnable string + ApprovalMode string + OnPremMultiEnable string + WatchNamespaces string + CloudPakThemes string + CloudPakThemesVersion string + ExcludedCatalog string + StatusMonitoredServices string +} + +// +kubebuilder:pruning:PreserveUnknownFields +type ExtensionWithMarker struct { + runtime.RawExtension `json:",inline"` } +// +kubebuilder:pruning:PreserveUnknownFields type ServiceConfig struct { - Name string `json:"name"` - Spec map[string]runtime.RawExtension `json:"spec"` - ManagementStrategy string `json:"managementStrategy,omitempty"` + Name string `json:"name"` + // +optional + Spec map[string]ExtensionWithMarker `json:"spec"` + ManagementStrategy string `json:"managementStrategy,omitempty"` + Resources []ExtensionWithMarker `json:"resources,omitempty"` } // CommonServiceSpec defines the desired state of CommonService @@ -94,14 +108,39 @@ type CommonServiceSpec struct { // DefalutAdminUser is the name of the default admin user for foundational // services IM, default is cpadmin DefaultAdminUser string `json:"defaultAdminUser,omitempty"` - + // Labels describes foundational services will use this + // labels to labels their corresponding resources + Labels map[string]string `json:"labels,omitempty"` + // +optional + // HugePages describes the hugepages settings for foundational services + // +kubebuilder:pruning:PreserveUnknownFields + HugePages *HugePages `json:"hugepages,omitempty"` + // OperatorConfigs is a list of configurations to be applied to operators via CSV updates + // +kubebuilder:pruning:PreserveUnknownFields + OperatorConfigs []OperatorConfig `json:"operatorConfigs,omitempty"` // +optional License LicenseList `json:"license"` + // +optional + EnableInstanaMetricCollection bool `json:"enableInstanaMetricCollection,omitempty"` +} + +// OperatorConfig is configuration composed of key-value pairs to be injected into specified CSVs +type OperatorConfig struct { + // Name is the name of the operator as requested in an OperandRequest + Name string `json:"name,omitempty"` + // Number of desired pods. This is a pointer to distinguish between explicit + // 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 type LicenseList struct { - // Accepting the license - URL: https://ibm.biz/integration-licenses + // Accepting the license - URL: https://ibm.biz/icpfs39license // +operator-sdk:gen-csv:customresourcedefinitions.specDescriptors.x-descriptors="urn:alm:descriptor:com.tectonic.ui:hidden" // +optional Accept bool `json:"accept"` @@ -188,6 +227,14 @@ type ConfigStatus struct { TopologyConfigurableCRs []ConfigurableCR `json:"topologyConfigurableCRs,omitempty"` } +// HugePages defines the various hugepages settings applied to foundational services +type HugePages struct { + // HugePagesEnabled enables hugepages settings for foundational services + Enable bool `json:"enable,omitempty"` + // HugePagesSizes describes the size of the hugepages + HugePagesSizes map[string]string `json:"-"` +} + // CommonServiceStatus defines the observed state of CommonService type CommonServiceStatus struct { // Phase describes the phase of the overall installation @@ -196,10 +243,69 @@ type CommonServiceStatus struct { // OverallStatus describes whether the Installation for the foundational services has succeeded or not OverallStatus string `json:"overallStatus,omitempty"` ConfigStatus ConfigStatus `json:"configStatus,omitempty"` + // Conditions represents the current state of CommonService + // +optional + // +operator-sdk:csv:customresourcedefinitions:type=status,displayName="Conditions",xDescriptors="urn:alm:descriptor:io.kubernetes.conditions" + Conditions []CommonServiceCondition `json:"conditions,omitempty"` } +// CommonServiceCondition defines the observed condition of CommonService +type CommonServiceCondition struct { + // Type of condition. + // +optional + Type ConditionType `json:"type"` + // Status of the condition, one of True, False, Unknown. + // +optional + Status corev1.ConditionStatus `json:"status"` + // The last time this condition was updated. + // +optional + LastUpdateTime string `json:"lastUpdateTime,omitempty"` + // Last time the condition transitioned from one status to another. + // +optional + LastTransitionTime string `json:"lastTransitionTime,omitempty"` + // The reason for the condition's last transition. + // +optional + Reason string `json:"reason,omitempty"` + // A human readable message indicating details about the transition. + // +optional + Message string `json:"message,omitempty"` +} + +// ConditionType is the condition of a service. +type ConditionType string + +// ResourceType is the type of condition use. +type ResourceType string + +const ( + ConditionTypeBlocked ConditionType = "Blocked" + ConditionTypeReady ConditionType = "Ready" + ConditionTypeWarning ConditionType = "Warning" + ConditionTypeError ConditionType = "Error" + ConditionTypePending ConditionType = "Pending" + ConditionTypeReconciling ConditionType = "Reconciling" +) + +const ( + ConditionReasonReconcile = "StartReconciling" + ConditionReasonInit = "UpdatingResources" + ConditionReasonConfig = "Configuring" + ConditionReasonWarning = "WarningOccurred" + ConditionReasonError = "ReconcileError" + ConditionReasonReady = "ReconcileSucceeded" +) + +const ( + ConditionMessageReconcile = "reconciling CommonService CR." + ConditionMessageInit = "initializing/updating: waiting for OperandRegistry and OperandConfig to become ready." + ConditionMessageConfig = "configuring CommonService CR." + ConditionMessageMissSC = "warning: StorageClass is not configured in CommonService CR, if KeyCloak or IBM IM service will be deployed, please configure StorageClass in the CS CR. Refer to the documentation for more information: https://www.ibm.com/docs/en/cloud-paks/foundational-services/4.6?topic=options-configuring-foundational-services#storage-class" + ConditionMessageReady = "CommonService CR is ready." +) + // +kubebuilder:object:root=true // +kubebuilder:subresource:status +// +kubebuilder:metadata:labels="foundationservices.cloudpak.ibm.com=crd" // +operator-sdk:gen-csv:customresourcedefinitions.displayName="CommonService" // CommonService is the Schema for the commonservices API. This API is used to @@ -220,7 +326,6 @@ type CommonService struct { } // +kubebuilder:object:root=true - // CommonServiceList contains a list of CommonService type CommonServiceList struct { metav1.TypeMeta `json:",inline"` @@ -273,6 +378,75 @@ func (r *CommonService) UpdateNonMasterConfigStatus(CSData *CSData) { r.UpdateTopologyCR(CSData) } +// SetPendingCondition sets a condition to claim Pending. +func (r *CommonService) SetPendingCondition(name string, ct ConditionType, cs corev1.ConditionStatus, reason, message string) { + c := newCondition(ct, cs, reason, message) + r.setCondition(*c) +} + +// SetReadyCondition creates a Condition to claim Ready. +func (r *CommonService) SetReadyCondition(name string, ct ConditionType, cs corev1.ConditionStatus) { + r.UpdateConditionList(corev1.ConditionFalse) + c := newCondition(ConditionTypeReady, cs, ConditionReasonReady, ConditionMessageReady) + r.setCondition(*c) +} + +// SetWarningCondition creates a Condition to claim Warning. +func (r *CommonService) SetWarningCondition(name string, ct ConditionType, cs corev1.ConditionStatus, reason, message string) { + c := newCondition(ct, cs, reason, message) + r.setCondition(*c) +} + +// SetErrorCondition creates a Condition to claim Error. +func (r *CommonService) SetErrorCondition(name string, ct ConditionType, cs corev1.ConditionStatus, reason, message string) { + r.UpdateConditionList(corev1.ConditionFalse) + c := newCondition(ct, cs, reason, message) + r.setCondition(*c) +} + +// UpdateConditionList updates the condition list of the CommonService CR +func (r *CommonService) UpdateConditionList(ct corev1.ConditionStatus) { + // check all the conditions + for i := range r.Status.Conditions { + if r.Status.Conditions[i].Type == ConditionTypePending || r.Status.Conditions[i].Type == ConditionTypeReconciling { + r.Status.Conditions[i].Status = ct + } + } +} + +// NewCondition Returns a new condition with the given values for CommonService +func newCondition(condType ConditionType, status corev1.ConditionStatus, reason, message string) *CommonServiceCondition { + now := time.Now().Format(time.RFC3339) + return &CommonServiceCondition{ + Type: condType, + Status: status, + LastUpdateTime: now, + LastTransitionTime: now, + Reason: reason, + Message: message, + } +} + +// GetCondition returns the condition status by given condition type and message +func getCondition(conds *[]CommonServiceCondition, condtype ConditionType, msg string) (int, *CommonServiceCondition) { + for i, condition := range *conds { + if condtype == condition.Type && msg == condition.Message { + return i, &condition + } + } + return -1, nil +} + +// SetCondition append a new condition status +func (r *CommonService) setCondition(condition CommonServiceCondition) { + position, cp := getCondition(&r.Status.Conditions, condition.Type, condition.Message) + if cp != nil { + r.Status.Conditions[position] = condition + } else { + r.Status.Conditions = append(r.Status.Conditions, condition) + } +} + func (r *CommonService) UpdateTopologyCR(CSData *CSData) { var masterCRSlice []ConfigurableCR var csCR ConfigurableCR diff --git a/api/v3/finalizer.go b/api/v3/finalizer.go new file mode 100644 index 000000000..783d2ddb8 --- /dev/null +++ b/api/v3/finalizer.go @@ -0,0 +1,37 @@ +// +// Copyright 2022 IBM Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package v3 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// RemoveFinalizer removes the finalizer from the object's ObjectMeta. +func RemoveFinalizer(objectMeta *metav1.ObjectMeta, deletingFinalizer string) bool { + outFinalizers := make([]string, 0) + var changed bool + for _, finalizer := range objectMeta.Finalizers { + if finalizer == deletingFinalizer { + changed = true + continue + } + outFinalizers = append(outFinalizers, finalizer) + } + + objectMeta.Finalizers = outFinalizers + return changed +} diff --git a/api/v3/zz_generated.deepcopy.go b/api/v3/zz_generated.deepcopy.go index 70148e8b5..559f03635 100644 --- a/api/v3/zz_generated.deepcopy.go +++ b/api/v3/zz_generated.deepcopy.go @@ -1,5 +1,4 @@ //go:build !ignore_autogenerated -// +build !ignore_autogenerated // // Copyright 2022 IBM Corporation @@ -112,6 +111,21 @@ func (in *CommonService) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CommonServiceCondition) DeepCopyInto(out *CommonServiceCondition) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CommonServiceCondition. +func (in *CommonServiceCondition) DeepCopy() *CommonServiceCondition { + if in == nil { + return nil + } + out := new(CommonServiceCondition) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CommonServiceList) DeepCopyInto(out *CommonServiceList) { *out = *in @@ -159,6 +173,25 @@ func (in *CommonServiceSpec) DeepCopyInto(out *CommonServiceSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.Labels != nil { + in, out := &in.Labels, &out.Labels + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.HugePages != nil { + in, out := &in.HugePages, &out.HugePages + *out = new(HugePages) + (*in).DeepCopyInto(*out) + } + if in.OperatorConfigs != nil { + in, out := &in.OperatorConfigs, &out.OperatorConfigs + *out = make([]OperatorConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } out.License = in.License } @@ -181,6 +214,11 @@ func (in *CommonServiceStatus) DeepCopyInto(out *CommonServiceStatus) { copy(*out, *in) } in.ConfigStatus.DeepCopyInto(&out.ConfigStatus) + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]CommonServiceCondition, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CommonServiceStatus. @@ -228,6 +266,22 @@ func (in *ConfigurableCR) DeepCopy() *ConfigurableCR { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExtensionWithMarker) DeepCopyInto(out *ExtensionWithMarker) { + *out = *in + in.RawExtension.DeepCopyInto(&out.RawExtension) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtensionWithMarker. +func (in *ExtensionWithMarker) DeepCopy() *ExtensionWithMarker { + if in == nil { + return nil + } + out := new(ExtensionWithMarker) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Features) DeepCopyInto(out *Features) { *out = *in @@ -253,6 +307,28 @@ func (in *Features) DeepCopy() *Features { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HugePages) DeepCopyInto(out *HugePages) { + *out = *in + if in.HugePagesSizes != nil { + in, out := &in.HugePagesSizes, &out.HugePagesSizes + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HugePages. +func (in *HugePages) DeepCopy() *HugePages { + if in == nil { + return nil + } + out := new(HugePages) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *LicenseList) DeepCopyInto(out *LicenseList) { *out = *in @@ -268,16 +344,43 @@ func (in *LicenseList) DeepCopy() *LicenseList { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OperatorConfig) DeepCopyInto(out *OperatorConfig) { + *out = *in + if in.Replicas != nil { + in, out := &in.Replicas, &out.Replicas + *out = new(int32) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OperatorConfig. +func (in *OperatorConfig) DeepCopy() *OperatorConfig { + if in == nil { + return nil + } + out := new(OperatorConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ServiceConfig) DeepCopyInto(out *ServiceConfig) { *out = *in if in.Spec != nil { in, out := &in.Spec, &out.Spec - *out = make(map[string]runtime.RawExtension, len(*in)) + *out = make(map[string]ExtensionWithMarker, len(*in)) for key, val := range *in { (*out)[key] = *val.DeepCopy() } } + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = make([]ExtensionWithMarker, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceConfig. diff --git a/base_images.json b/base_images.json index 66871f9f8..ec22d1caf 100644 --- a/base_images.json +++ b/base_images.json @@ -2,23 +2,23 @@ { "imageType": "external", "sourceRepo": "registry.access.redhat.com", - "sourceNamespace": "ubi8", - "sourceImage": "ubi", + "sourceNamespace": "ubi9", + "sourceImage": "ubi-minimal", "destStage": "edge", "destNamespace": "build-images", - "destImage": "ubi8", - "tag": "8.8-1067.1696517599", + "destImage": "ubi9-minimal", + "tag": "9.5-1738643652", "updatePackages": [] }, { "imageType": "external", "sourceRepo": "registry.access.redhat.com", - "sourceNamespace": "ubi8", - "sourceImage": "ubi-minimal", + "sourceNamespace": "ubi9", + "sourceImage": "ubi", "destStage": "edge", "destNamespace": "build-images", - "destImage": "ubi8-minimal", - "tag": "8.8-1072.1696517598", + "destImage": "ubi9", + "tag": "9.5-1738643550", "updatePackages": [] }, { @@ -29,32 +29,21 @@ "destStage": "edge", "destNamespace": "build-images", "destImage": "ubi9-micro", - "tag": "9.2-15.1696515526", - "updatePackages": [] - }, - { - "imageType": "external", - "sourceRepo": "quay.io", - "sourceNamespace": "operator-framework", - "sourceImage": "helm-operator", - "destStage": "edge", - "destNamespace": "build-images", - "destImage": "helm-operator", - "tag": "v1.32.0", + "tag": "9.5-1738659858", "updatePackages": [] }, { "imageType": "node", - "sourceImage": "ubi8-minimal", - "sourceTag": "8.8-1072.1696517598", - "destImage": "node-v18-ubi8-minimal", - "nodeVersion": "18.18.1" + "sourceImage": "ubi9-minimal", + "sourceTag": "9.5-1738643652", + "destImage": "node-v20-ubi9-minimal", + "nodeVersion": "20.18.2" }, { - "imageType": "liberty", - "sourceImage": "node-v18-ubi8-minimal", - "sourceTag": "18.18.1_8.8-1072.1696517598", - "destImage": "liberty11-ubi8-minimal", - "libertyVersion": "23.0.0.9" + "imageType": "node", + "sourceImage": "ubi9-minimal", + "sourceTag": "9.5-1738643652", + "destImage": "node-v22-ubi9-minimal", + "nodeVersion": "22.13.1" } ] diff --git a/bundle.Dockerfile b/bundle.Dockerfile index 89fca94cd..a4b5aca99 100644 --- a/bundle.Dockerfile +++ b/bundle.Dockerfile @@ -5,8 +5,8 @@ LABEL operators.operatorframework.io.bundle.mediatype.v1=registry+v1 LABEL operators.operatorframework.io.bundle.manifests.v1=manifests/ LABEL operators.operatorframework.io.bundle.metadata.v1=metadata/ LABEL operators.operatorframework.io.bundle.package.v1=ibm-common-service-operator -LABEL operators.operatorframework.io.bundle.channels.v1=v4.3 -LABEL operators.operatorframework.io.bundle.channel.default.v1=v4.3 +LABEL operators.operatorframework.io.bundle.channels.v1=v4.11 +LABEL operators.operatorframework.io.bundle.channel.default.v1=v4.11 LABEL operators.operatorframework.io.metrics.builder=operator-sdk-v1.31.0 LABEL operators.operatorframework.io.metrics.mediatype.v1=metrics+v1 LABEL operators.operatorframework.io.metrics.project_layout=go.kubebuilder.io/v3 diff --git a/bundle/manifests/ibm-common-service-operator.clusterserviceversion.yaml b/bundle/manifests/ibm-common-service-operator.clusterserviceversion.yaml index 9b77770a5..d7cbc85a2 100644 --- a/bundle/manifests/ibm-common-service-operator.clusterserviceversion.yaml +++ b/bundle/manifests/ibm-common-service-operator.clusterserviceversion.yaml @@ -21,25 +21,33 @@ metadata: } ] capabilities: Seamless Upgrades + cloudPakThemesVersion: styles4100.css containerImage: icr.io/cpopen/common-service-operator:latest - createdAt: "2023-09-20T20:40:14Z" - description: The IBM Common Service Operator is used to deploy IBM Common Services + createdAt: "2024-10-31T05:22:07Z" + 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: "" - olm.skipRange: ">=3.3.0 <4.3.1" - operatorChannel: v4.3 - operatorVersion: 4.3.1 + olm.skipRange: ">=3.3.0 <4.11.0" + operatorChannel: v4.11 + operatorVersion: 4.11.0 operators.openshift.io/infrastructure-features: '["disconnected"]' operators.operatorframework.io/builder: operator-sdk-v1.31.0 operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 repository: https://github.com/IBM/ibm-common-service-operator + features.operators.openshift.io/disconnected: "true" + features.operators.openshift.io/fips-compliant: "true" + features.operators.openshift.io/proxy-aware: "false" + features.operators.openshift.io/tls-profiles: "false" + features.operators.openshift.io/token-auth-aws: "false" + features.operators.openshift.io/token-auth-azure: "false" + features.operators.openshift.io/token-auth-gcp: "false" support: IBM labels: operatorframework.io/arch.amd64: supported operatorframework.io/arch.ppc64le: supported operatorframework.io/arch.s390x: supported operatorframework.io/os.linux: supported - name: ibm-common-service-operator.v4.3.1 + name: ibm-common-service-operator.v4.11.0 namespace: placeholder spec: apiservicedefinitions: {} @@ -50,14 +58,29 @@ spec: kind: CommonService name: commonservices.operator.ibm.com specDescriptors: - - description: 'Accepting the license - URL: https://ibm.biz/integration-licenses' + - description: License information for this instance. You must accept the license. + displayName: License + path: license + - description: Read and accept the license that is applicable to your installation. For more information, see https://ibm.biz/icpfs39license displayName: Accept path: license.accept value: - false x-descriptors: - urn:alm:descriptor:com.tectonic.ui:checkbox - - description: The size of deployment profile for IBM Cloud Pak foundational services + - path: license.license + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:hidden + - path: license.use + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:hidden + - path: license.key + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:hidden + - path: license.use + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:hidden + - description: The size of deployment profile for IBM Cloud Pak foundational services. displayName: Size path: size x-descriptors: @@ -67,6 +90,29 @@ spec: - urn:alm:descriptor:com.tectonic.ui:select:medium - urn:alm:descriptor:com.tectonic.ui:select:large - urn:alm:descriptor:com.tectonic.ui:select:production + - displayName: Operator namespace + path: operatorNamespace + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Namespace + - displayName: Services namespace + path: servicesNamespace + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Namespace + - displayName: Storage class + path: storageClass + x-descriptors: + - urn:alm:descriptor:io.kubernetes:StorageClass + - urn:alm:descriptor:com.tectonic.ui:advanced + - displayName: FIPS mode + path: fipsEnabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - urn:alm:descriptor:com.tectonic.ui:advanced + - displayName: HugePages Setting + path: hugePages.enable + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - urn:alm:descriptor:com.tectonic.ui:advanced - description: The profile controller for IBM Cloud Pak foundational services displayName: ProfileController path: profileController @@ -75,6 +121,44 @@ spec: - urn:alm:descriptor:com.tectonic.ui:select:commonservice - urn:alm:descriptor:com.tectonic.ui:select:turbonomic - urn:alm:descriptor:com.tectonic.ui:select:vpa + - urn:alm:descriptor:com.tectonic.ui:advanced + - displayName: Identity management custom hostname + path: routeHost + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:advanced + - displayName: Identity management custom certificates + path: BYOCACertificate + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - urn:alm:descriptor:com.tectonic.ui:advanced + - displayName: Identity management default admin username + path: defaultAdminUser + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:advanced + - displayName: Custom OLM catalog name + path: catalogName + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:advanced + - displayName: Custom OLM catalog namespace + path: catalogNamespace + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Namespace + - urn:alm:descriptor:com.tectonic.ui:advanced + - displayName: OLM Install Plan approval mode + path: installPlanApproval + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:select:Automatic + - urn:alm:descriptor:com.tectonic.ui:select:Manual + - urn:alm:descriptor:com.tectonic.ui:advanced + - path: manualManagement + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:hidden + - path: features + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:hidden + - path: services + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:hidden statusDescriptors: - description: Installed Bedrock Operator Name displayName: Name @@ -105,9 +189,8 @@ spec: When you install this operator, the operator completes the following tasks: - - Installs ODLM in all namespaces mode - - Creates the `ibm-common-services` namespace - - Creates the Common Services `OperandRegistry` and `OperandConfig` in the `ibm-common-services` namespace + - Installs ODLM operator namespace + - Creates the Common Services `OperandRegistry` and `OperandConfig` in the service namespace # Details For more information about installing this operator and other Common Services operators, see [Installer documentation](http://ibm.biz/cpcs_opinstall). If you are using this operator as part of an IBM Cloud Pak, see the documentation for that IBM Cloud Pak to learn more about how to install and use the operator service. For more information about IBM Cloud Paks, see [IBM Cloud Paks that use Common Services](http://ibm.biz/cpcs_cloudpaks). @@ -124,7 +207,7 @@ spec: ## Operator versions - - 4.3.1 + - 4.11.0 ## Prerequisites @@ -182,6 +265,14 @@ spec: verbs: - delete - update + - apiGroups: + - "" + resourceNames: + - cloud-native-postgresql-image-list + resources: + - configmaps + verbs: + - delete - apiGroups: - "" resources: @@ -191,6 +282,7 @@ spec: - get - list - watch + - update - apiGroups: - "" resources: @@ -224,6 +316,19 @@ spec: - infrastructures verbs: - get + - apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + - clusterroles + verbs: + - create + - delete + - get + - list + - patch + - update + - watch serviceAccountName: ibm-common-service-operator deployments: - label: @@ -249,8 +354,8 @@ spec: app.kubernetes.io/instance: ibm-common-service-operator app.kubernetes.io/managed-by: ibm-common-service-operator app.kubernetes.io/name: ibm-common-service-operator - productName: IBM_Cloud_Platform_Common_Services name: ibm-common-service-operator + productName: IBM_Cloud_Platform_Common_Services spec: affinity: nodeAffinity: @@ -278,12 +383,6 @@ spec: fieldPath: metadata.annotations['olm.targetNamespaces'] - name: OPERATOR_NAME value: ibm-common-service-operator - - name: IBM_CS_WEBHOOK_IMAGE - value: icr.io/cpopen/cpfs/ibm-cs-webhook:1.18.0 - - name: IBM_SECRETSHARE_OPERATOR_IMAGE - value: icr.io/cpopen/cpfs/ibm-secretshare-operator:1.19.0 - - name: IBM_ZEN_OPERATOR_IMAGE - value: icr.io/cpopen/ibm-zen-operator:1.7.0 image: icr.io/cpopen/common-service-operator:latest imagePullPolicy: IfNotPresent livenessProbe: @@ -323,6 +422,8 @@ spec: privileged: false readOnlyRootFilesystem: true runAsNonRoot: true + seccompProfile: + type: RuntimeDefault volumeMounts: - mountPath: /tmp/k8s-webhook-server/serving-certs name: cert @@ -336,6 +437,24 @@ spec: secretName: webhook-server-cert permissions: - rules: + - apiGroups: + - "" + resources: + - configmaps + verbs: + - delete + - patch + - apiGroups: + - operator.ibm.com + resources: + - namespacescopes + verbs: + - create + - delete + - get + - list + - watch + - patch - apiGroups: - cert-manager.io resources: @@ -354,6 +473,7 @@ spec: - statefulsets - daemonsets verbs: + - delete - get - list - patch @@ -367,6 +487,7 @@ spec: - commonservices/status - operandconfigs - operandregistries + - operatorconfigs verbs: - create - delete @@ -454,6 +575,51 @@ spec: - elasticstacks verbs: - delete + - apiGroups: + - "" + resources: + - serviceaccounts + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - rbac.authorization.k8s.io + resources: + - rolebindings + - roles + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - operator.ibm.com + resources: + - podpresets + verbs: + - get + - delete + - list + - apiGroups: + - ibmcpcs.ibm.com + resources: + - secretshares + verbs: + - create + - delete + - get + - list + - patch + - update + - watch serviceAccountName: ibm-common-service-operator strategy: deployment installModes: @@ -476,13 +642,9 @@ spec: name: IBM Support maturity: alpha minKubeVersion: 1.19.0 - nativeAPIs: - - group: cert-manager.io - kind: Certificate - version: v1 provider: name: IBM - version: 4.3.1 + version: 4.11.0 webhookdefinitions: - admissionReviewVersions: - v1 @@ -525,7 +687,5 @@ spec: type: ValidatingAdmissionWebhook webhookPath: /validate-operator-ibm-com-v3-commonservice relatedImages: - - image: icr.io/cpopen/common-service-operator:4.3.1 + - image: icr.io/cpopen/common-service-operator:4.11.0 name: COMMON_SERVICE_OPERATOR_IMAGE - - image: icr.io/cpopen/cpfs/cpfs-utils:latest - name: CPFS_UTILS_IMAGE diff --git a/bundle/manifests/operator.ibm.com_commonservices.yaml b/bundle/manifests/operator.ibm.com_commonservices.yaml index 426b781f9..cddf9fe13 100644 --- a/bundle/manifests/operator.ibm.com_commonservices.yaml +++ b/bundle/manifests/operator.ibm.com_commonservices.yaml @@ -2,12 +2,13 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.6.1 + controller-gen.kubebuilder.io/version: v0.14.0 creationTimestamp: null labels: app.kubernetes.io/instance: ibm-common-service-operator app.kubernetes.io/managed-by: ibm-common-service-operator app.kubernetes.io/name: ibm-common-service-operator + foundationservices.cloudpak.ibm.com: crd name: commonservices.operator.ibm.com spec: group: operator.ibm.com @@ -21,23 +22,29 @@ spec: - name: v3 schema: openAPIV3Schema: - description: CommonService is the Schema for the commonservices API. This - API is used to configure general foundational services configurations, such - as sizing, catalogsource, etc. See description of fields for more details. - An instance of this CRD is automatically created by the ibm-common-service-operator - upon installation to trigger the installation of critical installer components + description: |- + CommonService is the Schema for the commonservices API. This API is used to + configure general foundational services configurations, such as sizing, + catalogsource, etc. See description of fields for more details. An instance + of this CRD is automatically created by the ibm-common-service-operator upon + installation to trigger the installation of critical installer components such as operand-deployment-lifecycle-manager (ODLM), which is required to further install other services from foundational services, such as IM. properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -45,21 +52,27 @@ spec: description: CommonServiceSpec defines the desired state of CommonService properties: BYOCACertificate: - description: BYOCACertificate enables the option to replace the cs-ca-certificate - with your own CA certificate + description: |- + BYOCACertificate enables the option to replace the cs-ca-certificate with + your own CA certificate type: boolean catalogName: - description: CatalogName is the name of the CatalogSource that will - be used for ODLM and other services in foundational services + description: |- + CatalogName is the name of the CatalogSource that will be used for ODLM + and other services in foundational services type: string catalogNamespace: - description: CatalogNamespace is the namespace of the CatalogSource - that will be used for ODLM and other services in foundational services + description: |- + CatalogNamespace is the namespace of the CatalogSource that will be used + for ODLM and other services in foundational services type: string defaultAdminUser: - description: DefalutAdminUser is the name of the default admin user - for foundational services IM, default is cpadmin + description: |- + DefalutAdminUser is the name of the default admin user for foundational + services IM, default is cpadmin type: string + enableInstanaMetricCollection: + type: boolean features: description: Features defines the configurations of Cloud Pak Services properties: @@ -81,15 +94,33 @@ spec: fipsEnabled: description: FipsEnabled enables FIPS mode for foundational services type: boolean + hugepages: + description: HugePages describes the hugepages settings for foundational + services + properties: + enable: + description: HugePagesEnabled enables hugepages settings for foundational + services + type: boolean + type: object + x-kubernetes-preserve-unknown-fields: true installPlanApproval: - description: 'InstallPlanApproval sets the approval mode for ODLM - and other foundational services: Manual or Automatic' + description: |- + InstallPlanApproval sets the approval mode for ODLM and other + foundational services: Manual or Automatic type: string + labels: + additionalProperties: + type: string + description: |- + Labels describes foundational services will use this + labels to labels their corresponding resources + type: object license: description: LicenseList defines the license specification in CSV properties: accept: - description: 'Accepting the license - URL: https://ibm.biz/integration-licenses' + description: 'Accepting the license - URL: https://ibm.biz/icpfs39license' type: boolean key: description: The license key for this deployment. @@ -104,51 +135,90 @@ spec: type: object manualManagement: type: boolean + operatorConfigs: + description: OperatorConfigs is a list of configurations to be applied + to operators via CSV updates + items: + description: OperatorConfig is configuration composed of key-value + pairs to be injected into specified CSVs + properties: + name: + description: Name is the name of the operator as requested in + an OperandRequest + type: string + replicas: + description: |- + Number of desired pods. This is a pointer to distinguish between explicit + 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 operatorNamespace: - description: OperatorNamespace describes the namespace where operators - will be installed in such as ODLM. This will also apply to all services - in foundational services, e.g. ODLM will install IM operator in - this namespace + description: |- + OperatorNamespace describes the namespace where operators will be + installed in such as ODLM. This will also apply to all services in + foundational services, e.g. ODLM will install IM operator in this + namespace type: string profileController: - description: ProfileController enables turbonomic to automatically - handle sizing of foundational services. Default value is 'default' + description: |- + ProfileController enables turbonomic to automatically handle sizing of + foundational services. Default value is 'default' type: string routeHost: - description: RouteHost describes the hostname for the foundational - services route, and can only be configured pre-installation of IM + description: |- + RouteHost describes the hostname for the foundational services route, + and can only be configured pre-installation of IM type: string services: - description: Services describes the CPU, memory, and replica configuration - for individual services in foundational services + description: |- + Services describes the CPU, memory, and replica configuration for + individual services in foundational services items: properties: managementStrategy: type: string name: type: string + resources: + items: + type: object + x-kubernetes-preserve-unknown-fields: true + type: array spec: additionalProperties: + type: object x-kubernetes-preserve-unknown-fields: true type: object required: - name - - spec type: object + x-kubernetes-preserve-unknown-fields: true type: array servicesNamespace: - description: ServicesNamespace describes the namespace where operands - will be created in such as OperandRegistry and OperandConfig. This - will also apply to all services in foundational services, e.g. IM - will create operands in this namespace + description: |- + ServicesNamespace describes the namespace where operands will be created + in such as OperandRegistry and OperandConfig. This will also apply to all + services in foundational services, e.g. IM will create operands in this + namespace type: string size: - description: 'Size describes the T-shirt size of foundational services: - starterset, small, medium, or large' + description: |- + Size describes the T-shirt size of foundational services: starterset, + small, medium, or large type: string storageClass: - description: StorageClass describes the storage class to use for the - foundational services PVCs + description: |- + StorageClass describes the storage class to use for the foundational + services PVCs type: string type: object x-kubernetes-preserve-unknown-fields: true @@ -174,6 +244,34 @@ spec: type: string type: object type: array + conditions: + description: Conditions represents the current state of CommonService + items: + description: CommonServiceCondition defines the observed condition + of CommonService + properties: + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + type: string + lastUpdateTime: + description: The last time this condition was updated. + type: string + message: + description: A human readable message indicating details about + the transition. + type: string + reason: + description: The reason for the condition's last transition. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type of condition. + type: string + type: object + type: array configStatus: description: ConfigStatus describes various configuration currently applied onto the foundational services installer. @@ -186,26 +284,30 @@ spec: description: CatalogNamespace is the namesapce of the CatalogSource type: string configurable: - description: Configurable indicates whether this CommonService - CR is the one that can be used to configure the foundational - services' installer. Other CommonService CRs configurations - will not take effect, except for sizing + description: |- + Configurable indicates whether this CommonService CR is the one + that can be used to configure the foundational services' installer. Other + CommonService CRs configurations will not take effect, except for sizing type: boolean operatorDeployed: - description: OperatorDeployed indicates whether the OperandRegistry - has been created or not. + description: |- + OperatorDeployed indicates whether the OperandRegistry has been created + or not. type: boolean operatorNamespace: - description: OperatorNamespace is the namespace of where the foundational - services' operators will be installed in. + description: |- + OperatorNamespace is the namespace of where the foundational services' + operators will be installed in. type: string servicesDeployed: - description: ServicesDeployed indicates whether the OperandConfig - has been created or not. + description: |- + ServicesDeployed indicates whether the OperandConfig has been created or + not. type: boolean servicesNamespace: - description: ServicesNamespace is the namespace where the foundational - services' operands will be created in. + description: |- + ServicesNamespace is the namespace where the foundational services' + operands will be created in. type: string topologyConfigurableCRs: description: TopologyConfigurableCRs describes the configurable @@ -249,5 +351,5 @@ status: acceptedNames: kind: "" plural: "" - conditions: [] - storedVersions: [] + conditions: null + storedVersions: null diff --git a/bundle/metadata/annotations.yaml b/bundle/metadata/annotations.yaml index 76aaf20a4..aacbe0abd 100644 --- a/bundle/metadata/annotations.yaml +++ b/bundle/metadata/annotations.yaml @@ -4,8 +4,8 @@ annotations: operators.operatorframework.io.bundle.manifests.v1: manifests/ operators.operatorframework.io.bundle.metadata.v1: metadata/ operators.operatorframework.io.bundle.package.v1: ibm-common-service-operator - operators.operatorframework.io.bundle.channels.v1: v4.3 - operators.operatorframework.io.bundle.channel.default.v1: v4.3 + operators.operatorframework.io.bundle.channels.v1: v4.11 + operators.operatorframework.io.bundle.channel.default.v1: v4.11 operators.operatorframework.io.metrics.builder: operator-sdk-v1.31.0 operators.operatorframework.io.metrics.mediatype.v1: metrics+v1 operators.operatorframework.io.metrics.project_layout: go.kubebuilder.io/v3 diff --git a/common/Makefile.common.mk b/common/Makefile.common.mk index 9d1fa4059..f393f308c 100644 --- a/common/Makefile.common.mk +++ b/common/Makefile.common.mk @@ -49,6 +49,7 @@ lint-copyright-banner: ${XARGS} common/scripts/lint_copyright_banner.sh lint-go: + golangci-lint version @${FINDFILES} -name '*.go' \( ! \( -name '*.gen.go' -o -name '*.pb.go' \) \) -print0 | ${XARGS} common/scripts/lint_go.sh lint-all: lint-copyright-banner lint-go diff --git a/common/config/.golangci.yml b/common/config/.golangci.yml index 2ecb575e5..7e81cc4de 100644 --- a/common/config/.golangci.yml +++ b/common/config/.golangci.yml @@ -1,6 +1,6 @@ service: # When updating this, also update the version stored in docker/build-tools/Dockerfile in the multicloudlab/tools repo. - golangci-lint-version: 1.51.x # use the fixed version to not introduce new linters unexpectedly + golangci-lint-version: 1.60.x # use the fixed version to not introduce new linters unexpectedly run: # timeout for analysis, e.g. 30s, 5m, default is 1m deadline: 20m @@ -10,43 +10,44 @@ run: # default value is empty list, but next dirs are always skipped independently # from this option's value: # vendor$, third_party$, testdata$, examples$, Godeps$, builtin$ - skip-dirs: - - genfiles$ - - vendor$ + # skip-dirs: + # - genfiles$ + # - vendor$ # which files to skip: they will be analyzed, but issues from them # won't be reported. Default value is empty list, but there is # no need to include all autogenerated files, we confidently recognize # autogenerated files. If it's not please let us know. - skip-files: - - ".*\\.pb\\.go" - - ".*\\.gen\\.go" + # skip-files: + # - ".*\\.pb\\.go" + # - ".*\\.gen\\.go" linters: # please, do not use `enable-all`: it's deprecated and will be removed soon. # inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint disable-all: true enable: - - deadcode + # - deadcode - errcheck # - gocyclo - gofmt - goimports - - golint + # - golint + - revive # - gosec - gosimple - govet # - ineffassign - - interfacer + # - interfacer - lll # - misspell - staticcheck - - structcheck + # - structcheck - typecheck - unconvert - unparam - unused - - varcheck + # - varcheck # don't enable: # - gocritic # - bodyclose @@ -184,6 +185,15 @@ linters-settings: # - unlabelStmt # - unnamedResult # - wrapperFunc + + revive: + rules: + - name: dot-imports + arguments: + - allowedPackages: + - "github.com/onsi/ginkgo" + - "github.com/onsi/ginkgo/v2" + - "github.com/onsi/gomega" issues: # List of regexps of issue texts to exclude, empty list by default. @@ -193,6 +203,14 @@ issues: exclude: - composite literal uses unkeyed fields + exclude-dirs: + - genfiles$ + - vendor$ + + exclude-files: + - ".*\\.pb\\.go" + - ".*\\.gen\\.go" + exclude-rules: # Exclude some linters from running on test files. - path: _test\.go$|^tests/|^samples/ diff --git a/common/scripts/lint-csv.sh b/common/scripts/lint-csv.sh index 0e663c84d..79ab75f7a 100755 --- a/common/scripts/lint-csv.sh +++ b/common/scripts/lint-csv.sh @@ -40,7 +40,7 @@ echo "Lint alm-examples" $YQ eval '.metadata.annotations.alm-examples' $CSV_PATH | $JQ . >/dev/null || STATUS=1 # Lint yamls, only CS Operator needs this part -for section in csV3OperandConfig csV3SaasOperandConfig csV3OperandRegistry csV3SaasOperandRegistry csOperatorSubscription csSecretshareOperator csWebhookOperator csWebhookOperatorEnableOpreqWebhook nsRestrictedSubscription nsSubscription odlmClusterSubscription odlmNamespacedSubscription; do +for section in csV4OperandConfig csV4SaasOperandConfig csV4OperandRegistry csV4SaasOperandRegistry csOperatorSubscription csSecretshareOperator csWebhookOperator csWebhookOperatorEnableOpreqWebhook nsRestrictedSubscription nsSubscription odlmClusterSubscription odlmNamespacedSubscription; do echo "Lint $section" $YQ eval '.metadata.annotations.$section' $CSV_PATH | $YQ - >/dev/null || STATUS=1 done diff --git a/common/scripts/lint_go.sh b/common/scripts/lint_go.sh index 84a708106..1da714957 100755 --- a/common/scripts/lint_go.sh +++ b/common/scripts/lint_go.sh @@ -15,4 +15,4 @@ # limitations under the License. # -GOGC=25 golangci-lint run -c ./common/config/.golangci.yml +GOGC=25 golangci-lint run -c ./common/config/.golangci.yml --timeout=360s diff --git a/common/scripts/multiarch_image.sh b/common/scripts/multiarch_image.sh index 4e57d2eec..37814c8e3 100755 --- a/common/scripts/multiarch_image.sh +++ b/common/scripts/multiarch_image.sh @@ -24,7 +24,7 @@ ALL_PLATFORMS="amd64 ppc64le s390x" IMAGE_REPO=${1} IMAGE_NAME=${2} VERSION=${3-"$(git describe --exact-match 2> /dev/null || git describe --match=$(git rev-parse --short=8 HEAD) --always --dirty --abbrev=8)"} -RELEASE_VERSION=${4:-4.3.1} +RELEASE_VERSION=${4:-4.11.0} MAX_PULLING_RETRY=${MAX_PULLING_RETRY-10} RETRY_INTERVAL=${RETRY_INTERVAL-10} # support other container tools, e.g. podman diff --git a/common/scripts/next-csv.sh b/common/scripts/next-csv.sh index ff0acb130..a516aab3c 100755 --- a/common/scripts/next-csv.sh +++ b/common/scripts/next-csv.sh @@ -26,12 +26,6 @@ PREVIOUS_DEV_CSV=$3 # cs operator channel CURRENT_CHANNEL=$4 NEW_CHANNEL=$5 -# secretshare -CURRENT_SECRETSHARE_CSV=$6 -NEW_SECRETSHARE_CSV=$7 -# webhook -CURRENT_WEBHOOK_CSV=$8 -NEW_WEBHOOK_CSV=$9 if [[ "$OSTYPE" == "linux-gnu"* ]]; then # Linux OS @@ -39,15 +33,11 @@ if [[ "$OSTYPE" == "linux-gnu"* ]]; then sed -i "s/$CURRENT_DEV_CSV/$NEW_DEV_CSV/g" bundle/manifests/ibm-common-service-operator.clusterserviceversion.yaml sed -i "s/$PREVIOUS_DEV_CSV/$CURRENT_DEV_CSV/g" bundle/manifests/ibm-common-service-operator.clusterserviceversion.yaml sed -i "/operatorChannel/s/$CURRENT_CHANNEL/$NEW_CHANNEL/g" bundle/manifests/ibm-common-service-operator.clusterserviceversion.yaml - sed -i "/ibm-secretshare-operator/s/$CURRENT_SECRETSHARE_CSV/$NEW_SECRETSHARE_CSV/g" bundle/manifests/ibm-common-service-operator.clusterserviceversion.yaml - sed -i "/ibm-cs-webhook/s/$CURRENT_WEBHOOK_CSV/$NEW_WEBHOOK_CSV/g" bundle/manifests/ibm-common-service-operator.clusterserviceversion.yaml echo "Updated the bundle/manifests/ibm-common-service-operator.clusterserviceversion.yaml" # Update config/manifests/bases/ibm-common-service-operator.clusterserviceversion.yaml sed -i "s/$CURRENT_DEV_CSV/$NEW_DEV_CSV/g" config/manifests/bases/ibm-common-service-operator.clusterserviceversion.yaml sed -i "/operatorChannel/s/$CURRENT_CHANNEL/$NEW_CHANNEL/g" config/manifests/bases/ibm-common-service-operator.clusterserviceversion.yaml - sed -i "/ibm-secretshare-operator/s/$CURRENT_SECRETSHARE_CSV/$NEW_SECRETSHARE_CSV/g" config/manifests/bases/ibm-common-service-operator.clusterserviceversion.yaml - sed -i "/ibm-cs-webhook/s/$CURRENT_WEBHOOK_CSV/$NEW_WEBHOOK_CSV/g" config/manifests/bases/ibm-common-service-operator.clusterserviceversion.yaml echo "Updated the config/manifests/bases/ibm-common-service-operator.clusterserviceversion.yaml" # Update cs operator version only @@ -57,23 +47,12 @@ if [[ "$OSTYPE" == "linux-gnu"* ]]; then echo "Updated the multiarch_image.sh" sed -i "s/$CURRENT_DEV_CSV/$NEW_DEV_CSV/g" README.md echo "Updated the README.md" - sed -i "s/$CURRENT_DEV_CSV/$NEW_DEV_CSV/g" controllers/constant/secretshare.go - echo "Updated the controllers/constant/secretshare.go" - sed -i "s/$CURRENT_DEV_CSV/$NEW_DEV_CSV/g" controllers/constant/webhook.go - echo "Updated the controllers/constant/webhook.go" - # update cs operator & channel & webhook & secretshare version in deply.yaml + # update cs operator & channel in deply.yaml sed -i "s/$CURRENT_DEV_CSV/$NEW_DEV_CSV/g" testdata/deploy/deploy.yaml sed -i "/operatorChannel/s/$CURRENT_CHANNEL/$NEW_CHANNEL/g" testdata/deploy/deploy.yaml - sed -i "/ibm-secretshare-operator/s/$CURRENT_SECRETSHARE_CSV/$NEW_SECRETSHARE_CSV/g" testdata/deploy/deploy.yaml - sed -i "/ibm-cs-webhook/s/$CURRENT_WEBHOOK_CSV/$NEW_WEBHOOK_CSV/g" testdata/deploy/deploy.yaml echo "Updated the testdata/deploy/deploy.yaml" - # update webhook & secretshare version in manager.yaml - sed -i "/ibm-secretshare-operator/s/$CURRENT_SECRETSHARE_CSV/$NEW_SECRETSHARE_CSV/g" config/manager/manager.yaml - sed -i "/ibm-cs-webhook/s/$CURRENT_WEBHOOK_CSV/$NEW_WEBHOOK_CSV/g" config/manager/manager.yaml - echo "Updated the config/manager/manager.yaml" - # update cs operator channel in Makefile & bundle.Dockerfile & annotations.yaml sed -i "s/$CURRENT_CHANNEL/$NEW_CHANNEL/g" Makefile echo "Updated the Makefile" @@ -90,15 +69,11 @@ elif [[ "$OSTYPE" == "darwin"* ]]; then sed -i "" "s/$CURRENT_DEV_CSV/$NEW_DEV_CSV/g" bundle/manifests/ibm-common-service-operator.clusterserviceversion.yaml sed -i "" "s/$PREVIOUS_DEV_CSV/$CURRENT_DEV_CSV/g" bundle/manifests/ibm-common-service-operator.clusterserviceversion.yaml sed -i "" "/operatorChannel/s/$CURRENT_CHANNEL/$NEW_CHANNEL/g" bundle/manifests/ibm-common-service-operator.clusterserviceversion.yaml - sed -i "" "/ibm-secretshare-operator/s/$CURRENT_SECRETSHARE_CSV/$NEW_SECRETSHARE_CSV/g" bundle/manifests/ibm-common-service-operator.clusterserviceversion.yaml - sed -i "" "/ibm-cs-webhook/s/$CURRENT_WEBHOOK_CSV/$NEW_WEBHOOK_CSV/g" bundle/manifests/ibm-common-service-operator.clusterserviceversion.yaml echo "Updated the bundle/manifests/ibm-common-service-operator.clusterserviceversion.yaml" # Update config/manifests/bases/ibm-common-service-operator.clusterserviceversion.yaml sed -i "" "s/$CURRENT_DEV_CSV/$NEW_DEV_CSV/g" config/manifests/bases/ibm-common-service-operator.clusterserviceversion.yaml sed -i "" "/operatorChannel/s/$CURRENT_CHANNEL/$NEW_CHANNEL/g" config/manifests/bases/ibm-common-service-operator.clusterserviceversion.yaml - sed -i "" "/ibm-secretshare-operator/s/$CURRENT_SECRETSHARE_CSV/$NEW_SECRETSHARE_CSV/g" config/manifests/bases/ibm-common-service-operator.clusterserviceversion.yaml - sed -i "" "/ibm-cs-webhook/s/$CURRENT_WEBHOOK_CSV/$NEW_WEBHOOK_CSV/g" config/manifests/bases/ibm-common-service-operator.clusterserviceversion.yaml echo "Updated the config/manifests/bases/ibm-common-service-operator.clusterserviceversion.yaml" # Update cs operator version only @@ -108,23 +83,12 @@ elif [[ "$OSTYPE" == "darwin"* ]]; then echo "Updated the multiarch_image.sh" sed -i "" "s/$CURRENT_DEV_CSV/$NEW_DEV_CSV/g" README.md echo "Updated the README.md" - sed -i "" "s/$CURRENT_DEV_CSV/$NEW_DEV_CSV/g" controllers/constant/secretshare.go - echo "Updated the controllers/constant/secretshare.go" - sed -i "" "s/$CURRENT_DEV_CSV/$NEW_DEV_CSV/g" controllers/constant/webhook.go - echo "Updated the controllers/constant/webhook.go" - # update cs operator & channel & webhook & secretshare version in deply.yaml + # update cs operator & channel in deply.yaml sed -i "" "s/$CURRENT_DEV_CSV/$NEW_DEV_CSV/g" testdata/deploy/deploy.yaml sed -i "" "/operatorChannel/s/$CURRENT_CHANNEL/$NEW_CHANNEL/g" testdata/deploy/deploy.yaml - sed -i "" "/ibm-secretshare-operator/s/$CURRENT_SECRETSHARE_CSV/$NEW_SECRETSHARE_CSV/g" testdata/deploy/deploy.yaml - sed -i "" "/ibm-cs-webhook/s/$CURRENT_WEBHOOK_CSV/$NEW_WEBHOOK_CSV/g" testdata/deploy/deploy.yaml echo "Updated the testdata/deploy/deploy.yaml" - # update webhook & secretshare version in manager.yaml - sed -i "" "/ibm-secretshare-operator/s/$CURRENT_SECRETSHARE_CSV/$NEW_SECRETSHARE_CSV/g" config/manager/manager.yaml - sed -i "" "/ibm-cs-webhook/s/$CURRENT_WEBHOOK_CSV/$NEW_WEBHOOK_CSV/g" config/manager/manager.yaml - echo "Updated the config/manager/manager.yaml" - # update cs operator channel in Makefile & bundle.Dockerfile & annotations.yaml sed -i "" "s/$CURRENT_CHANNEL/$NEW_CHANNEL/g" Makefile echo "Updated the Makefile" diff --git a/config/certmanager/certificate.yaml b/config/certmanager/certificate.yaml index be5fa8680..b307834e9 100644 --- a/config/certmanager/certificate.yaml +++ b/config/certmanager/certificate.yaml @@ -5,7 +5,7 @@ apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: selfsigned-issuer - namespace: ibm-common-services + # namespace: ibm-common-services spec: selfSigned: {} --- @@ -13,7 +13,7 @@ apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml - namespace: ibm-common-services + # namespace: ibm-common-services spec: # $(SERVICE_NAME) and $(SERVICE_NAMESPACE) will be substituted by kustomize dnsNames: diff --git a/config/crd/bases/operator.ibm.com_commonservices.yaml b/config/crd/bases/operator.ibm.com_commonservices.yaml index 6f250cdd6..a3722bda1 100644 --- a/config/crd/bases/operator.ibm.com_commonservices.yaml +++ b/config/crd/bases/operator.ibm.com_commonservices.yaml @@ -1,11 +1,11 @@ - --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.6.1 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + foundationservices.cloudpak.ibm.com: crd name: commonservices.operator.ibm.com spec: group: operator.ibm.com @@ -19,23 +19,29 @@ spec: - name: v3 schema: openAPIV3Schema: - description: CommonService is the Schema for the commonservices API. This - API is used to configure general foundational services configurations, such - as sizing, catalogsource, etc. See description of fields for more details. - An instance of this CRD is automatically created by the ibm-common-service-operator - upon installation to trigger the installation of critical installer components + description: |- + CommonService is the Schema for the commonservices API. This API is used to + configure general foundational services configurations, such as sizing, + catalogsource, etc. See description of fields for more details. An instance + of this CRD is automatically created by the ibm-common-service-operator upon + installation to trigger the installation of critical installer components such as operand-deployment-lifecycle-manager (ODLM), which is required to further install other services from foundational services, such as IM. properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -43,21 +49,27 @@ spec: description: CommonServiceSpec defines the desired state of CommonService properties: BYOCACertificate: - description: BYOCACertificate enables the option to replace the cs-ca-certificate - with your own CA certificate + description: |- + BYOCACertificate enables the option to replace the cs-ca-certificate with + your own CA certificate type: boolean catalogName: - description: CatalogName is the name of the CatalogSource that will - be used for ODLM and other services in foundational services + description: |- + CatalogName is the name of the CatalogSource that will be used for ODLM + and other services in foundational services type: string catalogNamespace: - description: CatalogNamespace is the namespace of the CatalogSource - that will be used for ODLM and other services in foundational services + description: |- + CatalogNamespace is the namespace of the CatalogSource that will be used + for ODLM and other services in foundational services type: string defaultAdminUser: - description: DefalutAdminUser is the name of the default admin user - for foundational services IM, default is cpadmin + description: |- + DefalutAdminUser is the name of the default admin user for foundational + services IM, default is cpadmin type: string + enableInstanaMetricCollection: + type: boolean features: description: Features defines the configurations of Cloud Pak Services properties: @@ -79,15 +91,33 @@ spec: fipsEnabled: description: FipsEnabled enables FIPS mode for foundational services type: boolean + hugepages: + description: HugePages describes the hugepages settings for foundational + services + properties: + enable: + description: HugePagesEnabled enables hugepages settings for foundational + services + type: boolean + type: object + x-kubernetes-preserve-unknown-fields: true installPlanApproval: - description: 'InstallPlanApproval sets the approval mode for ODLM - and other foundational services: Manual or Automatic' + description: |- + InstallPlanApproval sets the approval mode for ODLM and other + foundational services: Manual or Automatic type: string + labels: + additionalProperties: + type: string + description: |- + Labels describes foundational services will use this + labels to labels their corresponding resources + type: object license: description: LicenseList defines the license specification in CSV properties: accept: - description: 'Accepting the license - URL: https://ibm.biz/integration-licenses' + description: 'Accepting the license - URL: https://ibm.biz/icpfs39license' type: boolean key: description: The license key for this deployment. @@ -102,51 +132,90 @@ spec: type: object manualManagement: type: boolean + operatorConfigs: + description: OperatorConfigs is a list of configurations to be applied + to operators via CSV updates + items: + description: OperatorConfig is configuration composed of key-value + pairs to be injected into specified CSVs + properties: + name: + description: Name is the name of the operator as requested in + an OperandRequest + type: string + replicas: + description: |- + Number of desired pods. This is a pointer to distinguish between explicit + 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 operatorNamespace: - description: OperatorNamespace describes the namespace where operators - will be installed in such as ODLM. This will also apply to all services - in foundational services, e.g. ODLM will install IM operator in - this namespace + description: |- + OperatorNamespace describes the namespace where operators will be + installed in such as ODLM. This will also apply to all services in + foundational services, e.g. ODLM will install IM operator in this + namespace type: string profileController: - description: ProfileController enables turbonomic to automatically - handle sizing of foundational services. Default value is 'default' + description: |- + ProfileController enables turbonomic to automatically handle sizing of + foundational services. Default value is 'default' type: string routeHost: - description: RouteHost describes the hostname for the foundational - services route, and can only be configured pre-installation of IM + description: |- + RouteHost describes the hostname for the foundational services route, + and can only be configured pre-installation of IM type: string services: - description: Services describes the CPU, memory, and replica configuration - for individual services in foundational services + description: |- + Services describes the CPU, memory, and replica configuration for + individual services in foundational services items: properties: managementStrategy: type: string name: type: string + resources: + items: + type: object + x-kubernetes-preserve-unknown-fields: true + type: array spec: additionalProperties: + type: object x-kubernetes-preserve-unknown-fields: true type: object required: - name - - spec type: object + x-kubernetes-preserve-unknown-fields: true type: array servicesNamespace: - description: ServicesNamespace describes the namespace where operands - will be created in such as OperandRegistry and OperandConfig. This - will also apply to all services in foundational services, e.g. IM - will create operands in this namespace + description: |- + ServicesNamespace describes the namespace where operands will be created + in such as OperandRegistry and OperandConfig. This will also apply to all + services in foundational services, e.g. IM will create operands in this + namespace type: string size: - description: 'Size describes the T-shirt size of foundational services: - starterset, small, medium, or large' + description: |- + Size describes the T-shirt size of foundational services: starterset, + small, medium, or large type: string storageClass: - description: StorageClass describes the storage class to use for the - foundational services PVCs + description: |- + StorageClass describes the storage class to use for the foundational + services PVCs type: string type: object x-kubernetes-preserve-unknown-fields: true @@ -172,6 +241,34 @@ spec: type: string type: object type: array + conditions: + description: Conditions represents the current state of CommonService + items: + description: CommonServiceCondition defines the observed condition + of CommonService + properties: + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + type: string + lastUpdateTime: + description: The last time this condition was updated. + type: string + message: + description: A human readable message indicating details about + the transition. + type: string + reason: + description: The reason for the condition's last transition. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type of condition. + type: string + type: object + type: array configStatus: description: ConfigStatus describes various configuration currently applied onto the foundational services installer. @@ -184,26 +281,30 @@ spec: description: CatalogNamespace is the namesapce of the CatalogSource type: string configurable: - description: Configurable indicates whether this CommonService - CR is the one that can be used to configure the foundational - services' installer. Other CommonService CRs configurations - will not take effect, except for sizing + description: |- + Configurable indicates whether this CommonService CR is the one + that can be used to configure the foundational services' installer. Other + CommonService CRs configurations will not take effect, except for sizing type: boolean operatorDeployed: - description: OperatorDeployed indicates whether the OperandRegistry - has been created or not. + description: |- + OperatorDeployed indicates whether the OperandRegistry has been created + or not. type: boolean operatorNamespace: - description: OperatorNamespace is the namespace of where the foundational - services' operators will be installed in. + description: |- + OperatorNamespace is the namespace of where the foundational services' + operators will be installed in. type: string servicesDeployed: - description: ServicesDeployed indicates whether the OperandConfig - has been created or not. + description: |- + ServicesDeployed indicates whether the OperandConfig has been created or + not. type: boolean servicesNamespace: - description: ServicesNamespace is the namespace where the foundational - services' operands will be created in. + description: |- + ServicesNamespace is the namespace where the foundational services' + operands will be created in. type: string topologyConfigurableCRs: description: TopologyConfigurableCRs describes the configurable @@ -243,9 +344,3 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/config/default/kustomization.yaml b/config/default/kustomization.yaml index a58fc1ea3..8d93769aa 100644 --- a/config/default/kustomization.yaml +++ b/config/default/kustomization.yaml @@ -1,5 +1,17 @@ # Adds namespace to all resources. -namespace: system +transformers: +- |- + apiVersion: builtin + kind: NamespaceTransformer + metadata: + name: notImportantHere + namespace: custom-namespace + setRoleBindingSubjects: allServiceAccounts + fieldSpecs: + - path: metadata/namespace + create: true + +namespace: custom-namespace # Value of this field is prepended to the # names of all resources, e.g. a deployment named @@ -23,6 +35,7 @@ bases: - ../certmanager # [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. #- ../prometheus +- ../service_account patchesStrategicMerge: # Protect the /metrics endpoint by putting it behind auth. @@ -32,7 +45,7 @@ patchesStrategicMerge: # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in # crd/kustomization.yaml -- manager_webhook_patch.yaml +# - manager_webhook_patch.yaml # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. # Uncomment 'CERTMANAGER' sections in crd/kustomization.yaml to enable the CA injection in the admission webhooks. diff --git a/config/default/manager_auth_proxy_patch.yaml b/config/default/manager_auth_proxy_patch.yaml index bccfb762f..cc81a7e08 100644 --- a/config/default/manager_auth_proxy_patch.yaml +++ b/config/default/manager_auth_proxy_patch.yaml @@ -4,7 +4,7 @@ apiVersion: apps/v1 kind: Deployment metadata: name: ibm-common-service-operator - namespace: ibm-common-services + # namespace: ibm-common-services spec: template: spec: diff --git a/config/default/manager_webhook_patch.yaml b/config/default/manager_webhook_patch.yaml index 05329cac3..88e3e6b94 100644 --- a/config/default/manager_webhook_patch.yaml +++ b/config/default/manager_webhook_patch.yaml @@ -2,7 +2,7 @@ apiVersion: apps/v1 kind: Deployment metadata: name: ibm-common-service-operator - namespace: ibm-common-services + # namespace: ibm-common-services spec: template: spec: diff --git a/config/ibm-common-service-operator.yaml b/config/ibm-common-service-operator.yaml new file mode 100644 index 000000000..aeb2ef544 --- /dev/null +++ b/config/ibm-common-service-operator.yaml @@ -0,0 +1,850 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + app.kubernetes.io/instance: ibm-common-service-operator + app.kubernetes.io/managed-by: ibm-common-service-operator + app.kubernetes.io/name: ibm-common-service-operator + foundationservices.cloudpak.ibm.com: crd + name: commonservices.operator.ibm.com +spec: + group: operator.ibm.com + names: + kind: CommonService + listKind: CommonServiceList + plural: commonservices + singular: commonservice + scope: Namespaced + versions: + - name: v3 + schema: + openAPIV3Schema: + description: |- + CommonService is the Schema for the commonservices API. This API is used to + configure general foundational services configurations, such as sizing, + catalogsource, etc. See description of fields for more details. An instance + of this CRD is automatically created by the ibm-common-service-operator upon + installation to trigger the installation of critical installer components + such as operand-deployment-lifecycle-manager (ODLM), which is required to + further install other services from foundational services, such as IM. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: CommonServiceSpec defines the desired state of CommonService + properties: + BYOCACertificate: + description: |- + BYOCACertificate enables the option to replace the cs-ca-certificate with + your own CA certificate + type: boolean + catalogName: + description: |- + CatalogName is the name of the CatalogSource that will be used for ODLM + and other services in foundational services + type: string + catalogNamespace: + description: |- + CatalogNamespace is the namespace of the CatalogSource that will be used + for ODLM and other services in foundational services + type: string + defaultAdminUser: + description: |- + DefalutAdminUser is the name of the default admin user for foundational + services IM, default is cpadmin + type: string + enableInstanaMetricCollection: + type: boolean + features: + description: Features defines the configurations of Cloud Pak Services + properties: + apiCatalog: + description: APICatalog defines the configuration of APICatalog + properties: + storageClass: + type: string + type: object + bedrockshim: + description: Bedrockshim defines the configuration of Bedrockshim + properties: + crossplaneProviderRemoval: + type: boolean + enabled: + type: boolean + type: object + type: object + fipsEnabled: + description: FipsEnabled enables FIPS mode for foundational services + type: boolean + hugepages: + description: HugePages describes the hugepages settings for foundational + services + properties: + enable: + description: HugePagesEnabled enables hugepages settings for foundational + services + type: boolean + type: object + x-kubernetes-preserve-unknown-fields: true + installPlanApproval: + description: |- + InstallPlanApproval sets the approval mode for ODLM and other + foundational services: Manual or Automatic + type: string + labels: + additionalProperties: + type: string + description: |- + Labels describes foundational services will use this + labels to labels their corresponding resources + type: object + license: + description: LicenseList defines the license specification in CSV + properties: + accept: + description: 'Accepting the license - URL: https://ibm.biz/icpfs39license' + type: boolean + key: + description: The license key for this deployment. + type: string + license: + description: The license being accepted where the component has + multiple. + type: string + use: + description: The type of license being accepted. + type: string + type: object + manualManagement: + type: boolean + operatorConfigs: + description: OperatorConfigs is a list of configurations to be applied + to operators via CSV updates + items: + description: OperatorConfig is configuration composed of key-value + pairs to be injected into specified CSVs + properties: + name: + description: Name is the name of the operator as requested in + an OperandRequest + type: string + replicas: + description: |- + Number of desired pods. This is a pointer to distinguish between explicit + 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 + operatorNamespace: + description: |- + OperatorNamespace describes the namespace where operators will be + installed in such as ODLM. This will also apply to all services in + foundational services, e.g. ODLM will install IM operator in this + namespace + type: string + profileController: + description: |- + ProfileController enables turbonomic to automatically handle sizing of + foundational services. Default value is 'default' + type: string + routeHost: + description: |- + RouteHost describes the hostname for the foundational services route, + and can only be configured pre-installation of IM + type: string + services: + description: |- + Services describes the CPU, memory, and replica configuration for + individual services in foundational services + items: + properties: + managementStrategy: + type: string + name: + type: string + resources: + items: + type: object + x-kubernetes-preserve-unknown-fields: true + type: array + spec: + additionalProperties: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + required: + - name + type: object + x-kubernetes-preserve-unknown-fields: true + type: array + servicesNamespace: + description: |- + ServicesNamespace describes the namespace where operands will be created + in such as OperandRegistry and OperandConfig. This will also apply to all + services in foundational services, e.g. IM will create operands in this + namespace + type: string + size: + description: |- + Size describes the T-shirt size of foundational services: starterset, + small, medium, or large + type: string + storageClass: + description: |- + StorageClass describes the storage class to use for the foundational + services PVCs + type: string + type: object + x-kubernetes-preserve-unknown-fields: true + status: + description: CommonServiceStatus defines the observed state of CommonService + properties: + bedrockOperators: + items: + description: BedrockOperator describes a list of foundational services' + operators currently installed for this tenant. + properties: + installPlanName: + type: string + name: + type: string + operatorStatus: + type: string + subscriptionStatus: + type: string + troubleshooting: + type: string + version: + type: string + type: object + type: array + conditions: + description: Conditions represents the current state of CommonService + items: + description: CommonServiceCondition defines the observed condition + of CommonService + properties: + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + type: string + lastUpdateTime: + description: The last time this condition was updated. + type: string + message: + description: A human readable message indicating details about + the transition. + type: string + reason: + description: The reason for the condition's last transition. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type of condition. + type: string + type: object + type: array + configStatus: + description: ConfigStatus describes various configuration currently + applied onto the foundational services installer. + properties: + catalogName: + description: CatalogName is the name of the CatalogSource foundational + services is using + type: string + catalogNamespace: + description: CatalogNamespace is the namesapce of the CatalogSource + type: string + configurable: + description: |- + Configurable indicates whether this CommonService CR is the one + that can be used to configure the foundational services' installer. Other + CommonService CRs configurations will not take effect, except for sizing + type: boolean + operatorDeployed: + description: |- + OperatorDeployed indicates whether the OperandRegistry has been created + or not. + type: boolean + operatorNamespace: + description: |- + OperatorNamespace is the namespace of where the foundational services' + operators will be installed in. + type: string + servicesDeployed: + description: |- + ServicesDeployed indicates whether the OperandConfig has been created or + not. + type: boolean + servicesNamespace: + description: |- + ServicesNamespace is the namespace where the foundational services' + operands will be created in. + type: string + topologyConfigurableCRs: + description: TopologyConfigurableCRs describes the configurable + CommonService CR + items: + properties: + apiVersion: + description: ApiVersion is the api version of the configurable + CommonService CR + type: string + kind: + description: Kind is the kind of the configurable CommonService + CR + type: string + namespace: + description: Namespace is the namespace of the configurable + CommonService CR + type: string + objectName: + description: ObjectName is the name of the configurable + CommonService CR + type: string + type: object + type: array + type: object + overallStatus: + description: OverallStatus describes whether the Installation for + the foundational services has succeeded or not + type: string + phase: + description: Phase describes the phase of the overall installation + type: string + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: ibm-common-service-operator + namespace: custom-namespace +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: ibm-common-service-operator + namespace: custom-namespace +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - delete + - patch +- apiGroups: + - operator.ibm.com + resources: + - namespacescopes + verbs: + - create + - delete + - get + - list + - watch + - patch +- apiGroups: + - cert-manager.io + resources: + - certificates + - issuers + verbs: + - create + - delete + - get + - list + - watch +- apiGroups: + - apps + resources: + - deployments + - statefulsets + - daemonsets + verbs: + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - operator.ibm.com + resources: + - commonservices + - commonservices/finalizers + - commonservices/status + - operandconfigs + - operandregistries + - operatorconfigs + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - operators.coreos.com + resources: + - subscriptions + - clusterserviceversions + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - namespaces + verbs: + - get +- apiGroups: + - "" + resources: + - pods + verbs: + - get + - list + - delete +- apiGroups: + - "" + resources: + - secrets + - services + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - events + verbs: + - create + - get + - patch + - update +- apiGroups: + - certmanager.k8s.io + resources: + - certificates + - issuers + verbs: + - delete +- apiGroups: + - monitoring.operator.ibm.com + resources: + - exporters + - prometheusexts + verbs: + - delete +- apiGroups: + - operator.ibm.com + resources: + - operandrequests + - operandbindinfos + - cataloguis + - helmapis + - helmrepos + verbs: + - delete +- apiGroups: + - elasticstack.ibm.com + resources: + - elasticstacks + verbs: + - delete +- apiGroups: + - "" + resources: + - serviceaccounts + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - rbac.authorization.k8s.io + resources: + - rolebindings + - roles + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - operator.ibm.com + resources: + - podpresets + verbs: + - get + - delete + - list +- apiGroups: + - ibmcpcs.ibm.com + resources: + - secretshares + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: ibm-common-service-operator +rules: +- apiGroups: + - "" + resourceNames: + - common-service-maps + resources: + - configmaps + verbs: + - delete + - update +- apiGroups: + - "" + resourceNames: + - cloud-native-postgresql-image-list + resources: + - configmaps + verbs: + - delete +- apiGroups: + - "" + resources: + - configmaps + verbs: + - create + - get + - list + - watch + - update +- apiGroups: + - "" + resources: + - secrets + verbs: + - get +- apiGroups: + - storage.k8s.io + resources: + - storageclasses + verbs: + - get + - list + - watch +- apiGroups: + - admissionregistration.k8s.io + resources: + - mutatingwebhookconfigurations + - validatingwebhookconfigurations + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - config.openshift.io + resources: + - infrastructures + verbs: + - get +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + - clusterroles + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/instance: ibm-common-service-operator + app.kubernetes.io/managed-by: ibm-common-service-operator + app.kubernetes.io/name: ibm-common-service-operator + name: ibm-common-service-operator + namespace: custom-namespace +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: ibm-common-service-operator +subjects: +- kind: ServiceAccount + name: ibm-common-service-operator + namespace: custom-namespace +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/instance: ibm-common-service-operator + app.kubernetes.io/managed-by: ibm-common-service-operator + app.kubernetes.io/name: ibm-common-service-operator + name: ibm-common-service-operator +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: ibm-common-service-operator +subjects: +- kind: ServiceAccount + name: ibm-common-service-operator + namespace: custom-namespace +--- +apiVersion: v1 +kind: Service +metadata: + name: webhook-service + namespace: custom-namespace +spec: + ports: + - port: 443 + targetPort: 9443 + selector: + control-plane: controller-manager +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/instance: ibm-common-service-operator + app.kubernetes.io/managed-by: ibm-common-service-operator + app.kubernetes.io/name: ibm-common-service-operator + productName: IBM_Cloud_Platform_Common_Services + name: ibm-common-service-operator + namespace: custom-namespace +spec: + replicas: 1 + selector: + matchLabels: + name: ibm-common-service-operator + strategy: + type: Recreate + template: + metadata: + annotations: + productID: 068a62892a1e4db39641342e592daa25 + productMetric: FREE + productName: IBM Cloud Platform Common Services + labels: + app.kubernetes.io/instance: ibm-common-service-operator + app.kubernetes.io/managed-by: ibm-common-service-operator + app.kubernetes.io/name: ibm-common-service-operator + name: ibm-common-service-operator + productName: IBM_Cloud_Platform_Common_Services + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/arch + operator: In + values: + - amd64 + - ppc64le + - s390x + containers: + - command: + - /manager + env: + - name: OPERATOR_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: WATCH_NAMESPACE + valueFrom: + configMapKeyRef: + key: namespaces + name: namespace-scope + optional: true + - name: NO_OLM + value: "true" + - name: ENABLE_WEBHOOKS + value: "false" + - name: OPERATOR_NAME + value: ibm-common-service-operator + image: icr.io/cpopen/common-service-operator:latest + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 10 + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 120 + periodSeconds: 60 + timeoutSeconds: 10 + name: ibm-common-service-operator + readinessProbe: + failureThreshold: 10 + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 20 + timeoutSeconds: 20 + resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 100m + ephemeral-storage: 256Mi + memory: 200Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + serviceAccountName: ibm-common-service-operator + terminationGracePeriodSeconds: 10 +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: serving-cert + namespace: custom-namespace +spec: + dnsNames: + - webhook-service.custom-namespace.svc + - webhook-service.custom-namespace.svc.cluster.local + issuerRef: + kind: Issuer + name: selfsigned-issuer + secretName: webhook-server-cert +--- +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: selfsigned-issuer + namespace: custom-namespace +spec: + selfSigned: {} +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + annotations: + cert-manager.io/inject-ca-from: custom-namespace/serving-cert + name: mutating-webhook-configuration +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: custom-namespace + path: /mutate-operator-ibm-com-v1alpha1-operandrequest + failurePolicy: Ignore + name: moperandrequest.kb.io + rules: + - apiGroups: + - operator.ibm.com + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - operandrequests + sideEffects: None +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + annotations: + cert-manager.io/inject-ca-from: custom-namespace/serving-cert + name: validating-webhook-configuration +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: custom-namespace + path: /validate-operator-ibm-com-v3-commonservice + failurePolicy: Fail + name: vcommonservice.kb.io + rules: + - apiGroups: + - operator.ibm.com + apiVersions: + - v3 + operations: + - CREATE + - UPDATE + resources: + - commonservices + sideEffects: None diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml index 5c5f0b84c..c47adaf38 100644 --- a/config/manager/kustomization.yaml +++ b/config/manager/kustomization.yaml @@ -1,2 +1,8 @@ resources: - manager.yaml +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +images: +- name: controller + newName: icr.io/cpopen/common-service-operator + newTag: latest diff --git a/config/manager/manager.yaml b/config/manager/manager.yaml index f079276e8..eca1924f8 100644 --- a/config/manager/manager.yaml +++ b/config/manager/manager.yaml @@ -2,11 +2,12 @@ apiVersion: apps/v1 kind: Deployment metadata: name: ibm-common-service-operator - namespace: ibm-common-services + # namespace: ibm-common-services labels: app.kubernetes.io/instance: "ibm-common-service-operator" app.kubernetes.io/managed-by: "ibm-common-service-operator" app.kubernetes.io/name: "ibm-common-service-operator" + productName: IBM_Cloud_Platform_Common_Services spec: strategy: type: Recreate @@ -21,6 +22,7 @@ spec: app.kubernetes.io/instance: ibm-common-service-operator app.kubernetes.io/managed-by: "ibm-common-service-operator" app.kubernetes.io/name: "ibm-common-service-operator" + productName: IBM_Cloud_Platform_Common_Services annotations: productName: "IBM Cloud Platform Common Services" productID: "068a62892a1e4db39641342e592daa25" @@ -68,16 +70,16 @@ spec: fieldPath: metadata.namespace - name: WATCH_NAMESPACE valueFrom: - fieldRef: - fieldPath: metadata.annotations['olm.targetNamespaces'] + configMapKeyRef: + name: namespace-scope + key: namespaces + optional: true + - name: NO_OLM + value: 'true' + - name: ENABLE_WEBHOOKS + value: 'false' - name: OPERATOR_NAME value: "ibm-common-service-operator" - - name: IBM_CS_WEBHOOK_IMAGE - value: icr.io/cpopen/cpfs/ibm-cs-webhook:1.18.0 - - name: IBM_SECRETSHARE_OPERATOR_IMAGE - value: icr.io/cpopen/cpfs/ibm-secretshare-operator:1.19.0 - - name: IBM_ZEN_OPERATOR_IMAGE - value: icr.io/cpopen/ibm-zen-operator:1.7.0 resources: limits: cpu: 500m @@ -87,6 +89,8 @@ spec: memory: 200Mi ephemeral-storage: 256Mi securityContext: + seccompProfile: + type: RuntimeDefault allowPrivilegeEscalation: false capabilities: drop: diff --git a/config/manifests/bases/ibm-common-service-operator.clusterserviceversion.yaml b/config/manifests/bases/ibm-common-service-operator.clusterserviceversion.yaml index d909a87e5..670be6923 100644 --- a/config/manifests/bases/ibm-common-service-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/ibm-common-service-operator.clusterserviceversion.yaml @@ -4,19 +4,28 @@ metadata: annotations: alm-examples: '[]' capabilities: Seamless Upgrades + cloudPakThemesVersion: styles4100.css containerImage: icr.io/cpopen/common-service-operator:latest createdAt: "2020-10-19T21:38:33Z" - description: The IBM Common Service Operator is used to deploy IBM Common Services + 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: "" olm.skipRange: "" - operatorChannel: v4.3 - operatorVersion: 4.3.1 + operatorChannel: v4.11 + operatorVersion: 4.11.0 operators.openshift.io/infrastructure-features: '["disconnected"]' operators.operatorframework.io/builder: operator-sdk-v1.2.0 operators.operatorframework.io/project_layout: go.kubebuilder.io/v2 repository: https://github.com/IBM/ibm-common-service-operator support: IBM + features.operators.openshift.io/disconnected: "true" + features.operators.openshift.io/fips-compliant: "true" + features.operators.openshift.io/proxy-aware: "false" + features.operators.openshift.io/tls-profiles: "false" + features.operators.openshift.io/token-auth-aws: "false" + features.operators.openshift.io/token-auth-azure: "false" + features.operators.openshift.io/token-auth-gcp: "false" labels: operatorframework.io/arch.amd64: supported operatorframework.io/arch.ppc64le: supported @@ -35,15 +44,31 @@ spec: kind: CommonService name: commonservices.operator.ibm.com specDescriptors: - - description: 'Accepting the license - URL: https://ibm.biz/integration-licenses' + - description: License information for this instance. You must accept the license. + displayName: License + path: license + - description: Read and accept the license that is applicable to your installation. + For more information, see https://ibm.biz/icpfs39license displayName: Accept path: license.accept value: - false x-descriptors: - urn:alm:descriptor:com.tectonic.ui:checkbox + - path: license.license + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:hidden + - path: license.use + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:hidden + - path: license.key + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:hidden + - path: license.use + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:hidden - description: The size of deployment profile for IBM Cloud Pak foundational - services + services. displayName: Size path: size x-descriptors: @@ -53,6 +78,29 @@ spec: - urn:alm:descriptor:com.tectonic.ui:select:medium - urn:alm:descriptor:com.tectonic.ui:select:large - urn:alm:descriptor:com.tectonic.ui:select:production + - displayName: Operator namespace + path: operatorNamespace + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Namespace + - displayName: Services namespace + path: servicesNamespace + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Namespace + - displayName: Storage class + path: storageClass + x-descriptors: + - urn:alm:descriptor:io.kubernetes:StorageClass + - urn:alm:descriptor:com.tectonic.ui:advanced + - displayName: FIPS mode + path: fipsEnabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - urn:alm:descriptor:com.tectonic.ui:advanced + - displayName: HugePages Setting + path: hugePages.enable + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - urn:alm:descriptor:com.tectonic.ui:advanced - description: The profile controller for IBM Cloud Pak foundational services displayName: ProfileController path: profileController @@ -61,6 +109,44 @@ spec: - urn:alm:descriptor:com.tectonic.ui:select:commonservice - urn:alm:descriptor:com.tectonic.ui:select:turbonomic - urn:alm:descriptor:com.tectonic.ui:select:vpa + - urn:alm:descriptor:com.tectonic.ui:advanced + - displayName: Identity management custom hostname + path: routeHost + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:advanced + - displayName: Identity management custom certificates + path: BYOCACertificate + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - urn:alm:descriptor:com.tectonic.ui:advanced + - displayName: Identity management default admin username + path: defaultAdminUser + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:advanced + - displayName: Custom OLM catalog name + path: catalogName + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:advanced + - displayName: Custom OLM catalog namespace + path: catalogNamespace + x-descriptors: + - urn:alm:descriptor:io.kubernetes:Namespace + - urn:alm:descriptor:com.tectonic.ui:advanced + - displayName: OLM Install Plan approval mode + path: installPlanApproval + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:select:Automatic + - urn:alm:descriptor:com.tectonic.ui:select:Manual + - urn:alm:descriptor:com.tectonic.ui:advanced + - path: manualManagement + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:hidden + - path: features + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:hidden + - path: services + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:hidden statusDescriptors: - description: Installed Bedrock Operator Name displayName: Name @@ -91,9 +177,8 @@ spec: When you install this operator, the operator completes the following tasks: - - Installs ODLM in all namespaces mode - - Creates the `ibm-common-services` namespace - - Creates the Common Services `OperandRegistry` and `OperandConfig` in the `ibm-common-services` namespace + - Installs ODLM operator namespace + - Creates the Common Services `OperandRegistry` and `OperandConfig` in the service namespace # Details For more information about installing this operator and other Common Services operators, see [Installer documentation](http://ibm.biz/cpcs_opinstall). If you are using this operator as part of an IBM Cloud Pak, see the documentation for that IBM Cloud Pak to learn more about how to install and use the operator service. For more information about IBM Cloud Paks, see [IBM Cloud Paks that use Common Services](http://ibm.biz/cpcs_cloudpaks). @@ -110,7 +195,7 @@ spec: ## Operator versions - - 4.3.1 + - 4.11.0 ## Prerequisites @@ -179,15 +264,9 @@ spec: name: IBM Support maturity: alpha minKubeVersion: 1.19.0 - nativeAPIs: - - group: cert-manager.io - kind: Certificate - version: v1 provider: name: IBM relatedImages: - - image: icr.io/cpopen/common-service-operator:4.3.1 + - image: icr.io/cpopen/common-service-operator:4.11.0 name: COMMON_SERVICE_OPERATOR_IMAGE - - image: icr.io/cpopen/cpfs/cpfs-utils:latest - name: CPFS_UTILS_IMAGE version: 0.0.0 diff --git a/config/prometheus/monitor.yaml b/config/prometheus/monitor.yaml index 36620c554..cd5f711e0 100644 --- a/config/prometheus/monitor.yaml +++ b/config/prometheus/monitor.yaml @@ -6,7 +6,7 @@ metadata: labels: control-plane: controller-manager name: controller-manager-metrics-monitor - namespace: ibm-common-services + # namespace: ibm-common-services spec: endpoints: - path: /metrics diff --git a/config/rbac/auth_proxy_service.yaml b/config/rbac/auth_proxy_service.yaml index 8c0a1a4e7..67096c581 100644 --- a/config/rbac/auth_proxy_service.yaml +++ b/config/rbac/auth_proxy_service.yaml @@ -4,7 +4,7 @@ metadata: labels: control-plane: controller-manager name: controller-manager-metrics-service - namespace: ibm-common-services + # namespace: ibm-common-services spec: ports: - name: https diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 52daaedb8..03cd18fc4 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -13,11 +13,20 @@ rules: - configmaps resourceNames: - common-service-maps +- verbs: + - delete + apiGroups: + - "" + resources: + - configmaps + resourceNames: + - cloud-native-postgresql-image-list - verbs: - create - get - list - watch + - update apiGroups: - '' resources: @@ -57,12 +66,43 @@ rules: - config.openshift.io resources: - infrastructures +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + - clusterroles + verbs: + - create + - delete + - get + - list + - patch + - update + - watch --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: ibm-common-service-operator rules: +- apiGroups: + - "" + verbs: + - delete + - patch + resources: + - configmaps +- apiGroups: + - operator.ibm.com + verbs: + - create + - delete + - get + - list + - watch + - patch + resources: + - namespacescopes - apiGroups: - cert-manager.io resources: @@ -81,6 +121,7 @@ rules: - statefulsets - daemonsets verbs: + - delete - get - list - patch @@ -94,6 +135,7 @@ rules: - commonservices/status - operandconfigs - operandregistries + - operatorconfigs verbs: - create - delete @@ -184,3 +226,49 @@ rules: - elasticstacks verbs: - delete +# Delete ServiceAccount, RoleBinding, Role, secretshares +- apiGroups: + - "" + resources: + - serviceaccounts + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - rbac.authorization.k8s.io + resources: + - rolebindings + - roles + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - operator.ibm.com + verbs: + - get + - delete + - list + resources: + - podpresets +- apiGroups: + - ibmcpcs.ibm.com + resources: + - secretshares + verbs: + - create + - delete + - get + - list + - patch + - update + - watch diff --git a/config/service_account/kustomization.yaml b/config/service_account/kustomization.yaml new file mode 100644 index 000000000..f50f29084 --- /dev/null +++ b/config/service_account/kustomization.yaml @@ -0,0 +1,2 @@ +resources: +- service_account.yaml \ No newline at end of file diff --git a/config/service_account/service_account.yaml b/config/service_account/service_account.yaml new file mode 100644 index 000000000..0976d4157 --- /dev/null +++ b/config/service_account/service_account.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: ibm-common-service-operator \ No newline at end of file diff --git a/config/webhook/manifests.yaml b/config/webhook/manifests.yaml index 5543cf3f8..c753e3f46 100644 --- a/config/webhook/manifests.yaml +++ b/config/webhook/manifests.yaml @@ -1,9 +1,7 @@ - --- apiVersion: admissionregistration.k8s.io/v1 kind: MutatingWebhookConfiguration metadata: - creationTimestamp: null name: mutating-webhook-configuration webhooks: - admissionReviewVersions: @@ -26,12 +24,10 @@ webhooks: resources: - operandrequests sideEffects: None - --- apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration metadata: - creationTimestamp: null name: validating-webhook-configuration webhooks: - admissionReviewVersions: diff --git a/config/webhook/service.yaml b/config/webhook/service.yaml index af959970b..d5e521a2d 100644 --- a/config/webhook/service.yaml +++ b/config/webhook/service.yaml @@ -3,7 +3,7 @@ apiVersion: v1 kind: Service metadata: name: webhook-service - namespace: ibm-common-services + # namespace: ibm-common-services spec: ports: - port: 443 diff --git a/controllers/bootstrap/init.go b/controllers/bootstrap/init.go index 05fd4fe6e..5e2d29242 100644 --- a/controllers/bootstrap/init.go +++ b/controllers/bootstrap/init.go @@ -20,6 +20,7 @@ import ( "bytes" "context" "fmt" + "os" "reflect" "strconv" "strings" @@ -28,7 +29,12 @@ import ( utilyaml "github.com/ghodss/yaml" olmv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1" + "golang.org/x/mod/semver" + admv1 "k8s.io/api/admissionregistration/v1" + appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + storagev1 "k8s.io/api/storage/v1" "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -45,27 +51,19 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/manager" - apiv3 "github.com/IBM/ibm-common-service-operator/api/v3" - util "github.com/IBM/ibm-common-service-operator/controllers/common" - "github.com/IBM/ibm-common-service-operator/controllers/constant" - "github.com/IBM/ibm-common-service-operator/controllers/deploy" - odlm "github.com/IBM/operand-deployment-lifecycle-manager/api/v1alpha1" + apiv3 "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" + "github.com/IBM/ibm-common-service-operator/v4/controllers/deploy" + nssv1 "github.com/IBM/ibm-namespace-scope-operator/v4/api/v1" + ssv1 "github.com/IBM/ibm-secretshare-operator/api/v1" + odlm "github.com/IBM/operand-deployment-lifecycle-manager/v4/api/v1alpha1" certmanagerv1 "github.com/ibm/ibm-cert-manager-operator/apis/cert-manager/v1" ) var ( - placeholder = "placeholder" - OdlmNamespacedSubResource = "odlmNamespacedSubscription" - OdlmClusterSubResource = "odlmClusterSubscription" - RegistryCrResources = "csV3OperandRegistry" - RegistrySaasCrResources = "csV3SaasOperandRegistry" - ConfigCrResources = "csV3OperandConfig" - ConfigSaasCrResources = "csV3SaasOperandConfig" - CSOperatorVersions = map[string]string{ - "operand-deployment-lifecycle-manager-app": "1.5.0", - "ibm-cert-manager-operator": "3.9.0", - } + placeholder = "placeholder" ) var ctx = context.Background() @@ -110,24 +108,28 @@ func NewBootstrap(mgr manager.Manager) (bs *Bootstrap, err error) { } catalogSourceName, catalogSourceNs := util.GetCatalogSource(constant.IBMCSPackage, operatorNs, mgr.GetAPIReader()) - if catalogSourceName == "" || catalogSourceNs == "" { - err = fmt.Errorf("failed to get catalogsource") - return + if os.Getenv("NO_OLM") != "true" { + if catalogSourceName == "" || catalogSourceNs == "" { + err = fmt.Errorf("failed to get catalogsource") + return + } } + approvalMode, err := util.GetApprovalModeinNs(mgr.GetAPIReader(), operatorNs) if err != nil { return } csData := apiv3.CSData{ - CPFSNs: cpfsNs, - ServicesNs: servicesNs, - OperatorNs: operatorNs, - CatalogSourceName: catalogSourceName, - CatalogSourceNs: catalogSourceNs, - ApprovalMode: approvalMode, - ZenOperatorImage: util.GetImage("IBM_ZEN_OPERATOR_IMAGE"), - WatchNamespaces: util.GetWatchNamespace(), - OnPremMultiEnable: strconv.FormatBool(util.CheckMultiInstances(mgr.GetAPIReader())), + CPFSNs: cpfsNs, + ServicesNs: servicesNs, + OperatorNs: operatorNs, + CatalogSourceName: catalogSourceName, + CatalogSourceNs: catalogSourceNs, + ApprovalMode: approvalMode, + WatchNamespaces: util.GetWatchNamespace(), + OnPremMultiEnable: strconv.FormatBool(util.CheckMultiInstances(mgr.GetAPIReader())), + ExcludedCatalog: constant.ExcludedCatalog, + StatusMonitoredServices: constant.StatusMonitoredServices, } bs = &Bootstrap{ @@ -154,19 +156,35 @@ func NewBootstrap(mgr manager.Manager) (bs *Bootstrap, err error) { if r, ok := annotations["operatorVersion"]; ok { bs.CSData.Version = r } + + if r, ok := annotations["cloudPakThemesVersion"]; ok { + bs.CSData.CloudPakThemesVersion = r + } + klog.Infof("Single Deployment Status: %v, MultiInstance Deployment status: %v, SaaS Depolyment Status: %v", !bs.MultiInstancesEnable, bs.MultiInstancesEnable, bs.SaasEnable) return } // InitResources initialize resources at the bootstrap of operator func (b *Bootstrap) InitResources(instance *apiv3.CommonService, forceUpdateODLMCRs bool) error { - installPlanApproval := instance.Spec.InstallPlanApproval - if installPlanApproval != "" { - if installPlanApproval != olmv1alpha1.ApprovalAutomatic && installPlanApproval != olmv1alpha1.ApprovalManual { - return fmt.Errorf("invalid value for installPlanApproval %v", installPlanApproval) + installPlanApproval := instance.Spec.InstallPlanApproval + if os.Getenv("NO_OLM") != "true" { + if installPlanApproval != "" { + if installPlanApproval != olmv1alpha1.ApprovalAutomatic && installPlanApproval != olmv1alpha1.ApprovalManual { + return fmt.Errorf("invalid value for installPlanApproval %v", installPlanApproval) + } + b.CSData.ApprovalMode = string(installPlanApproval) } - b.CSData.ApprovalMode = string(installPlanApproval) + } else { + // set installPlanApproval to empty in non olm environment + installPlanApproval = "" + } + + // Clean v3 Namespace Scope Operator and CRs in the servicesNamespace + if err := b.CleanNamespaceScopeResources(); err != nil { + klog.Errorf("Failed to clean NamespaceScope resources: %v", err) + return err } // Check storageClass @@ -180,6 +198,28 @@ func (b *Bootstrap) InitResources(instance *apiv3.CommonService, forceUpdateODLM return err } + // Temporary solution for EDB image ConfigMap reference + if os.Getenv("NO_OLM") != "true" { + klog.Infof("It is not a non-OLM mode, create EDB Image ConfigMap") + if err := b.CreateEDBImageMaps(); err != nil { + klog.Errorf("Failed to create EDB Image ConfigMap: %v", err) + return err + } + } + + // Create Keycloak themes ConfigMap + if err := b.CreateKeycloakThemesConfigMap(); err != nil { + klog.Errorf("Failed to create Keycloak Themes ConfigMap: %v", err) + return err + } + + mutatingWebhooks := []string{constant.CSWebhookConfig, constant.OperanReqConfig} + validatingWebhooks := []string{constant.CSMappingConfig} + if err := b.DeleteV3Resources(mutatingWebhooks, validatingWebhooks); err != nil { + klog.Errorf("Failed to delete v3 resources: %v", err) + return err + } + // Backward compatible for All Namespace Installation Mode upgrade // Uninstall ODLM in servicesNamespace(ibm-common-services) if b.CSData.CPFSNs != b.CSData.ServicesNs { @@ -191,10 +231,9 @@ func (b *Bootstrap) InitResources(instance *apiv3.CommonService, forceUpdateODLM } // Check if ODLM OperandRegistry and OperandConfig are created - dc := discovery.NewDiscoveryClientForConfigOrDie(b.Config) klog.Info("Checking if OperandRegistry and OperandConfig CRD already exist") - existOpreg, _ := b.ResourceExists(dc, "operator.ibm.com/v1alpha1", "OperandRegistry") - existOpcon, _ := b.ResourceExists(dc, "operator.ibm.com/v1alpha1", "OperandConfig") + existOpreg, _ := b.CheckCRD(constant.OpregAPIGroupVersion, constant.OpregKind) + existOpcon, _ := b.CheckCRD(constant.OpregAPIGroupVersion, constant.OpconKind) // Install/update Opreg and Opcon resources before installing ODLM if CRDs exist if existOpreg && existOpcon { @@ -203,6 +242,11 @@ func (b *Bootstrap) InitResources(instance *apiv3.CommonService, forceUpdateODLM if err := b.ConfigODLMOperandManagedByOperator(ctx); err != nil { return err } + // Set "Pending" condition when creating OperandRegistry and OperandConfig + instance.SetPendingCondition(constant.MasterCR, apiv3.ConditionTypePending, corev1.ConditionTrue, apiv3.ConditionReasonInit, apiv3.ConditionMessageInit) + if err := b.Client.Status().Update(ctx, instance); err != nil { + return err + } klog.Info("Installing/Updating OperandRegistry") if err := b.InstallOrUpdateOpreg(forceUpdateODLMCRs, installPlanApproval); err != nil { @@ -215,29 +259,74 @@ func (b *Bootstrap) InitResources(instance *apiv3.CommonService, forceUpdateODLM } } - klog.Info("Installing ODLM Operator") - if err := b.renderTemplate(constant.ODLMSubscription, b.CSData); err != nil { - return err + if os.Getenv("NO_OLM") != "true" { + // skip deploy ODLM in no-olm + klog.Info("Installing ODLM Operator") + if err := b.renderTemplate(constant.ODLMSubscription, b.CSData); err != nil { + return err + } + + klog.Info("Waiting for ODLM Operator to be ready") + if isWaiting, err := b.waitOperatorCSV(constant.IBMODLMPackage, "ibm-odlm", b.CSData.CPFSNs); err != nil { + return err + } else if isWaiting { + forceUpdateODLMCRs = true + } + } else { + forceUpdateODLMCRs = true } // wait ODLM OperandRegistry and OperandConfig CRD - if err := b.waitResourceReady("operator.ibm.com/v1alpha1", "OperandRegistry"); err != nil { + if err := b.waitResourceReady(constant.OpregAPIGroupVersion, constant.OpregKind); err != nil { return err } - if err := b.waitResourceReady("operator.ibm.com/v1alpha1", "OperandConfig"); err != nil { + if err := b.waitResourceReady(constant.OpregAPIGroupVersion, constant.OpconKind); err != nil { return err } + // Reinstall/update OperandRegistry and OperandConfig if not installed/updated in the previous step + if !existOpreg || !existOpcon || forceUpdateODLMCRs { - klog.Info("Installing/Updating OperandRegistry") - if err := b.InstallOrUpdateOpreg(forceUpdateODLMCRs, installPlanApproval); err != nil { - return err + // Set "Pending" condition when creating OperandRegistry and OperandConfig + instance.SetPendingCondition(constant.MasterCR, apiv3.ConditionTypePending, corev1.ConditionTrue, apiv3.ConditionReasonInit, apiv3.ConditionMessageInit) + if err := b.Client.Status().Update(ctx, instance); err != nil { + return err + } + + klog.Info("Installing/Updating OperandRegistry") + if err := b.InstallOrUpdateOpreg(forceUpdateODLMCRs, installPlanApproval); err != nil { + return err + } + + klog.Info("Installing/Updating OperandConfig") + if err := b.InstallOrUpdateOpcon(forceUpdateODLMCRs); err != nil { + return err + } } + return nil +} - klog.Info("Installing/Updating OperandConfig") - if err := b.InstallOrUpdateOpcon(forceUpdateODLMCRs); err != nil { +// CheckWarningCondition +func (b *Bootstrap) CheckWarningCondition(instance *apiv3.CommonService) error { + csStorageClass := &storagev1.StorageClassList{} + err := b.Reader.List(context.TODO(), csStorageClass) + if err != nil { return err } + defaultCount := 0 + if len(csStorageClass.Items) > 0 { + for _, sc := range csStorageClass.Items { + if sc.Annotations != nil && sc.Annotations["storageclass.kubernetes.io/is-default-class"] == "true" { + klog.V(2).Infof("Default StorageClass found: %s\n", sc.Name) + defaultCount++ + } + } + } + + // check if there is no storageClass declared under spec section and the default count is not 1 + if instance.Spec.StorageClass == "" && defaultCount != 1 { + instance.SetWarningCondition(constant.MasterCR, apiv3.ConditionTypeWarning, corev1.ConditionTrue, apiv3.ConditionReasonWarning, apiv3.ConditionMessageMissSC) + } return nil } @@ -286,41 +375,21 @@ func (b *Bootstrap) CreateCsCR() error { if len(b.CSData.WatchNamespaces) == 0 { // All Namespaces Mode: - // using `ibm-common-services` ns as ServicesNs if it exists - // Otherwise, do not create default CR - // Tolerate if someone manually create the default CR in operator NS - defaultCRReady := false - for !defaultCRReady { - _, err := b.GetObject(cs) - if errors.IsNotFound(err) { - ctx := context.Background() - ns := &corev1.Namespace{} - if err := b.Reader.Get(ctx, types.NamespacedName{Name: constant.MasterNamespace}, ns); err != nil { - if errors.IsNotFound(err) { - klog.Warningf("Not found well-known default namespace %v, please manually create the namespace", constant.MasterNamespace) - time.Sleep(10 * time.Second) - continue - } - return err - } - b.CSData.ServicesNs = constant.MasterNamespace - return b.renderTemplate(constant.CsCR, b.CSData) - } else if err != nil { - return err - } - defaultCRReady = true + // using `ibm-common-services` ns as ServicesNs if CS CR does not exist + if _, err := b.GetObject(cs); errors.IsNotFound(err) { + b.CSData.ServicesNs = constant.MasterNamespace + return b.renderTemplate(constant.CsCR, b.CSData) + } else if err != nil { + return err } } else { - _, err := b.GetObject(cs) - if errors.IsNotFound(err) { // Only if it's a fresh install + if _, err := b.GetObject(cs); errors.IsNotFound(err) { // Only if it's a fresh install // Fresh Intall: No ODLM and NO CR return b.renderTemplate(constant.CsCR, b.CSData) } else if err != nil { return err } } - - // Restart && Upgrade from 3.5+: Found existing CR return nil } @@ -337,7 +406,7 @@ func (b *Bootstrap) CreateOrUpdateFromYaml(yamlContent []byte, alwaysUpdate ...b objInCluster, err := b.GetObject(obj) if errors.IsNotFound(err) { - klog.Infof("Creating resource with name: %s, namespace: %s, kind: %s, apiversion: %s/%s\n", obj.GetName(), obj.GetNamespace(), gvk.Kind, gvk.Group, gvk.Version) + klog.V(2).Infof("Creating resource with name: %s, namespace: %s, kind: %s, apiversion: %s/%s\n", obj.GetName(), obj.GetNamespace(), gvk.Kind, gvk.Group, gvk.Version) if err := b.CreateObject(obj); err != nil { errMsg = err } @@ -392,7 +461,6 @@ func (b *Bootstrap) CreateOrUpdateFromYaml(yamlContent []byte, alwaysUpdate ...b } } } - return errMsg } @@ -417,14 +485,14 @@ func (b *Bootstrap) DeleteFromYaml(objectTemplate string, data interface{}) erro _, err := b.GetObject(obj) if errors.IsNotFound(err) { - klog.Infof("Not Found name: %s, namespace: %s, kind: %s, apiversion: %s/%s\n, skipping", obj.GetName(), obj.GetNamespace(), gvk.Kind, gvk.Group, gvk.Version) + klog.V(2).Infof("Not Found name: %s, namespace: %s, kind: %s, apiversion: %s/%s, skipping", obj.GetName(), obj.GetNamespace(), gvk.Kind, gvk.Group, gvk.Version) continue } else if err != nil { errMsg = err continue } - klog.Infof("Deleting object with name: %s, namespace: %s, kind: %s, apiversion: %s/%s\n", obj.GetName(), obj.GetNamespace(), gvk.Kind, gvk.Group, gvk.Version) + klog.Infof("Deleting object with name: %s, namespace: %s, kind: %s, apiversion: %s/%s", obj.GetName(), obj.GetNamespace(), gvk.Kind, gvk.Group, gvk.Version) if err := b.DeleteObject(obj); err != nil { errMsg = err } @@ -435,7 +503,7 @@ func (b *Bootstrap) DeleteFromYaml(objectTemplate string, data interface{}) erro if errors.IsNotFound(errNotFound) { return true, nil } - klog.Infof("waiting for object with name: %s, namespace: %s, kind: %s, apiversion: %s/%s to delete\n", obj.GetName(), obj.GetNamespace(), gvk.Kind, gvk.Group, gvk.Version) + klog.Infof("waiting for object with name: %s, namespace: %s, kind: %s, apiversion: %s/%s to delete", obj.GetName(), obj.GetNamespace(), gvk.Kind, gvk.Group, gvk.Version) return false, nil }); err != nil { return err @@ -448,6 +516,10 @@ func (b *Bootstrap) DeleteFromYaml(objectTemplate string, data interface{}) erro // GetSubscription returns the subscription instance of "name" from "namespace" namespace func (b *Bootstrap) GetSubscription(ctx context.Context, name, namespace string) (*unstructured.Unstructured, error) { + if os.Getenv("NO_OLM") == "true" { + klog.V(2).Infof("skip get subscription in no olm environment") + return nil, nil + } klog.Infof("Fetch Subscription: %v/%v", namespace, name) sub := &unstructured.Unstructured{} sub.SetGroupVersionKind(olmv1alpha1.SchemeGroupVersion.WithKind("subscription")) @@ -465,6 +537,10 @@ func (b *Bootstrap) GetSubscription(ctx context.Context, name, namespace string) // GetSubscription returns the subscription instances from a namespace func (b *Bootstrap) ListSubscriptions(ctx context.Context, namespace string, listOptions client.ListOptions) (*unstructured.UnstructuredList, error) { + if os.Getenv("NO_OLM") == "true" { + klog.V(2).Infof("skip list subscription in no olm environment") + return nil, nil + } klog.Infof("List Subscriptions in namespace %v", namespace) subs := &unstructured.UnstructuredList{} subs.SetGroupVersionKind(olmv1alpha1.SchemeGroupVersion.WithKind("SubscriptionList")) @@ -528,6 +604,28 @@ func (b *Bootstrap) ListOperandConfig(ctx context.Context, opts ...client.ListOp return opconfigList } +// ListOperatorConfig returns the OperatorConfig instance with "options" +func (b *Bootstrap) ListOperatorConfig(ctx context.Context, opts ...client.ListOption) *odlm.OperatorConfigList { + operatorConfigList := &odlm.OperatorConfigList{} + if err := b.Client.List(ctx, operatorConfigList, opts...); err != nil { + klog.Errorf("failed to List OperatorConfig: %v", err) + return nil + } + + return operatorConfigList +} + +// ListNssCRs returns the NameSpaceScopes instance list with "options" +func (b *Bootstrap) ListNssCRs(ctx context.Context, namespace string) (*nssv1.NamespaceScopeList, error) { + nssCRsList := &nssv1.NamespaceScopeList{} + if err := b.Client.List(ctx, nssCRsList, &client.ListOptions{Namespace: namespace}); err != nil { + klog.Errorf("failed to List NamespaceScope CRs in namespace %s: %v", namespace, err) + return nil, err + } + + return nssCRsList, nil +} + // ListCerts returns the Certificate instance list with "options" func (b *Bootstrap) ListCerts(ctx context.Context, opts ...client.ListOption) *certmanagerv1.CertificateList { certList := &certmanagerv1.CertificateList{} @@ -552,6 +650,11 @@ func (b *Bootstrap) ListIssuer(ctx context.Context, opts ...client.ListOption) * func (b *Bootstrap) CheckOperatorCatalog(ns string) error { + if os.Getenv("NO_OLM") == "true" { + klog.V(2).Infof("skip ckeck catalog in no olm environment") + return nil + } + err := utilwait.PollImmediate(time.Second*10, time.Minute*3, func() (done bool, err error) { subList := &olmv1alpha1.SubscriptionList{} @@ -585,6 +688,37 @@ func (b *Bootstrap) CheckOperatorCatalog(ns string) error { return err } +// CheckCRD returns true if the given crd is existent +func (b *Bootstrap) CheckCRD(apiGroupVersion string, kind string) (bool, error) { + dc := discovery.NewDiscoveryClientForConfigOrDie(b.Config) + exist, err := b.ResourceExists(dc, apiGroupVersion, kind) + if err != nil { + return false, err + } + if !exist { + return false, nil + } + return true, nil +} + +// WaitResourceReady returns true only when the specific resource CRD is created and wait for infinite time +func (b *Bootstrap) WaitResourceReady(apiGroupVersion string, kind string) error { + dc := discovery.NewDiscoveryClientForConfigOrDie(b.Config) + if err := utilwait.PollImmediateInfinite(time.Second*10, func() (done bool, err error) { + exist, err := b.ResourceExists(dc, apiGroupVersion, kind) + if err != nil { + return exist, err + } + if !exist { + klog.V(2).Infof("waiting for resource ready with kind: %s, apiGroupVersion: %s", kind, apiGroupVersion) + } + return exist, nil + }); err != nil { + return err + } + return nil +} + func (b *Bootstrap) waitResourceReady(apiGroupVersion, kind string) error { dc := discovery.NewDiscoveryClientForConfigOrDie(b.Config) if err := utilwait.PollImmediate(time.Second*10, time.Minute*2, func() (done bool, err error) { @@ -630,138 +764,240 @@ func (b *Bootstrap) InstallOrUpdateOpreg(forceUpdateODLMCRs bool, installPlanApp } } - var err error - constant.CSV3OperandRegistry, err = constant.ConcatenateRegistries(constant.CSV2OpReg, constant.CSV3OpReg, b.CSData) - if err != nil { - klog.Errorf("failed to concatenate registries CSV3OperandRegistry: %v", err) - } - // Append CP3 Operators into CP3 OperandRegistry + var baseReg string registries := []string{ + constant.CSV4OpReg, constant.MongoDBOpReg, constant.IMOpReg, constant.IdpConfigUIOpReg, constant.PlatformUIOpReg, constant.KeyCloakOpReg, + constant.CommonServicePGOpReg, } - - for _, reg := range registries { - constant.CSV3OperandRegistry, err = constant.ConcatenateRegistries(constant.CSV3OperandRegistry, reg, b.CSData) - if err != nil { - klog.Errorf("failed to append CP3 operators into OperandRegistry: %v", err) - } + if b.SaasEnable { + baseReg = constant.CSV3SaasOpReg + } else { + baseReg = constant.CSV3OpReg } - constant.CSV3SaasOperandRegistry, err = constant.ConcatenateRegistries(constant.CSV2SaasOpReg, constant.CSV3SaasOpReg, b.CSData) + concatenatedReg, err := constant.ConcatenateRegistries(baseReg, registries, b.CSData) if err != nil { - klog.Errorf("failed to concatenate registries CSV3SaasOperandRegistry: %v", err) + klog.Errorf("failed to concatenate OperandRegistry: %v", err) + return err } - // Append CP3 operators into CP3 SaaS OperandRegistry - Saasregistries := []string{ - constant.MongoDBOpReg, - constant.IMOpReg, - constant.PlatformUIOpReg, - constant.KeyCloakOpReg, + if err := b.renderTemplate(concatenatedReg, b.CSData, forceUpdateODLMCRs); err != nil { + return err } + return nil +} - for _, reg := range Saasregistries { - constant.CSV3SaasOperandRegistry, err = constant.ConcatenateRegistries(constant.CSV3SaasOperandRegistry, reg, b.CSData) - if err != nil { - klog.Errorf("failed to append CP3 operators into SaaS OperandRegistry: %v", err) - } - } +// InstallOrUpdateOpcon will install or update OperandConfig when Opcon CRD is existent +func (b *Bootstrap) InstallOrUpdateOpcon(forceUpdateODLMCRs bool) error { - var obj []*unstructured.Unstructured - if b.SaasEnable { - // OperandRegistry for SaaS deployment - obj, err = b.GetObjs(constant.CSV3SaasOperandRegistry, b.CSData) - } else { - // OperandRegistry for on-prem deployment - obj, err = b.GetObjs(constant.CSV3OperandRegistry, b.CSData) + var baseCon string + configs := []string{ + constant.MongoDBOpCon, + constant.IMOpCon, + constant.UserMgmtOpCon, + constant.IdpConfigUIOpCon, + constant.PlatformUIOpCon, + constant.KeyCloakOpCon, + constant.CommonServicePGOpCon, } + + baseCon = constant.CSV4OpCon + + concatenatedCon, err := constant.ConcatenateConfigs(baseCon, configs, b.CSData) if err != nil { - klog.Error(err) + klog.Errorf("failed to concatenate OperandConfig: %v", err) return err } - objInCluster, err := b.GetObject(obj[0]) - if errors.IsNotFound(err) { - klog.Infof("Creating resource with name: %s, namespace: %s, kind: %s, apiversion: %s\n", obj[0].GetName(), obj[0].GetNamespace(), obj[0].GetKind(), obj[0].GetAPIVersion()) - if err := b.CreateObject(obj[0]); err != nil { - klog.Error(err) - return err - } - } else if err != nil { - klog.Error(err) + if err := b.renderTemplate(concatenatedCon, b.CSData, forceUpdateODLMCRs); err != nil { return err - } else { - klog.Infof("Updating resource with name: %s, namespace: %s, kind: %s, apiversion: %s\n", obj[0].GetName(), obj[0].GetNamespace(), obj[0].GetKind(), obj[0].GetAPIVersion()) - resourceVersion := objInCluster.GetResourceVersion() - obj[0].SetResourceVersion(resourceVersion) - v1IsLarger, convertErr := util.CompareVersion(obj[0].GetAnnotations()["version"], objInCluster.GetAnnotations()["version"]) - if convertErr != nil { - return convertErr - } - if v1IsLarger || forceUpdateODLMCRs { - if err := b.UpdateObject(obj[0]); err != nil { - klog.Error(err) - return err + } + return nil +} + +// InstallOrUpdateOpcon will install or update OperandConfig when Opcon CRD is existent +func (b *Bootstrap) InstallOrUpdateOperatorConfig(config string, forceUpdateODLMCRs bool) error { + // clean up OperatorConfigs not in servicesNamespace every time function is called + opts := []client.ListOption{ + client.MatchingLabels( + map[string]string{constant.CsManagedLabel: "true"}), + } + operatorConfigList := b.ListOperatorConfig(ctx, opts...) + if operatorConfigList != nil { + for _, operatorConfig := range operatorConfigList.Items { + if operatorConfig.Namespace != b.CSData.ServicesNs { + if err := b.Client.Delete(ctx, &operatorConfig); err != nil { + klog.Errorf("Failed to delete idle OperandConfig %s/%s which is managed by CS operator, but not in ServicesNamespace %s", operatorConfig.GetNamespace(), operatorConfig.GetName(), b.CSData.ServicesNs) + return err + } + klog.Infof("Delete idle OperandConfig %s/%s which is managed by CS operator, but not in ServicesNamespace %s", operatorConfig.GetNamespace(), operatorConfig.GetName(), b.CSData.ServicesNs) } } } + if err := b.renderTemplate(config, b.CSData, forceUpdateODLMCRs); err != nil { + return err + } + return nil } -// InstallOrUpdateOpcon will install or update OperandConfig when Opcon CRD is existent -func (b *Bootstrap) InstallOrUpdateOpcon(forceUpdateODLMCRs bool) error { - var err error +// CreateNsScopeConfigmap creates nss configmap for operators +func (b *Bootstrap) CreateNsScopeConfigmap() error { + cmRes := constant.NamespaceScopeConfigMap + if err := b.renderTemplate(cmRes, b.CSData, false); err != nil { + return err + } + return nil +} - // Append CP3 Services with suffix into CP3 and SaaS OperandConfig - Configs := []string{ - constant.MongoDBOpCon, - constant.IMOpCon, - constant.IdpConfigUIOpCon, - constant.PlatformUIOpCon, - constant.KeyCloakOpCon, +// CreateEDBImageConfig creates a ConfigMap contains EDB image reference +func (b *Bootstrap) CreateEDBImageMaps() error { + cmRes := constant.EDBImageConfigMap + if err := b.renderTemplate(cmRes, b.CSData, false); err != nil { + return err } + return nil +} - constant.CSV3OperandConfig = constant.CSV3OpCon - constant.CSV3SaasOperandConfig = constant.CSV3SaasOpCon - for _, con := range Configs { - constant.CSV3OperandConfig, err = constant.ConcatenateConfigs(constant.CSV3OperandConfig, con, b.CSData) - if err != nil { - klog.Errorf("failed to append CP3 services into OperandConfig: %v", err) - return err - } - constant.CSV3SaasOperandConfig, err = constant.ConcatenateConfigs(constant.CSV3SaasOperandConfig, con, b.CSData) - if err != nil { - klog.Errorf("failed to append CP3 services into SaaS OperandConfig: %v", err) - return err - } +// CreateKeycloakThemesConfigMap creates a ConfigMap contains Keycloak themes +func (b *Bootstrap) CreateKeycloakThemesConfigMap() error { + + klog.Info("Extracting Keycloak themes from jar file") + themeFile := constant.KeycloakThemesJar + themeFileContent, err := util.ReadFile(themeFile) + if err != nil { + return err } + b.CSData.CloudPakThemes = util.EncodeBase64(themeFileContent) - if b.SaasEnable { - // OperandConfig for SaaS deployment - if err := b.renderTemplate(constant.CSV3SaasOperandConfig, b.CSData, forceUpdateODLMCRs); err != nil { + cmRes := constant.KeycloakThemesConfigMap + if err := b.renderTemplate(cmRes, b.CSData, false); err != nil { + return err + } + return nil +} + +func (b *Bootstrap) DeleteV3Resources(mutatingWebhooks, validatingWebhooks []string) error { + + // Delete the list of MutatingWebhookConfigurations + for _, webhook := range mutatingWebhooks { + if err := b.deleteResource(&admv1.MutatingWebhookConfiguration{}, webhook, "", "MutatingWebhookConfiguration"); err != nil { return err } - } else { - // OperandConfig for on-prem deployment - if err := b.renderTemplate(constant.CSV3OperandConfig, b.CSData, forceUpdateODLMCRs); err != nil { + } + + // Delete the list of ValidatingWebhookConfiguration + for _, webhook := range validatingWebhooks { + if err := b.deleteResource(&admv1.ValidatingWebhookConfiguration{}, webhook, "", "ValidatingWebhookConfiguration"); err != nil { return err } } + if err := b.deleteWebhookResources(); err != nil { + klog.Errorf("Error deleting webhook resources: %v", err) + } + + if err := b.deleteSecretShareResources(); err != nil { + klog.Errorf("Error deleting secretshare resources: %v", err) + } return nil } -// CreateNsScopeConfigmap creates nss configmap for operators -func (b *Bootstrap) CreateNsScopeConfigmap() error { - cmRes := constant.NamespaceScopeConfigMap - if err := b.renderTemplate(cmRes, b.CSData, false); err != nil { +// deleteWebhookResources deletes resources related to ibm-common-service-webhook +func (b *Bootstrap) deleteWebhookResources() error { + // Delete PodPreset (CR) + if err := b.deleteResource(&unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": "operator.ibm.com/v1alpha1", + "kind": "PodPreset", + }, + }, constant.WebhookServiceName, b.CSData.ServicesNs, "PodPreset"); err != nil { + return err + } + + // Delete ServiceAccount + if err := b.deleteResource(&corev1.ServiceAccount{}, constant.WebhookServiceName, b.CSData.ServicesNs, "ServiceAccount"); err != nil { + return err + } + + // Delete Roles and RoleBindings + if err := b.deleteResource(&rbacv1.Role{}, constant.WebhookServiceName, b.CSData.ServicesNs, "Role"); err != nil { + return err + } + + if err := b.deleteResource(&rbacv1.RoleBinding{}, constant.WebhookServiceName, b.CSData.ServicesNs, "RoleBinding"); err != nil { + return err + } + + if err := b.deleteResource(&rbacv1.ClusterRole{}, constant.WebhookServiceName, "", "ClusterRole"); err != nil { + return err + } + + if err := b.deleteResource(&rbacv1.ClusterRoleBinding{}, "ibm-common-service-webhook-"+b.CSData.ServicesNs, "", "ClusterRoleBinding"); err != nil { + return err + } + + // Delete Deployment + if err := b.deleteResource(&appsv1.Deployment{}, constant.WebhookServiceName, b.CSData.ServicesNs, "Deployment"); err != nil { + return err + } + + return nil +} + +// deleteSecretShareResources deletes resources related to secretshare +func (b *Bootstrap) deleteSecretShareResources() error { + if err := b.deleteResource(&corev1.ServiceAccount{}, constant.Secretshare, b.CSData.ServicesNs, "ServiceAccount"); err != nil { + return err + } + + // Delete SecretShare ClusterRole and ClusterRoleBinding + if err := b.deleteResource(&rbacv1.ClusterRole{}, constant.Secretshare, "", "ClusterRole"); err != nil { + return err + } + + if err := b.deleteResource(&rbacv1.ClusterRoleBinding{}, "secretshare-"+b.CSData.ServicesNs, "", "ClusterRoleBinding"); err != nil { + return err + } + + // Delete SecretShare Operator CR + if err := b.deleteResource(&ssv1.SecretShare{}, constant.MasterCR, b.CSData.ServicesNs, "SecretShare Operator CR"); err != nil { + return err + } + + // Delete SecretShare Operator Deployment + if err := b.deleteResource(&appsv1.Deployment{}, constant.Secretshare, b.CSData.ServicesNs, "Deployment"); err != nil { + return err + } + return nil +} + +func (b *Bootstrap) deleteResource(resource client.Object, name, namespace string, resourceType string) error { + namespacedName := types.NamespacedName{Name: name} + if namespace != "" { + namespacedName.Namespace = namespace + } + + if err := b.Reader.Get(ctx, namespacedName, resource); err != nil { + if !errors.IsNotFound(err) { + return err + } + klog.V(2).Infof("%s %s/%s not found, skipping deletion", resourceType, namespace, name) + return nil + } + + if err := b.Client.Delete(ctx, resource); err != nil { + klog.Errorf("Failed to delete %s %s/%s: %v", resourceType, namespace, name, err) return err } + + klog.Infof("Successfully deleted %s %s/%s", resourceType, namespace, name) return nil } @@ -790,6 +1026,12 @@ func (b *Bootstrap) CreateCsMaps() error { Data: data, } + if !(cm.Labels != nil && cm.Labels[constant.CsManagedLabel] == "true") { + util.EnsureLabelsForConfigMap(cm, map[string]string{ + constant.CsManagedLabel: "true", + }) + } + if err := b.Client.Create(ctx, cm); err != nil { klog.Errorf("could not create common-service-map in kube-public: %v", err) } @@ -871,6 +1113,11 @@ func (b *Bootstrap) GetObjs(objectTemplate string, data interface{}, alwaysUpdat // need this function because common service operator is not in operandRegistry func (b *Bootstrap) UpdateCsOpApproval() error { var commonserviceNS string + if os.Getenv("NO_OLM") == "true" { + klog.V(2).Infof("skip update common-service operator approval mode in no olm environment") + return nil + } + operatorNs, err := util.GetOperatorNamespace() if err != nil { klog.Errorf("Getting operator namespace failed: %v", err) @@ -928,6 +1175,11 @@ func (b *Bootstrap) UpdateCsOpApproval() error { } func (b *Bootstrap) updateApprovalMode() error { + if os.Getenv("NO_OLM") == "true" { + klog.V(2).Infof("skip update ApprovalMode in no olm environment") + return nil + } + opreg := &odlm.OperandRegistry{} opregKey := types.NamespacedName{ Name: "common-service", @@ -960,24 +1212,6 @@ func (b *Bootstrap) updateApprovalMode() error { return nil } -// WaitResourceReady returns true only when the specific resource CRD is created and wait for infinite time -func (b *Bootstrap) WaitResourceReady(apiGroupVersion string, kind string) error { - dc := discovery.NewDiscoveryClientForConfigOrDie(b.Config) - if err := utilwait.PollImmediateInfinite(time.Second*10, func() (done bool, err error) { - exist, err := b.ResourceExists(dc, apiGroupVersion, kind) - if err != nil { - return exist, err - } - if !exist { - klog.V(2).Infof("waiting for resource ready with kind: %s, apiGroupVersion: %s", kind, apiGroupVersion) - } - return exist, nil - }); err != nil { - return err - } - return nil -} - // deployResource deploys the given resource CR func (b *Bootstrap) DeployResource(cr, placeholder string) bool { if err := utilwait.PollImmediateInfinite(time.Second*10, func() (done bool, err error) { @@ -1077,7 +1311,7 @@ func (b *Bootstrap) IsBYOCert() (bool, error) { client.MatchingLabels( map[string]string{"app.kubernetes.io/instance": "cs-ca-certificate"}), } - if certerr := b.Reader.List(ctx, certList, opts...); err != nil { + if certerr := b.Reader.List(ctx, certList, opts...); certerr != nil { return false, certerr } @@ -1092,6 +1326,20 @@ func (b *Bootstrap) IsBYOCert() (bool, error) { } func (b *Bootstrap) DeployCertManagerCR() error { + for _, kind := range constant.CertManagerKinds { + klog.Infof("Checking if resource %s CRD exsits ", kind) + // if the crd is not exist, skip it + exist, err := b.CheckCRD(constant.CertManagerAPIGroupVersionV1, kind) + if err != nil { + klog.Errorf("Failed to check resource with kind: %s, apiGroupVersion: %s", kind, constant.CertManagerAPIGroupVersionV1) + return err + } + if !exist { + klog.Infof("Skiped deploying %s, it is not exist in cluster", kind) + return nil + } + } + klog.V(2).Info("Fetch all the CommonService instances") csReq, err := labels.NewRequirement(constant.CsClonedFromLabel, selection.DoesNotExist, []string{}) if err != nil { @@ -1131,12 +1379,6 @@ func (b *Bootstrap) DeployCertManagerCR() error { } klog.Info("Deploying Cert Manager CRs") - for _, kind := range constant.CertManagerKinds { - // wait for v1 crd ready - if err := b.waitResourceReady(constant.CertManagerAPIGroupVersionV1, kind); err != nil { - klog.Errorf("Failed to wait for resource ready with kind: %s, apiGroupVersion: %s", kind, constant.CertManagerAPIGroupVersionV1) - } - } // will use v1 cert instead of v1alpha cert // delete v1alpha1 cert if it exist var resourceList = []*Resource{ @@ -1192,11 +1434,184 @@ func (b *Bootstrap) DeployCertManagerCR() error { return nil } +// CleanNamespaceScopeResources will delete the v3 NamesapceScopes resources and namespace scope operator +// NamespaceScope resources include common-service, nss-managedby-odlm, nss-odlm-scope, and odlm-scope-managedby-odlm +func (b *Bootstrap) CleanNamespaceScopeResources() error { + + if os.Getenv("NO_OLM") == "true" { + klog.V(2).Infof("skip cleanup namespace scope resources in no olm environment") + return nil + } + + // get namespace-scope ConfigMap in operatorNamespace + nssCmNs, err := util.GetNssCmNs(b.Reader, b.CSData.OperatorNs) + if err != nil { + klog.Errorf("Failed to get %s configmap: %v", constant.NamespaceScopeConfigmapName, err) + return err + } else if nssCmNs == nil { + klog.Infof("The %s configmap is not found in the %s namespace, skip cleaning the NamespaceScope resources", constant.NamespaceScopeConfigmapName, b.CSData.OperatorNs) + return nil + } + + // If the topology is (NOT ALL NS Mode) and (NOT Simple) , return + if b.CSData.WatchNamespaces != "" && len(nssCmNs) > 1 { + klog.Infof("The topology is not All Namespaces Mode or Simple Topology, skip cleaning the NamespaceScope resources") + return nil + } + + if isOpregAPI, err := b.CheckCRD(constant.OpregAPIGroupVersion, constant.OpregKind); err != nil { + klog.Errorf("Failed to check if %s CRD exists: %v", constant.OpregKind, err) + return err + } else if !isOpregAPI { + klog.Infof("%s CRD does not exist, skip checking no-op installMode", constant.OpregKind) + } else if isOpregAPI { + // Get the common-service OperandRegistry + operandRegistry, err := b.GetOperandRegistry(ctx, constant.MasterCR, b.CSData.ServicesNs) + if err != nil { + klog.Errorf("Failed to get common-service OperandRegistry: %v", err) + return err + } else if operandRegistry == nil { + klog.Infof("The common-service OperandRegistry is not found in the %s namespace, skip cleaning the NamespaceScope resources", b.CSData.ServicesNs) + return nil + } + + // Check if there is v4 OperandRegistry exists + if operandRegistry.Annotations != nil { + if v1IsLarger, convertErr := util.CompareVersion("4.0.0", operandRegistry.Annotations["version"]); convertErr != nil { + klog.Errorf("Failed to convert version for OperandRegistry: %v", convertErr) + return convertErr + } else if v1IsLarger { + klog.Infof("The OperandRegistry's version %v is smaller than 4.0.0, skip cleaning the NamespaceScope resources", operandRegistry.Annotations["version"]) + return nil + } + } + // List all requested operators + if operandRegistry.Status.OperatorsStatus != nil { + for operator := range operandRegistry.Status.OperatorsStatus { + // If there is a requested operator's installMode is "no-op", then skip call delete function + for _, op := range operandRegistry.Spec.Operators { + if op.Name == operator && op.InstallMode == "no-op" { + klog.Infof("The operator %s with 'no-op' installMode is still requested in OperandRegistry, skip cleaning the NamespaceScope resources", operator) + return nil + } + } + } + } + } + + // Delete v3 Namespace Scope operator + sub := &olmv1alpha1.Subscription{} + if err := b.Client.Get(ctx, types.NamespacedName{Name: constant.NsSubName, Namespace: b.CSData.ServicesNs}, sub); err == nil { + if strings.HasPrefix(sub.Spec.Channel, "v4.") { + klog.Infof("The %s subscription is in the v4.x channel, skip cleaning up", constant.NsSubName) + return nil + } + + klog.Info("Cleaning NamespaceScope resources in Simple Topology or All Namespaces Mode") + klog.Infof("Uninstall v3 Namespace Scope operator in servicesNamespace %s when the topology is Simple or All Namespaces Mode", b.CSData.ServicesNs) + if err := b.DeleteOperator(constant.NsSubName, b.CSData.ServicesNs); err != nil { + klog.Errorf("Failed to uninstall v3 Namespace Scope operator in servicesNamespace %s", b.CSData.ServicesNs) + return err + } + } else { + if !errors.IsNotFound(err) { + klog.Errorf("Failed to get %s subscription in namespace %s: %v", constant.NsSubName, b.CSData.ServicesNs, err) + return err + } + klog.Infof("The %s subscription is not found in the %s namespace, skip cleaning up", constant.NsSubName, b.CSData.ServicesNs) + } + + // Patch and remove the ownerReference in the namespace-scope configmap if it exist + if nssCm, err := util.GetCmOfNss(b.Reader, b.CSData.OperatorNs); err != nil { + if errors.IsNotFound(err) { + klog.Infof("The %s configmap is not found in the %s namespace, skip patching ownerReference", constant.NamespaceScopeConfigmapName, b.CSData.OperatorNs) + } else { + klog.Errorf("Failed to get %s configmap: %v", constant.NamespaceScopeConfigmapName, err) + return err + } + } else { + if len(nssCm.OwnerReferences) > 0 { + klog.Infof("Remove the ownerReference in the %s configmap", constant.NamespaceScopeConfigmapName) + // Patch and remove the ownerReference in the namespace-scope configmap in data section + originalCm := nssCm.DeepCopy() + nssCm.OwnerReferences = nil + if err := b.Client.Patch(context.TODO(), nssCm, client.MergeFrom(originalCm)); err != nil { + klog.Errorf("Failed to patch and remove the ownerReference in the %s configmap", constant.NamespaceScopeConfigmapName) + return err + } + } + } + + // Delete NamespaceScope CRs and wait for those are deleted exactly, if time is out for deleting the CRs, then proceed to delete the operator + // Check if the NamespaceScope CRD is existent + exist, err := b.CheckCRD(constant.NssAPIVersion, constant.NssKindCR) + if err != nil { + klog.Errorf("Failed to check resource with kind: %s, apiGroupVersion: %s", constant.NssKindCR, constant.NssAPIVersion) + return err + } + if !exist { + klog.Infof("Skiped deleting NamespaceScope CRs, it is not exist in cluster") + return nil + } + + nssCRsList, err := b.ListNssCRs(ctx, b.CSData.ServicesNs) + if len(nssCRsList.Items) > 0 && err == nil { + for _, nssCR := range nssCRsList.Items { + if err := b.Client.Delete(context.TODO(), &nssCR); err != nil { + klog.Errorf("Failed to delete NamespaceScope CR %s: %v", nssCR.Name, err) + } + } + + klog.Infof("Waiting for the NamespaceScope CRs to be deleted in the %s namespace", b.CSData.ServicesNs) + if err := utilwait.PollImmediate(time.Second*5, time.Second*30, func() (done bool, err error) { + nssCRsList, err := b.ListNssCRs(ctx, b.CSData.ServicesNs) + if err != nil { + return false, err + } + if len(nssCRsList.Items) > 0 { + allDeleted := true + for _, nssCR := range nssCRsList.Items { + if nssCR.GetDeletionTimestamp() == nil { + allDeleted = false + break + } + } + if !allDeleted { + // At least one NSS resource doesn't have deletion timestamp set + return false, nil + } + // Deletion timestamp set for all Nss resources + return true, errors.NewResourceExpired("All NSS CRs are ready to be deleted.") + } + // No NSS resources found + return len(nssCRsList.Items) == 0, nil + }); err != nil { + klog.Infof("Patch finalizers to delete the NamespaceScope CRs") + nssCRsList, err := b.ListNssCRs(ctx, b.CSData.ServicesNs) + if err != nil { + return err + } + for _, nssCR := range nssCRsList.Items { + if nssCR.GetDeletionTimestamp() != nil && len(nssCR.ObjectMeta.Finalizers) > 0 { + originalCopy := nssCR.DeepCopy() + if change := apiv3.RemoveFinalizer(&nssCR.ObjectMeta, constant.NssCRFinalizer); change { + if err := b.Client.Patch(context.TODO(), &nssCR, client.MergeFrom(originalCopy)); err != nil { + klog.Errorf("Failed to patch finalizers to delete the NamespaceScope CR %s: %v", nssCR.Name, err) + return err + } + klog.Infof("Rmoved finalizers to delete the NamespaceScope CR %s", nssCR.Name) + } + } + } + } + } + return nil +} + func (b *Bootstrap) Cleanup(operatorNs string, resource *Resource) error { - // check if crd exist - dc := discovery.NewDiscoveryClientForConfigOrDie(b.Config) + // Check if CRD exist APIGroupVersion := resource.Group + "/" + resource.Version - exist, err := b.ResourceExists(dc, APIGroupVersion, resource.Kind) + exist, err := b.CheckCRD(APIGroupVersion, resource.Kind) if err != nil { klog.Errorf("Failed to check resource with kind: %s, apiGroupVersion: %s", resource.Kind, APIGroupVersion) } @@ -1270,6 +1685,19 @@ func (b *Bootstrap) ConfigODLMOperandManagedByOperator(ctx context.Context) erro } } + operatorConfigList := b.ListOperatorConfig(ctx, opts...) + if operatorConfigList != nil { + for _, operatorConfig := range operatorConfigList.Items { + if operatorConfig.Namespace != b.CSData.ServicesNs { + if err := b.Client.Delete(ctx, &operatorConfig); err != nil { + klog.Errorf("Failed to delete idle OperandConfig %s/%s which is managed by CS operator, but not in ServicesNamespace %s", operatorConfig.GetNamespace(), operatorConfig.GetName(), b.CSData.ServicesNs) + return err + } + klog.Infof("Delete idle OperandConfig %s/%s which is managed by CS operator, but not in ServicesNamespace %s", operatorConfig.GetNamespace(), operatorConfig.GetName(), b.CSData.ServicesNs) + } + } + } + return nil } @@ -1335,43 +1763,47 @@ func (b *Bootstrap) ConfigCertManagerOperandManagedByOperator(ctx context.Contex func (b *Bootstrap) PropagateDefaultCR(instance *apiv3.CommonService) error { // Copy Master CR into namespace in WATCH_NAMESPACE list watchNamespaceList := strings.Split(b.CSData.WatchNamespaces, ",") - csLabel := make(map[string]string) - // Copy from the original labels to the target labels - for k, v := range instance.Labels { - csLabel[k] = v - } - csAnnotation := make(map[string]string) - // Copy from the original Annotations to the target Annotations - for k, v := range instance.Annotations { - csAnnotation[k] = v - } - // Exclude CommonService cloned in AllNamespace Mode if len(watchNamespaceList) > 1 { + // Get the unstructured object of the main CommonService CR + mainCsInstance := &unstructured.Unstructured{} + mainCsInstance.SetGroupVersionKind(apiv3.GroupVersion.WithKind("CommonService")) + if err := b.Client.Get(ctx, types.NamespacedName{Name: instance.Name, Namespace: instance.Namespace}, mainCsInstance); err != nil { + return fmt.Errorf("failed to get CommonService CR %s in namespace %s: %v", instance.Name, instance.Namespace, err) + } + csLabel := make(map[string]string) + // Copy from the original labels to the target labels + for k, v := range mainCsInstance.GetLabels() { + csLabel[k] = v + } + csLabel[constant.CsClonedFromLabel] = b.CSData.OperatorNs + + csAnnotation := make(map[string]string) + // Copy from the original Annotations to the target Annotations + for k, v := range mainCsInstance.GetAnnotations() { + csAnnotation[k] = v + } for _, watchNamespace := range watchNamespaceList { - if watchNamespace == instance.Namespace { + if watchNamespace == mainCsInstance.GetNamespace() { continue } - copiedCsInstance := &apiv3.CommonService{ - ObjectMeta: metav1.ObjectMeta{ - Name: constant.MasterCR, - Namespace: watchNamespace, - Labels: csLabel, - Annotations: csAnnotation, - }, - Spec: instance.Spec, - } - util.EnsureLabelsForCsCR(copiedCsInstance, map[string]string{ - constant.CsClonedFromLabel: b.CSData.OperatorNs, - }) + copiedCsInstance := &unstructured.Unstructured{} + copiedCsInstance.SetGroupVersionKind(apiv3.GroupVersion.WithKind("CommonService")) + copiedCsInstance.SetNamespace(watchNamespace) + copiedCsInstance.SetName(constant.MasterCR) + copiedCsInstance.SetLabels(csLabel) + copiedCsInstance.SetAnnotations(csAnnotation) + copiedCsInstance.Object["spec"] = mainCsInstance.Object["spec"] + if err := b.Client.Create(ctx, copiedCsInstance); err != nil { if errors.IsAlreadyExists(err) { csKey := types.NamespacedName{Name: constant.MasterCR, Namespace: watchNamespace} - existingCsInstance := &apiv3.CommonService{} + existingCsInstance := &unstructured.Unstructured{} + existingCsInstance.SetGroupVersionKind(apiv3.GroupVersion.WithKind("CommonService")) if err := b.Client.Get(ctx, csKey, existingCsInstance); err != nil { return fmt.Errorf("failed to get cloned CommonService CR in namespace %s: %v", watchNamespace, err) } - if needUpdate := util.CompareCsCR(copiedCsInstance, existingCsInstance); needUpdate { + if needUpdate := util.CompareObj(copiedCsInstance, existingCsInstance); needUpdate { copiedCsInstance.SetResourceVersion(existingCsInstance.GetResourceVersion()) if err := b.Client.Update(ctx, copiedCsInstance); err != nil { return fmt.Errorf("failed to update cloned CommonService CR in namespace %s: %v", watchNamespace, err) @@ -1409,37 +1841,43 @@ func (b *Bootstrap) PropagateCPPConfig(instance *corev1.ConfigMap) error { // Do not copy ibm-cpp-config in AllNamespace Mode if len(watchNamespaceList) > 1 { - for _, watchNamespace := range watchNamespaceList { - if watchNamespace == instance.Namespace { + for _, ns := range watchNamespaceList { + if ns == instance.Namespace { continue } copiedCPPConfigMap := &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: constant.IBMCPPCONFIG, - Namespace: watchNamespace, + Namespace: ns, + Labels: instance.GetLabels(), }, Data: instance.Data, } if err := b.Client.Create(ctx, copiedCPPConfigMap); err != nil { if errors.IsAlreadyExists(err) { - cmKey := types.NamespacedName{Name: constant.IBMCPPCONFIG, Namespace: watchNamespace} + cmKey := types.NamespacedName{Name: constant.IBMCPPCONFIG, Namespace: ns} existingCM := &corev1.ConfigMap{} - if err := b.Client.Get(ctx, cmKey, existingCM); err != nil { - return fmt.Errorf("failed to get %s ConfigMap in namespace %s: %v", constant.IBMCPPCONFIG, watchNamespace, err) + if err := b.Reader.Get(ctx, cmKey, existingCM); err != nil { + return fmt.Errorf("failed to get %s ConfigMap in namespace %s: %v", constant.IBMCPPCONFIG, ns, err) + } + for k, v := range existingCM.Data { + if _, ok := copiedCPPConfigMap.Data[k]; !ok { + copiedCPPConfigMap.Data[k] = v + } } - if !reflect.DeepEqual(copiedCPPConfigMap.Data, existingCM.Data) { + if !reflect.DeepEqual(copiedCPPConfigMap.Data, existingCM.Data) || !reflect.DeepEqual(copiedCPPConfigMap.Labels, existingCM.Labels) { copiedCPPConfigMap.SetResourceVersion(existingCM.GetResourceVersion()) if err := b.Client.Update(ctx, copiedCPPConfigMap); err != nil { - return fmt.Errorf("failed to update %s ConfigMap in namespace %s: %v", constant.IBMCPPCONFIG, watchNamespace, err) + return fmt.Errorf("failed to update %s ConfigMap in namespace %s: %v", constant.IBMCPPCONFIG, ns, err) } - klog.Infof("Global CPP config %s/%s is updated", watchNamespace, constant.IBMCPPCONFIG) + klog.Infof("Global CPP config %s/%s is updated", ns, constant.IBMCPPCONFIG) } } else { - return fmt.Errorf("failed to create cloned %s ConfigMap in namespace %s: %v", constant.IBMCPPCONFIG, watchNamespace, err) + return fmt.Errorf("failed to create cloned %s ConfigMap in namespace %s: %v", constant.IBMCPPCONFIG, ns, err) } } else { - klog.Infof("Global CPP config %s/%s is propagated to namespace %s", b.CSData.ServicesNs, constant.IBMCPPCONFIG, watchNamespace) + klog.Infof("Global CPP config %s/%s is propagated to namespace %s", b.CSData.ServicesNs, constant.IBMCPPCONFIG, ns) } } } @@ -1487,3 +1925,283 @@ func (b *Bootstrap) CleanupWebhookResources() error { } return nil } + +func (b *Bootstrap) UpdateResourceLabel(instance *apiv3.CommonService) error { + labelsMap := make(map[string]string) + // Fetch all the CommonService instances + csReq, err := labels.NewRequirement(constant.CsClonedFromLabel, selection.DoesNotExist, []string{}) + if err != nil { + return err + } + csObjectList := &apiv3.CommonServiceList{} + if err := b.Client.List(ctx, csObjectList, &client.ListOptions{ + LabelSelector: labels.NewSelector().Add(*csReq), + }); err != nil { + return err + } + csObjectList.Items = append(csObjectList.Items, *instance) + + // get spec.labels in the spec + for _, cs := range csObjectList.Items { + labels := cs.Spec.Labels + for key, val := range labels { + (labelsMap)[key] = val + } + } + + if len(labelsMap) == 0 { + return nil + } + + // Update labels in the CommonService CRs + klog.Infof("Update labels for resources managed by CommonService CR %s/%s", instance.GetNamespace(), instance.GetName()) + for _, cs := range csObjectList.Items { + util.EnsureLabelsForCsCR(&cs, labelsMap) + if err := b.Client.Update(context.TODO(), &cs); err != nil { + klog.Errorf("Failed to update label in commonservice cr:%v, %v", cs.GetName(), err) + return err + } + } + + // update labels in the configmap + cmNames := []string{"common-services-maps", "namespace-scope"} + cmList := &corev1.ConfigMapList{} + for _, cmName := range cmNames { + cm := &corev1.ConfigMap{} + if err := b.Client.Get(context.TODO(), types.NamespacedName{Name: cmName, Namespace: b.CSData.ServicesNs}, cm); err != nil && !errors.IsNotFound(err) { + return err + } else if errors.IsNotFound(err) { + klog.V(3).Infof("configmap %s is not found in namespace: %s", cmName, b.CSData.ServicesNs) + } + cmList.Items = append(cmList.Items, *cm) + } + cmUnstructedList, err := util.ObjectListToNewUnstructuredList(cmList) + if err != nil { + return err + } + if err := b.UpdateResourceWithLabel(cmUnstructedList, labelsMap); err != nil { + return err + } + + // Update labels in the OperandConfig and OperandRegistry + opconfigList := &odlm.OperandConfigList{} + opcon := &odlm.OperandConfig{} + if err := b.Client.Get(context.TODO(), types.NamespacedName{Name: "common-service", Namespace: b.CSData.ServicesNs}, opcon); err != nil && !errors.IsNotFound(err) { + return err + } else if errors.IsNotFound(err) { + klog.V(3).Infof("OperandConfig common-service is not found in namespace: %s", b.CSData.ServicesNs) + } + opconfigList.Items = append(opconfigList.Items, *opcon) + opconUnstructedList, err := util.ObjectListToNewUnstructuredList(opconfigList) + if err != nil { + return err + } + if err := b.UpdateResourceWithLabel(opconUnstructedList, labelsMap); err != nil { + return err + } + opregList := &odlm.OperandRegistryList{} + opreg := &odlm.OperandRegistry{} + if err := b.Client.Get(context.TODO(), types.NamespacedName{Name: "common-service", Namespace: b.CSData.ServicesNs}, opreg); err != nil && !errors.IsNotFound(err) { + return err + } else if errors.IsNotFound(err) { + klog.V(3).Infof("OperandRegistry common-service is not found in namespace: %s", b.CSData.ServicesNs) + } + opregList.Items = append(opregList.Items, *opreg) + opregUnstructedList, err := util.ObjectListToNewUnstructuredList(opregList) + if err != nil { + return err + } + if err := b.UpdateResourceWithLabel(opregUnstructedList, labelsMap); err != nil { + return err + } + + // update labels in the Issuer + issuerList := &certmanagerv1.IssuerList{} + issuerNames := []string{"cs-ss-issuer", "cs-ca-issuer"} + for _, issuerName := range issuerNames { + issuer := &certmanagerv1.Issuer{} + if err := b.Client.Get(context.TODO(), types.NamespacedName{Name: issuerName, Namespace: b.CSData.ServicesNs}, issuer); err != nil && !errors.IsNotFound(err) { + return err + } else if errors.IsNotFound(err) { + klog.V(3).Infof("Issuer %s is not found in namespace: %s", issuerName, b.CSData.ServicesNs) + } + issuerList.Items = append(issuerList.Items, *issuer) + } + issuerUnstructedList, err := util.ObjectListToNewUnstructuredList(issuerList) + if err != nil { + return err + } + + if err := b.UpdateResourceWithLabel(issuerUnstructedList, labelsMap); err != nil { + return err + } + + // update labels in the Certificate + certList := &certmanagerv1.CertificateList{} + cert := &certmanagerv1.Certificate{} + if err := b.Client.Get(context.TODO(), types.NamespacedName{Name: "cs-ca-certificate", Namespace: b.CSData.ServicesNs}, cert); err != nil && !errors.IsNotFound(err) { + return err + } else if errors.IsNotFound(err) { + klog.V(3).Infof("certificate cs-ca-certificate is not found in namespace: %s", b.CSData.ServicesNs) + } + certList.Items = append(certList.Items, *cert) + certUnstructedList, err := util.ObjectListToNewUnstructuredList(certList) + if err != nil { + return err + } + if err := b.UpdateResourceWithLabel(certUnstructedList, labelsMap); err != nil { + return err + } + + return nil +} + +func (b *Bootstrap) UpdateResourceWithLabel(resources *unstructured.UnstructuredList, labels map[string]string) error { + for _, resource := range resources.Items { + util.EnsureLabels(&resource, labels) + klog.Infof("Updating labels in %s %s/%s", resource.GetKind(), resource.GetNamespace(), resource.GetName()) + if err := b.UpdateObject(&resource); err != nil { + klog.Errorf("Failed to update label in kind:%v namespace/name:%v/%v, %v", resource.GetKind(), resource.GetNamespace(), resource.GetName(), err) + return err + } + } + return nil +} + +func (b *Bootstrap) UpdateEDBUserManaged() error { + operatorNamespace, err := util.GetOperatorNamespace() + if err != nil { + return err + } + defaultCsCR := &apiv3.CommonService{} + csName := "common-service" + if err := b.Client.Get(context.TODO(), types.NamespacedName{Name: csName, Namespace: operatorNamespace}, defaultCsCR); err != nil { + return err + } + servicesNamespace := string(defaultCsCR.Spec.ServicesNamespace) + + config := &corev1.ConfigMap{} + if err := b.Client.Get(context.TODO(), types.NamespacedName{Name: constant.IBMCPPCONFIG, Namespace: servicesNamespace}, config); err != nil { + if errors.IsNotFound(err) { + return nil + } + return err + } + userManaged := config.Data["EDB_USER_MANAGED_OPERATOR_ENABLED"] + if userManaged != "true" { + unsetEDBUserManaged(defaultCsCR) + } else { + setEDBUserManaged(defaultCsCR) + } + + if err := b.Client.Update(context.TODO(), defaultCsCR); err != nil { + return err + } + return nil +} + +func unsetEDBUserManaged(instance *apiv3.CommonService) { + if instance.Spec.OperatorConfigs == nil { + return + } + for i := range instance.Spec.OperatorConfigs { + i := i + if instance.Spec.OperatorConfigs[i].Name == "internal-use-only-edb" { + instance.Spec.OperatorConfigs[i].UserManaged = false + } + } +} + +func setEDBUserManaged(instance *apiv3.CommonService) { + if instance.Spec.OperatorConfigs == nil { + instance.Spec.OperatorConfigs = []apiv3.OperatorConfig{} + } + isExist := false + for i := range instance.Spec.OperatorConfigs { + i := i + if instance.Spec.OperatorConfigs[i].Name == "internal-use-only-edb" { + instance.Spec.OperatorConfigs[i].UserManaged = true + isExist = true + } + } + if !isExist { + instance.Spec.OperatorConfigs = append(instance.Spec.OperatorConfigs, apiv3.OperatorConfig{Name: "internal-use-only-edb", UserManaged: true}) + } +} + +func (b *Bootstrap) waitOperatorCSV(subName, packageManifest, operatorNs string) (bool, error) { + var isWaiting bool + // Wait for the operator CSV to be installed + klog.Infof("Waiting for the operator CSV with packageManifest %s in namespace %s to be installed", packageManifest, operatorNs) + if err := utilwait.PollImmediate(time.Second*5, time.Minute*5, func() (done bool, err error) { + installed, err := b.checkOperatorCSV(subName, packageManifest, operatorNs) + if err != nil { + return false, err + } else if !installed { + klog.Infof("The operator CSV with packageManifest %s in namespace %s is not installed yet", packageManifest, operatorNs) + isWaiting = true + } + return installed, nil + }); err != nil { + return isWaiting, fmt.Errorf("failed to wait for the operator CSV to be installed: %v", err) + } + return isWaiting, nil +} + +func (b *Bootstrap) checkOperatorCSV(subName, packageManifest, operatorNs string) (bool, error) { + if os.Getenv("NO_OLM") == "true" { + klog.V(2).Infof("skip checking operator CSV in no olm environment") + return false, nil + } + // Get the subscription by name and namespace + sub := &olmv1alpha1.Subscription{} + if err := b.Reader.Get(context.TODO(), types.NamespacedName{Name: subName, Namespace: operatorNs}, sub); err != nil { + klog.Warningf("Failed to get Subscription %s in namespace %s: %v, list subscription by packageManifest and operatorNs", subName, operatorNs, err) + // List the subscription by packageManifest and operatorNs + // The subscription contain label "operators.coreos.com/.: ''" + subList := &olmv1alpha1.SubscriptionList{} + labelKey := util.GetFirstNCharacter(packageManifest+"."+operatorNs, 63) + if err := b.Reader.List(context.TODO(), subList, &client.ListOptions{ + LabelSelector: labels.SelectorFromSet(labels.Set{ + "operators.coreos.com/" + labelKey: "", + }), + Namespace: operatorNs, + }); err != nil { + klog.Errorf("Failed to list Subscription by packageManifest %s and operatorNs %s: %v", packageManifest, operatorNs, err) + return false, err + } + + // Check if multiple subscriptions exist + if len(subList.Items) > 1 { + return false, fmt.Errorf("multiple subscriptions found by packageManifest %s and operatorNs %s", packageManifest, operatorNs) + } else if len(subList.Items) == 0 { + return false, fmt.Errorf("no subscription found by packageManifest %s and operatorNs %s", packageManifest, operatorNs) + } + sub = &subList.Items[0] + } + + // Get the channel in the subscription .spec.channel, and check if it is semver + channel := sub.Spec.Channel + if !semver.IsValid(channel) { + klog.Warningf("channel %s is not a semver for operator with packageManifest %s and operatorNs %s", channel, packageManifest, operatorNs) + return false, nil + } + + // Get the CSV from subscription .status.installedCSV + installedCSV := sub.Status.InstalledCSV + var installedVersion string + if installedCSV != "" { + // installedVersion is the version after the first dot in installedCSV + // For example, version is v4.3.1 for operand-deployment-lifecycle-manager.v4.3.1 + installedVersion = installedCSV[strings.IndexByte(installedCSV, '.')+1:] + } + + // 0 if channel == installedVersion - v4.3 == v4.3.0 + // -1 if channel < installedVersion - v4.3 < v4.3.1 + // +1 if channel > installedVersion - v4.3 > v4.2.0 + if semver.Compare(channel, installedVersion) > 0 { + return false, nil + } + + return true, nil +} diff --git a/controllers/bootstrap/init_test.go b/controllers/bootstrap/init_test.go new file mode 100644 index 000000000..118d53677 --- /dev/null +++ b/controllers/bootstrap/init_test.go @@ -0,0 +1,243 @@ +// +// Copyright 2022 IBM Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package bootstrap + +import ( + "context" + "fmt" + "testing" + "time" + + olmv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1" + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/kubernetes/scheme" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/fake" +) + +func init() { + // Add the v1alpha1 version of the operators.coreos.com API to the scheme + _ = olmv1alpha1.AddToScheme(scheme.Scheme) +} + +func TestCheckOperatorCSV(t *testing.T) { + // Create a fake client + fakeClient := fake.NewClientBuilder().Build() + + // Create a Bootstrap instance + bootstrap := &Bootstrap{ + Client: fakeClient, + } + + // Define the packageManifest and operatorNs + packageManifest := "ibm-common-service-operator" + operatorNs := "cpfs-operator-ns" + + // Create a SubscriptionList with a single item + subList := &olmv1alpha1.SubscriptionList{ + Items: []olmv1alpha1.Subscription{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "subscription-1", + Namespace: operatorNs, + Labels: map[string]string{ + "operators.coreos.com/" + packageManifest + "." + operatorNs: "", + }, + }, + Spec: &olmv1alpha1.SubscriptionSpec{ + Channel: "v1.0", + }, + Status: olmv1alpha1.SubscriptionStatus{ + InstalledCSV: "ibm-common-service-operator.v1.0.0", + }, + }, + }, + } + + var err error + for _, item := range subList.Items { + err = fakeClient.Create(context.TODO(), &item) + assert.NoError(t, err) + } + + // Test case 1: Single subscription found with valid semver + result, err := bootstrap.checkOperatorCSV("subscription-1", packageManifest, operatorNs) + assert.True(t, result) + assert.NoError(t, err) + + // Test case 2: Multiple subscriptions found and not subscription name matched + err = fakeClient.Create(context.TODO(), &olmv1alpha1.Subscription{ + ObjectMeta: metav1.ObjectMeta{ + Name: "subscription-2", + Namespace: operatorNs, + Labels: map[string]string{ + "operators.coreos.com/" + packageManifest + "." + operatorNs: "", + }, + }, + Spec: &olmv1alpha1.SubscriptionSpec{ + Channel: "v2.0", + }, + Status: olmv1alpha1.SubscriptionStatus{ + InstalledCSV: "ibm-common-service-operator.v2.0.0", + }, + }) + assert.NoError(t, err) + + result, err = bootstrap.checkOperatorCSV("subscription-non-match", packageManifest, operatorNs) + assert.False(t, result) + assert.EqualError(t, err, fmt.Sprintf("multiple subscriptions found by packageManifest %s and operatorNs %s", packageManifest, operatorNs)) + + // Test case 3: No subscription found + err = fakeClient.DeleteAllOf(context.TODO(), &unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": "operators.coreos.com/v1alpha1", + "kind": "Subscription", + }, + }, &client.DeleteAllOfOptions{ + ListOptions: client.ListOptions{ + Namespace: operatorNs, + }, + }) + assert.NoError(t, err) + + result, err = bootstrap.checkOperatorCSV("subscription-1", packageManifest, operatorNs) + assert.False(t, result) + assert.EqualError(t, err, fmt.Sprintf("no subscription found by packageManifest %s and operatorNs %s", packageManifest, operatorNs)) + + // Test case 4: Invalid semver in channel + err = fakeClient.Create(context.TODO(), &olmv1alpha1.Subscription{ + ObjectMeta: metav1.ObjectMeta{ + Name: "subscription-3", + Namespace: operatorNs, + Labels: map[string]string{ + "operators.coreos.com/" + packageManifest + "." + operatorNs: "", + }, + }, + Spec: &olmv1alpha1.SubscriptionSpec{ + Channel: "invalid-semver", + }, + Status: olmv1alpha1.SubscriptionStatus{ + InstalledCSV: "ibm-common-service-operator.v1.0.0", + }, + }) + assert.NoError(t, err) + + result, err = bootstrap.checkOperatorCSV("subscription-3", packageManifest, operatorNs) + assert.False(t, result) + assert.NoError(t, err) + + // Test case 5: Small semver in channel + // InstalledCSV: "ibm-common-service-operator.v1.0.0", Channel: "v0.1" + subscription := &olmv1alpha1.Subscription{} + err = fakeClient.Get(context.TODO(), types.NamespacedName{Name: "subscription-3", Namespace: "cpfs-operator-ns"}, subscription) + assert.NoError(t, err) + + subscription.Spec.Channel = "v0.1" + err = fakeClient.Update(context.TODO(), subscription) + assert.NoError(t, err) + + result, err = bootstrap.checkOperatorCSV("subscription-3", packageManifest, operatorNs) + assert.True(t, result) + assert.NoError(t, err) + + // Test case 6: Large semver in channel + // InstalledCSV: "ibm-common-service-operator.v1.0.0", Channel: "v1.1" + subscription = &olmv1alpha1.Subscription{} + err = fakeClient.Get(context.TODO(), types.NamespacedName{Name: "subscription-3", Namespace: "cpfs-operator-ns"}, subscription) + assert.NoError(t, err) + + subscription.Spec.Channel = "v1.1" + err = fakeClient.Update(context.TODO(), subscription) + assert.NoError(t, err) + + result, err = bootstrap.checkOperatorCSV("subscription-3", packageManifest, operatorNs) + assert.False(t, result) + assert.NoError(t, err) + + // Test case 7: same semver in channel and installedCSV + // InstalledCSV: "ibm-common-service-operator.v1.0.0", Channel: "v1.0" + subscription = &olmv1alpha1.Subscription{} + err = fakeClient.Get(context.TODO(), types.NamespacedName{Name: "subscription-3", Namespace: "cpfs-operator-ns"}, subscription) + assert.NoError(t, err) + + subscription.Spec.Channel = "v1.0" + err = fakeClient.Update(context.TODO(), subscription) + assert.NoError(t, err) + + result, err = bootstrap.checkOperatorCSV("subscription-3", packageManifest, operatorNs) + assert.True(t, result) + assert.NoError(t, err) + +} + +func TestWaitOperatorCSV(t *testing.T) { + // Create a fake client + fakeClient := fake.NewClientBuilder().Build() + + // Create a Bootstrap instance + bootstrap := &Bootstrap{ + Client: fakeClient, + } + + // Define the packageManifest and operatorNs + packageManifest := "ibm-common-service-operator" + operatorNs := "cpfs-operator-ns" + + // Test case 1: Operator CSV is not installed yet + err := fakeClient.Create(context.TODO(), &olmv1alpha1.Subscription{ + ObjectMeta: metav1.ObjectMeta{ + Name: "subscription-1", + Namespace: operatorNs, + Labels: map[string]string{ + "operators.coreos.com/" + packageManifest + "." + operatorNs: "", + }, + }, + Spec: &olmv1alpha1.SubscriptionSpec{ + Channel: "v1.2", + }, + Status: olmv1alpha1.SubscriptionStatus{ + InstalledCSV: "ibm-common-service-operator.v1.0.0", + }, + }) + assert.NoError(t, err) + + // additional go routine to update the subscription status + go func() { + // sleep for 3 seconds to simulate the operator CSV installation + <-time.After(3 * time.Second) + + subscription := &olmv1alpha1.Subscription{} + err := fakeClient.Get(context.TODO(), types.NamespacedName{Name: "subscription-1", Namespace: "cpfs-operator-ns"}, subscription) + assert.NoError(t, err) + + subscription.Status.InstalledCSV = "ibm-common-service-operator.v1.2.0" + err = fakeClient.Update(context.TODO(), subscription) + assert.NoError(t, err) + }() + + isWaiting, err := bootstrap.waitOperatorCSV("subscription-1", packageManifest, operatorNs) + assert.True(t, isWaiting) + assert.NoError(t, err) + + // Test case 2: Operator CSV is already installed + isWaiting, err = bootstrap.waitOperatorCSV("subscription-1", packageManifest, operatorNs) + assert.False(t, isWaiting) + assert.NoError(t, err) +} diff --git a/controllers/cert-manager/certificaterefresh_controller.go b/controllers/cert-manager/certificaterefresh_controller.go index d668cd363..806b96405 100644 --- a/controllers/cert-manager/certificaterefresh_controller.go +++ b/controllers/cert-manager/certificaterefresh_controller.go @@ -32,7 +32,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/source" certmanagerv1 "github.com/ibm/ibm-cert-manager-operator/apis/cert-manager/v1" - res "github.com/ibm/ibm-cert-manager-operator/controllers/resources" + + "github.com/IBM/ibm-common-service-operator/v4/controllers/constant" ) var logd = log.Log.WithName("controller_certificaterefresh") @@ -78,7 +79,7 @@ func (r *CertificateRefreshReconciler) Reconcile(ctx context.Context, req ctrl.R foundCA := false // check this secret has refresh label or not // if this secret has refresh label - if secret.GetLabels()[res.RefreshCALabel] == "true" { + if secret.GetLabels()[constant.RefreshCALabel] == "true" { foundCA = true } else { // Get the certificate by this secret in the same namespace @@ -95,7 +96,7 @@ func (r *CertificateRefreshReconciler) Reconcile(ctx context.Context, req ctrl.R // if we found this certificate in the same namespace if foundCert { // check this certificate has refresh label or not - if cert.Labels[res.RefreshCALabel] == "true" { + if cert.Labels[constant.RefreshCALabel] == "true" { foundCA = true } } @@ -228,7 +229,7 @@ func (r *CertificateRefreshReconciler) findLeafSecrets(v1Certs []certmanagerv1.C // SetupWithManager sets up the controller with the Manager. func (r *CertificateRefreshReconciler) SetupWithManager(mgr ctrl.Manager) error { - klog.Infof("Set up") + klog.V(2).Infof("Set up") // Create a new controller c, err := controller.New("certificaterefresh-controller", mgr, controller.Options{Reconciler: r}) diff --git a/controllers/cert-manager/podrefresh_controller.go b/controllers/cert-manager/podrefresh_controller.go index 74757f052..3cf89e330 100644 --- a/controllers/cert-manager/podrefresh_controller.go +++ b/controllers/cert-manager/podrefresh_controller.go @@ -149,7 +149,7 @@ NEXT_DEPLOYMENT: } restartedTime, err := time.Parse("2006-1-2.150405", labelTime) if err != nil { - return deploymentsToUpdate, fmt.Errorf("error parsing time-restarted: %v", err) + return deploymentsToUpdate, fmt.Errorf("error parsing time-restarted for deployment: %v", err) } if restartedTime.After(lastUpdatedTime) { continue @@ -198,9 +198,13 @@ NEXT_STATEFULSET: if err != nil { return statefulsetsToUpdate, fmt.Errorf("error parsing NotAfter time: %v", err) } - restartedTime, err := time.Parse("2006-1-2.150405", statefulset.ObjectMeta.Labels[restartLabel]) + labelTime := statefulset.ObjectMeta.Labels[restartLabel] + if t := strings.Split(labelTime, "."); len(t[len(t)-1]) == 4 { + labelTime = labelTime + string("00") + } + restartedTime, err := time.Parse("2006-1-2.150405", labelTime) if err != nil { - return statefulsetsToUpdate, fmt.Errorf("error parsing time-restarted: %v", err) + return statefulsetsToUpdate, fmt.Errorf("error parsing time-restarted for statefulSet: %v", err) } if restartedTime.After(lastUpdatedTime) { continue @@ -248,9 +252,13 @@ NEXT_DAEMONSET: if err != nil { return daemonsetsToUpdate, fmt.Errorf("error parsing NotAfter time: %v", err) } - restartedTime, err := time.Parse("2006-1-2.150405", daemonset.ObjectMeta.Labels[restartLabel]) + labelTime := daemonset.ObjectMeta.Labels[restartLabel] + if t := strings.Split(labelTime, "."); len(t[len(t)-1]) == 4 { + labelTime = labelTime + string("00") + } + restartedTime, err := time.Parse("2006-1-2.150405", labelTime) if err != nil { - return daemonsetsToUpdate, fmt.Errorf("error parsing time-restarted: %v", err) + return daemonsetsToUpdate, fmt.Errorf("error parsing time-restarted for daemonSet: %v", err) } if restartedTime.After(lastUpdatedTime) { continue @@ -340,7 +348,7 @@ func (r *PodRefreshReconciler) updateDaemonSetAnnotations(daemonsetsToUpdate []a // SetupWithManager sets up the controller with the Manager. func (r *PodRefreshReconciler) SetupWithManager(mgr ctrl.Manager) error { - klog.Infof("Set up") + klog.V(2).Infof("Set up") // Create a new controller c, err := controller.New("podrefresh-controller", mgr, controller.Options{Reconciler: r}) diff --git a/controllers/cert-manager/v1_add_label_controller.go b/controllers/cert-manager/v1_add_label_controller.go index a20a092a1..373d7e7f5 100644 --- a/controllers/cert-manager/v1_add_label_controller.go +++ b/controllers/cert-manager/v1_add_label_controller.go @@ -32,7 +32,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/source" certmanagerv1 "github.com/ibm/ibm-cert-manager-operator/apis/cert-manager/v1" - res "github.com/ibm/ibm-cert-manager-operator/controllers/resources" + + "github.com/IBM/ibm-common-service-operator/v4/controllers/constant" ) // V1AddLabelReconciler reconciles a Certificate object @@ -83,8 +84,8 @@ func (r *V1AddLabelReconciler) Reconcile(ctx context.Context, req ctrl.Request) if oldLabelsMap == nil { oldLabelsMap = make(map[string]string) } - if _, ok := oldLabelsMap[res.SecretWatchLabel]; !ok { - oldLabelsMap[res.SecretWatchLabel] = "" + if _, ok := oldLabelsMap[constant.SecretWatchLabel]; !ok { + oldLabelsMap[constant.SecretWatchLabel] = "" secretInstance.SetLabels(oldLabelsMap) } @@ -111,7 +112,7 @@ func (r *V1AddLabelReconciler) updateSecret(secret *corev1.Secret) error { // SetupWithManager sets up the controller with the Manager. func (r *V1AddLabelReconciler) SetupWithManager(mgr ctrl.Manager) error { - klog.Infof("Set up") + klog.V(2).Infof("Set up") // Create a new controller c, err := controller.New("addlabel-controller", mgr, controller.Options{Reconciler: r}) diff --git a/controllers/common/util.go b/controllers/common/util.go index c80b19026..18ce184f9 100644 --- a/controllers/common/util.go +++ b/controllers/common/util.go @@ -19,6 +19,7 @@ package common import ( "bytes" "context" + "encoding/base64" "fmt" "io" "os" @@ -46,9 +47,10 @@ import ( "k8s.io/klog" "sigs.k8s.io/controller-runtime/pkg/client" - apiv3 "github.com/IBM/ibm-common-service-operator/api/v3" - "github.com/IBM/ibm-common-service-operator/controllers/constant" - nssv1 "github.com/IBM/ibm-namespace-scope-operator/api/v1" + 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 { @@ -492,7 +494,13 @@ func GetControlNs(r client.Reader) (controlNs string) { return } +// could have issue func GetApprovalModeinNs(r client.Reader, ns string) (approvalMode string, err error) { + // set approval mode to empty in non-olm environment + if os.Getenv("NO_OLM") == "true" { + klog.V(2).Infof("set approval mode to empty in no olm environment") + return "", nil + } approvalMode = string(olmv1alpha1.ApprovalAutomatic) subList := &olmv1alpha1.SubscriptionList{} if err := r.List(context.TODO(), subList, &client.ListOptions{Namespace: ns}); err != nil { @@ -509,6 +517,10 @@ func GetApprovalModeinNs(r client.Reader, ns string) (approvalMode string, err e // GetCatalogSource gets CatalogSource will be used by operators func GetCatalogSource(packageName, ns string, r client.Reader) (CatalogSourceName, CatalogSourceNS string) { + if os.Getenv("NO_OLM") == "true" { + klog.V(2).Infof("set catalogsource name and namespace to empty in no olm environment") + return "", "" + } subList := &olmv1alpha1.SubscriptionList{} if err := r.List(context.TODO(), subList, &client.ListOptions{Namespace: ns}); err != nil { klog.Info(err) @@ -675,6 +687,16 @@ func EnsureLabelsForConfigMap(cm *corev1.ConfigMap, labels map[string]string) { } } +// EnsureLabels ensures that the specifc resource has the certain labels +func EnsureLabels(resource *unstructured.Unstructured, labels map[string]string) { + if resource.Object["metadata"].(map[string]interface{})["labels"] == nil { + resource.Object["metadata"].(map[string]interface{})["labels"] = make(map[string]string) + } + for k, v := range labels { + resource.Object["metadata"].(map[string]interface{})["labels"].(map[string]string)[k] = v + } +} + // GetRequestNs gets requested-from-namespace of map-to-common-service-namespace func GetRequestNs(r client.Reader) (requestNs []string) { operatorNs, err := GetOperatorNamespace() @@ -712,45 +734,44 @@ func GetRequestNs(r client.Reader) (requestNs []string) { } // GetNssCmNs gets namespaces from namespace-scope ConfigMap -func GetNssCmNs(r client.Reader, cpfsNamespace string) (nssCmNs []string) { - nssConfigMap := GetCmOfNss(r, cpfsNamespace) - +func GetNssCmNs(r client.Reader, cpfsNamespace string) ([]string, error) { + nssConfigMap, err := GetCmOfNss(r, cpfsNamespace) + if err != nil { + if errors.IsNotFound(err) { + return nil, nil + } + return nil, err + } nssNsMems, ok := nssConfigMap.Data["namespaces"] if !ok { klog.Infof("There is no namespace in configmap %v/%v", cpfsNamespace, constant.NamespaceScopeConfigmapName) - return + return nil, nil } - nssCmNs = strings.Split(nssNsMems, ",") + nssCmNs := strings.Split(nssNsMems, ",") - return nssCmNs + return nssCmNs, nil } // GetCmOfNss gets ConfigMap of Namespace-scope -func GetCmOfNss(r client.Reader, operatorNs string) *corev1.ConfigMap { +func GetCmOfNss(r client.Reader, operatorNs string) (*corev1.ConfigMap, error) { cmName := constant.NamespaceScopeConfigmapName cmNs := operatorNs nssConfigmap := &corev1.ConfigMap{} - for { - if err := utilwait.PollImmediateInfinite(time.Second*10, func() (done bool, err error) { - err = r.Get(context.TODO(), types.NamespacedName{Name: cmName, Namespace: cmNs}, nssConfigmap) - if err != nil { - if errors.IsNotFound(err) { - klog.Infof("waiting for configmap %v/%v", operatorNs, constant.NamespaceScopeConfigmapName) - return false, nil - } - return false, err + if err := utilwait.PollImmediate(time.Second*5, time.Second*30, func() (done bool, err error) { + err = r.Get(context.TODO(), types.NamespacedName{Name: cmName, Namespace: cmNs}, nssConfigmap) + if err != nil { + if errors.IsNotFound(err) { + klog.Infof("waiting for configmap %v/%v", operatorNs, constant.NamespaceScopeConfigmapName) } - return true, nil - }); err == nil { - break - } else { - klog.Errorf("Failed to get configmap %v/%v: %v, retry in 10 seconds", operatorNs, constant.NamespaceScopeConfigmapName, err) - time.Sleep(10 * time.Second) + return false, err } + return true, nil + }); err != nil { + return nil, err } - return nssConfigmap + return nssConfigmap, nil } func GetResourcesDynamically(ctx context.Context, dynamic dynamic.Interface, group string, version string, resource string) ( @@ -793,6 +814,104 @@ func EnsureLabelsForCsCR(cs *apiv3.CommonService, labels map[string]string) { } } -func CompareCsCR(csCR *apiv3.CommonService, existingCsCR *apiv3.CommonService) (needUpdate bool) { - return !equality.Semantic.DeepEqual(csCR.GetLabels(), existingCsCR.GetLabels()) || !equality.Semantic.DeepEqual(csCR.GetAnnotations(), existingCsCR.GetAnnotations()) || !equality.Semantic.DeepEqual(csCR.Spec, existingCsCR.Spec) +func CompareObj(newObj *unstructured.Unstructured, existingObj *unstructured.Unstructured) (needUpdate bool) { + return !equality.Semantic.DeepEqual(newObj.GetLabels(), existingObj.GetLabels()) || !equality.Semantic.DeepEqual(newObj.GetAnnotations(), existingObj.GetAnnotations()) || !equality.Semantic.DeepEqual(newObj.Object["spec"], existingObj.Object["spec"]) +} + +// ReadFile reads file from local path +func ReadFile(path string) ([]byte, error) { + file, err := os.Open(path) + if err != nil { + klog.Error(err) + return nil, err + } + defer file.Close() + + fileInfo, err := file.Stat() + if err != nil { + klog.Error(err) + return nil, err + } + + fileSize := fileInfo.Size() + buffer := make([]byte, fileSize) + + _, err = file.Read(buffer) + if err != nil { + klog.Error(err) + return nil, err + } + + return buffer, nil +} + +// EncodeBase64 encodes data to base64 string +func EncodeBase64(data []byte) string { + return base64.StdEncoding.EncodeToString(data) +} + +// SanitizeData keep the key-value pair in the map if the value fulfill the valueType and requirement +func SanitizeData(data interface{}, valueType string, isEmpty bool) interface{} { + // check data type + switch data.(type) { + case map[string]interface{}: + sanitizedData := make(map[string]interface{}) + for key, value := range data.(map[string]interface{}) { + switch valueType { + case "string": + if v, ok := value.(string); ok && (isEmpty || v != "") { + sanitizedData[key] = v + } + case "bool": + if v, ok := value.(bool); ok { + sanitizedData[key] = v + } + case "int": + if v, ok := value.(int); ok { + sanitizedData[key] = v + } + case "float64": + if v, ok := value.(float64); ok { + sanitizedData[key] = v + } + } + } + return sanitizedData + default: + klog.Errorf("data type is not map[string]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 "" +} + +func GetFirstNCharacter(str string, n int) string { + if n >= len(str) { + return str + } + return str[:n] } diff --git a/controllers/common/util_test.go b/controllers/common/util_test.go new file mode 100644 index 000000000..13b1a7293 --- /dev/null +++ b/controllers/common/util_test.go @@ -0,0 +1,72 @@ +// +// Copyright 2022 IBM Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package common + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestSanitizeData(t *testing.T) { + // Test case 1: valueType is "string" and isEmpty is true + data1 := map[string]interface{}{ + "key1": "value1", + "key2": "", + "key3": 123, + } + expectedResult1 := map[string]interface{}{ + "key1": "value1", + "key2": "", + } + result1 := SanitizeData(data1, "string", true) + assert.Equal(t, expectedResult1, result1) + + // Test case 2: valueType is "string" and isEmpty is false + data2 := map[string]interface{}{ + "key1": "value1", + "key2": "", + "key3": 123, + } + expectedResult2 := map[string]interface{}{ + "key1": "value1", + } + result2 := SanitizeData(data2, "string", false) + assert.Equal(t, expectedResult2, result2) + + // Test case 3: valueType is "bool" + data3 := map[string]interface{}{ + "key1": "value1", + "key2": true, + "key3": 123, + } + expectedResult3 := map[string]interface{}{ + "key2": true, + } + result3 := SanitizeData(data3, "bool", false) + assert.Equal(t, expectedResult3, result3) + + // Test case 4: valueType is not "string" or "bool" + data4 := map[string]interface{}{ + "key1": "value1", + "key2": true, + "key3": 123, + } + expectedResult4 := map[string]interface{}{} + result4 := SanitizeData(data4, "other", false) + assert.Equal(t, expectedResult4, result4) +} diff --git a/controllers/commonservice_controller.go b/controllers/commonservice_controller.go index 1482b8a74..2e27fa6e2 100644 --- a/controllers/commonservice_controller.go +++ b/controllers/commonservice_controller.go @@ -23,8 +23,6 @@ import ( "reflect" "strings" - // certmanagerv1alpha1 "github.com/ibm/ibm-cert-manager-operator/apis/certmanager/v1alpha1" - corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" @@ -40,10 +38,12 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" "sigs.k8s.io/controller-runtime/pkg/source" - apiv3 "github.com/IBM/ibm-common-service-operator/api/v3" - "github.com/IBM/ibm-common-service-operator/controllers/bootstrap" - util "github.com/IBM/ibm-common-service-operator/controllers/common" - "github.com/IBM/ibm-common-service-operator/controllers/constant" + apiv3 "github.com/IBM/ibm-common-service-operator/v4/api/v3" + "github.com/IBM/ibm-common-service-operator/v4/controllers/bootstrap" + util "github.com/IBM/ibm-common-service-operator/v4/controllers/common" + "github.com/IBM/ibm-common-service-operator/v4/controllers/configurationcollector" + "github.com/IBM/ibm-common-service-operator/v4/controllers/constant" + odlm "github.com/IBM/operand-deployment-lifecycle-manager/v4/api/v1alpha1" ) // CommonServiceReconciler reconciles a CommonService object @@ -56,6 +56,7 @@ type CommonServiceReconciler struct { const ( CRInitializing string = "Initializing" CRUpdating string = "Updating" + CRPending string = "Pending" CRSucceeded string = "Succeeded" CRFailed string = "Failed" ) @@ -73,10 +74,10 @@ func (r *CommonServiceReconciler) Reconcile(ctx context.Context, req ctrl.Reques } return ctrl.Result{}, client.IgnoreNotFound(err) } - return r.ReconileNonConfigurableCR(ctx, instance) + return r.ReconcileNonConfigurableCR(ctx, instance) } - if err := r.Bootstrap.Client.Get(ctx, req.NamespacedName, instance); err != nil { + if err := r.Reader.Get(ctx, req.NamespacedName, instance); err != nil { if errors.IsNotFound(err) { if err := r.handleDelete(ctx); err != nil { return ctrl.Result{}, err @@ -90,24 +91,46 @@ func (r *CommonServiceReconciler) Reconcile(ctx context.Context, req ctrl.Reques return ctrl.Result{}, client.IgnoreNotFound(err) } - masterCR := &apiv3.CommonService{} - if err := r.Bootstrap.Client.Get(ctx, types.NamespacedName{Namespace: r.Bootstrap.CSData.OperatorNs, Name: "common-service"}, masterCR); err != nil { - if !errors.IsNotFound(err) { - return ctrl.Result{}, err - } - } - - if !masterCR.Spec.License.Accept { + if !instance.Spec.License.Accept { klog.Error("Accept license by changing .spec.license.accept to true in the CommonService CR. Operator will not proceed until then") } - if r.checkNamespace(req.NamespacedName.String()) { - return r.ReconcileMasterCR(ctx, instance) + // If the CommonService CR is not paused, continue to reconcile + if !r.reconcilePauseRequest(instance) { + if r.checkNamespace(req.NamespacedName.String()) { + return r.ReconcileMasterCR(ctx, instance) + } + return r.ReconcileGeneralCR(ctx, instance) } - return r.ReconcileGeneralCR(ctx, instance) + // If the CommonService CR is paused, update the status to pending + if err := r.updatePhase(ctx, instance, CRPending); err != nil { + klog.Errorf("Fail to reconcile %s/%s: %v", instance.Namespace, instance.Name, err) + return ctrl.Result{}, err + } + klog.Infof("%s/%s is in pending status due to pause request", instance.Namespace, instance.Name) + return ctrl.Result{}, nil } func (r *CommonServiceReconciler) ReconcileMasterCR(ctx context.Context, instance *apiv3.CommonService) (ctrl.Result, error) { + + var statusErr error + // Defer to Set error/ready/warning condition + defer func() { + if err := r.Bootstrap.CheckWarningCondition(instance); err != nil { + klog.Warning(err) + return + } + if statusErr != nil { + instance.SetErrorCondition(constant.MasterCR, apiv3.ConditionTypeError, corev1.ConditionTrue, apiv3.ConditionReasonError, statusErr.Error()) + } else { + instance.SetReadyCondition(constant.KindCR, apiv3.ConditionTypeReady, corev1.ConditionTrue) + } + if err := r.Client.Status().Update(ctx, instance); err != nil { + klog.Warning(err) + return + } + }() + originalInstance := instance.DeepCopy() operatorDeployed, servicesDeployed := r.Bootstrap.CheckDeployStatus(ctx) @@ -123,19 +146,22 @@ func (r *CommonServiceReconciler) ReconcileMasterCR(ctx context.Context, instanc forceUpdateODLMCRs = true } - if err := r.Client.Status().Patch(ctx, instance, client.MergeFrom(originalInstance)); err != nil { - return ctrl.Result{}, fmt.Errorf("error while patching CommonService.Status: %v", err) + if statusErr = r.Client.Status().Patch(ctx, instance, client.MergeFrom(originalInstance)); statusErr != nil { + return ctrl.Result{}, fmt.Errorf("error while patching CommonService.Status: %v", statusErr) } if instance.Status.Phase == "" { - if err := r.updatePhase(ctx, instance, CRInitializing); err != nil { - klog.Errorf("Fail to reconcile %s/%s: %v", instance.Namespace, instance.Name, err) - return ctrl.Result{}, err + // Set "Reconciling" condition and "Initializing" for phase + instance.SetPendingCondition(constant.MasterCR, apiv3.ConditionTypeReconciling, corev1.ConditionTrue, apiv3.ConditionReasonReconcile, apiv3.ConditionMessageReconcile) + instance.Status.Phase = CRInitializing + if statusErr = r.Client.Status().Update(ctx, instance); statusErr != nil { + klog.Errorf("Fail to update %s/%s: %v", instance.Namespace, instance.Name, statusErr) + return ctrl.Result{}, statusErr } } else { - if err := r.updatePhase(ctx, instance, CRUpdating); err != nil { - klog.Errorf("Fail to reconcile %s/%s: %v", instance.Namespace, instance.Name, err) - return ctrl.Result{}, err + if statusErr = r.updatePhase(ctx, instance, CRUpdating); statusErr != nil { + klog.Errorf("Fail to reconcile %s/%s: %v", instance.Namespace, instance.Name, statusErr) + return ctrl.Result{}, statusErr } } @@ -171,6 +197,19 @@ func (r *CommonServiceReconciler) ReconcileMasterCR(ctx context.Context, instanc os.Exit(1) } } + } else { + // check if the servicesNamespace is created + ns := &corev1.Namespace{} + if err := r.Reader.Get(ctx, types.NamespacedName{Name: r.Bootstrap.CSData.ServicesNs}, ns); err != nil { + if errors.IsNotFound(err) { + klog.Errorf("Not found servicesNamespace %s specified in the common-service CR.", r.Bootstrap.CSData.ServicesNs) + if err := r.updatePhase(ctx, instance, CRFailed); err != nil { + klog.Error(err) + } + klog.Errorf("Fail to reconcile %s/%s: %v", instance.Namespace, instance.Name, err) + return ctrl.Result{}, err + } + } } typeCorrect, err := r.Bootstrap.CheckClusterType(util.GetServicesNamespace(r.Reader)) @@ -185,70 +224,105 @@ func (r *CommonServiceReconciler) ReconcileMasterCR(ctx context.Context, instanc if !typeCorrect { klog.Error("Cluster type specificed in the ibm-cpp-config isn't correct") - if err := r.updatePhase(ctx, instance, CRFailed); err != nil { - klog.Error(err) + if statusErr = r.updatePhase(ctx, instance, CRFailed); statusErr != nil { + klog.Error(statusErr) } - klog.Errorf("Fail to reconcile %s/%s: %v", instance.Namespace, instance.Name, err) - return ctrl.Result{}, err + klog.Errorf("Fail to reconcile %s/%s: %v", instance.Namespace, instance.Name, statusErr) + return ctrl.Result{}, statusErr } // Init common service bootstrap resource // Including namespace-scope configmap // Deploy OperandConfig and OperandRegistry - if err := r.Bootstrap.InitResources(instance, forceUpdateODLMCRs); err != nil { - klog.Errorf("Failed to initialize resources: %v", err) - if err := r.updatePhase(ctx, instance, CRFailed); err != nil { - klog.Error(err) + if statusErr = r.Bootstrap.InitResources(instance, forceUpdateODLMCRs); statusErr != nil { + if statusErr := r.updatePhase(ctx, instance, CRFailed); statusErr != nil { + klog.Error(statusErr) } - klog.Errorf("Fail to reconcile %s/%s: %v", instance.Namespace, instance.Name, err) - return ctrl.Result{}, err + klog.Errorf("Fail to reconcile %s/%s: %v", instance.Namespace, instance.Name, statusErr) + return ctrl.Result{}, statusErr } + // Generate Issuer and Certificate CR + if statusErr = r.Bootstrap.DeployCertManagerCR(); statusErr != nil { + klog.Errorf("Failed to deploy cert manager CRs: %v", statusErr) + if statusErr = r.updatePhase(ctx, instance, CRFailed); statusErr != nil { + klog.Error(statusErr) + } + klog.Errorf("Fail to reconcile %s/%s: %v", instance.Namespace, instance.Name, statusErr) + return ctrl.Result{}, statusErr + } + + // Apply new configs to CommonService CR cs := util.NewUnstructured("operator.ibm.com", "CommonService", "v3") - if err := r.Bootstrap.Client.Get(ctx, types.NamespacedName{Name: instance.Name, Namespace: instance.Namespace}, cs); err != nil { - klog.Errorf("Fail to reconcile %s/%s: %v", instance.Namespace, instance.Name, err) - return ctrl.Result{}, err + if statusErr = r.Bootstrap.Client.Get(ctx, types.NamespacedName{Name: instance.Name, Namespace: instance.Namespace}, cs); statusErr != nil { + klog.Errorf("Fail to reconcile %s/%s: %v", instance.Namespace, instance.Name, statusErr) + return ctrl.Result{}, statusErr } - // Generate Issuer and Certificate CR - if err := r.Bootstrap.DeployCertManagerCR(); err != nil { - klog.Errorf("Failed to deploy cert manager CRs: %v", err) - if err := r.updatePhase(ctx, instance, CRFailed); err != nil { - klog.Error(err) + // Set "Pengding" condition and "Updating" for phase when config CS CR + instance.SetPendingCondition(constant.MasterCR, apiv3.ConditionTypeReconciling, corev1.ConditionTrue, apiv3.ConditionReasonConfig, apiv3.ConditionMessageConfig) + instance.Status.Phase = CRUpdating + newConfigs, serviceControllerMapping, statusErr := r.getNewConfigs(cs) + if statusErr != nil { + klog.Errorf("Fail to reconcile %s/%s: %v", instance.Namespace, instance.Name, statusErr) + instance.SetErrorCondition(constant.MasterCR, apiv3.ConditionTypeError, corev1.ConditionTrue, apiv3.ConditionReasonError, statusErr.Error()) + instance.Status.Phase = CRFailed + } + + if statusErr = r.Client.Status().Update(ctx, instance); statusErr != nil { + klog.Errorf("Fail to update %s/%s: %v", instance.Namespace, instance.Name, err) + return ctrl.Result{}, statusErr + } + + var isEqual bool + if isEqual, statusErr = r.updateOperandConfig(ctx, newConfigs, serviceControllerMapping); statusErr != nil { + if statusErr := r.updatePhase(ctx, instance, CRFailed); statusErr != nil { + klog.Error(statusErr) } - klog.Errorf("Fail to reconcile %s/%s: %v", instance.Namespace, instance.Name, err) - return ctrl.Result{}, err + klog.Errorf("Fail to reconcile %s/%s: %v", instance.Namespace, instance.Name, statusErr) + return ctrl.Result{}, statusErr + } else if isEqual { + r.Recorder.Event(instance, corev1.EventTypeNormal, "Noeffect", fmt.Sprintf("No update, resource sizings in the OperandConfig %s/%s are larger than the profile from CommonService CR %s/%s", r.Bootstrap.CSData.OperatorNs, "common-service", instance.Namespace, instance.Name)) } - newConfigs, serviceControllerMapping, err := r.getNewConfigs(cs, true) - if err != nil { - if err := r.updatePhase(ctx, instance, CRFailed); err != nil { - klog.Error(err) + + if err := r.Bootstrap.UpdateEDBUserManaged(); err != nil { + if statusErr := r.updatePhase(ctx, instance, CRFailed); statusErr != nil { + klog.Error(statusErr) } klog.Errorf("Fail to reconcile %s/%s: %v", instance.Namespace, instance.Name, err) - return ctrl.Result{}, client.IgnoreNotFound(err) + return ctrl.Result{}, statusErr } - isEqual, err := r.updateOperandConfig(ctx, newConfigs, serviceControllerMapping) - if err != nil { - if err := r.updatePhase(ctx, instance, CRFailed); err != nil { - klog.Error(err) + if isEqual, statusErr = r.updateOperatorConfig(ctx, instance.Spec.OperatorConfigs); statusErr != nil { + if statusErr := r.updatePhase(ctx, instance, CRFailed); statusErr != nil { + klog.Error(statusErr) } - klog.Errorf("Fail to reconcile %s/%s: %v", instance.Namespace, instance.Name, err) - return ctrl.Result{}, err + klog.Errorf("Fail to reconcile %s/%s: %v", instance.Namespace, instance.Name, statusErr) + return ctrl.Result{}, statusErr + } else if isEqual { + r.Recorder.Event(instance, corev1.EventTypeNormal, "Noeffect", fmt.Sprintf("No update, replica sizings in the OperatorConfig %s/%s are larger than the profile from CommonService CR %s/%s", r.Bootstrap.CSData.OperatorNs, "common-service", instance.Namespace, instance.Name)) } - // Create Event if there is no update in OperandConfig after applying current CR - if isEqual { - r.Recorder.Event(instance, corev1.EventTypeNormal, "Noeffect", fmt.Sprintf("No update, resource sizings in the OperandConfig %s/%s are larger than the profile from CommonService CR %s/%s", r.Bootstrap.CSData.OperatorNs, "common-service", instance.Namespace, instance.Name)) + if statusErr = configurationcollector.CreateUpdateConfig(r.Bootstrap); statusErr != nil { + if statusErr := r.updatePhase(ctx, instance, CRFailed); statusErr != nil { + klog.Error(statusErr) + } + klog.Errorf("Fail to reconcile %s/%s: %v", instance.Namespace, instance.Name, statusErr) + return ctrl.Result{}, statusErr } - if err := r.Bootstrap.PropagateDefaultCR(instance); err != nil { - klog.Error(err) - return ctrl.Result{}, err + if statusErr = r.Bootstrap.PropagateDefaultCR(instance); statusErr != nil { + klog.Error(statusErr) + return ctrl.Result{}, statusErr } - if err := r.updatePhase(ctx, instance, CRSucceeded); err != nil { - klog.Error(err) - return ctrl.Result{}, err + if statusErr = r.Bootstrap.UpdateResourceLabel(instance); statusErr != nil { + klog.Error(statusErr) + return ctrl.Result{}, statusErr + } + // Set Succeeded phase + if statusErr = r.updatePhase(ctx, instance, CRSucceeded); statusErr != nil { + klog.Error(statusErr) + return ctrl.Result{}, statusErr } klog.Infof("Finished reconciling CommonService: %s/%s", instance.Namespace, instance.Name) @@ -301,7 +375,7 @@ func (r *CommonServiceReconciler) ReconcileGeneralCR(ctx context.Context, instan return ctrl.Result{}, err } - newConfigs, serviceControllerMapping, err := r.getNewConfigs(cs, true) + newConfigs, serviceControllerMapping, err := r.getNewConfigs(cs) if err != nil { if err := r.updatePhase(ctx, instance, CRFailed); err != nil { klog.Error(err) @@ -324,6 +398,32 @@ func (r *CommonServiceReconciler) ReconcileGeneralCR(ctx context.Context, instan r.Recorder.Event(instance, corev1.EventTypeNormal, "Noeffect", fmt.Sprintf("No update, resource sizings in the OperandConfig %s/%s are larger than the profile from CommonService CR %s/%s", r.Bootstrap.CSData.OperatorNs, "common-service", instance.Namespace, instance.Name)) } + isEqual, err = r.updateOperatorConfig(ctx, instance.Spec.OperatorConfigs) + if err != nil { + if err := r.updatePhase(ctx, instance, CRFailed); err != nil { + klog.Error(err) + } + klog.Errorf("Fail to reconcile %s/%s: %v", instance.Namespace, instance.Name, err) + return ctrl.Result{}, err + } + + if err := r.Bootstrap.UpdateResourceLabel(instance); err != nil { + klog.Error(err) + return ctrl.Result{}, err + } + + // Create Event if there is no update in OperatorConfig after applying current CR + if isEqual { + r.Recorder.Event(instance, corev1.EventTypeNormal, "Noeffect", fmt.Sprintf("No update to, replica sizings in the OperatorConfig %s/%s are larger than the profile from CommonService CR %s/%s", r.Bootstrap.CSData.OperatorNs, "test-operator-config", instance.Namespace, instance.Name)) + } + + // Set Ready condition + instance.SetReadyCondition(constant.KindCR, apiv3.ConditionTypeReady, corev1.ConditionTrue) + if err := r.Client.Status().Update(ctx, instance); err != nil { + klog.Warning(err) + return ctrl.Result{}, err + } + if err := r.updatePhase(ctx, instance, CRSucceeded); err != nil { klog.Errorf("Fail to reconcile %s/%s: %v", instance.Namespace, instance.Name, err) return ctrl.Result{}, err @@ -334,7 +434,7 @@ func (r *CommonServiceReconciler) ReconcileGeneralCR(ctx context.Context, instan } // ReconileNonConfigurableCR is for setting the cloned Master CR status for advanced topologies -func (r *CommonServiceReconciler) ReconileNonConfigurableCR(ctx context.Context, instance *apiv3.CommonService) (ctrl.Result, error) { +func (r *CommonServiceReconciler) ReconcileNonConfigurableCR(ctx context.Context, instance *apiv3.CommonService) (ctrl.Result, error) { if instance.Status.Phase == "" { if err := r.updatePhase(ctx, instance, CRInitializing); err != nil { @@ -358,6 +458,13 @@ func (r *CommonServiceReconciler) ReconileNonConfigurableCR(ctx context.Context, } } + // Set Ready condition + instance.SetReadyCondition(constant.KindCR, apiv3.ConditionTypeReady, corev1.ConditionTrue) + if err := r.Client.Status().Update(ctx, instance); err != nil { + klog.Warning(err) + return ctrl.Result{}, err + } + if err := r.updatePhase(ctx, instance, CRSucceeded); err != nil { klog.Errorf("Fail to reconcile %s/%s: %v", instance.Namespace, instance.Name, err) return ctrl.Result{}, err @@ -373,15 +480,58 @@ func (r *CommonServiceReconciler) mappingToCsRequest() handler.MapFunc { cmName := object.GetName() cmNs := object.GetNamespace() if cmName == constant.CsMapConfigMap && cmNs == "kube-public" { - CsInstance = append(CsInstance, reconcile.Request{NamespacedName: types.NamespacedName{Name: "common-service", Namespace: r.Bootstrap.CSData.OperatorNs}}) + CsInstance = append(CsInstance, reconcile.Request{NamespacedName: types.NamespacedName{Name: constant.MasterCR, Namespace: r.Bootstrap.CSData.OperatorNs}}) } return CsInstance } } +func (r *CommonServiceReconciler) mappingToCsRequestForOperandRegistry() handler.MapFunc { + return func(object client.Object) []reconcile.Request { + operandRegistry, ok := object.(*odlm.OperandRegistry) + if !ok { + // It's not an OperandRegistry, ignore + return nil + } + if operandRegistry.Name == constant.MasterCR && operandRegistry.Namespace == r.Bootstrap.CSData.ServicesNs { + if shouldReconcile(operandRegistry) { + // Enqueue a reconciliation request for the corresponding CommonService + return []reconcile.Request{ + {NamespacedName: types.NamespacedName{Name: constant.MasterCR, Namespace: r.Bootstrap.CSData.OperatorNs}}, + } + } + } + return nil + } +} + +// shouldReconcile checks the conditions for reconciliation +func shouldReconcile(operandRegistry *odlm.OperandRegistry) bool { + + if operandRegistry.Status.OperatorsStatus != nil { + // List all requested operators + for operator := range operandRegistry.Status.OperatorsStatus { + // If there is a requested operator's installMode is "no-op", then skip reconcile + for _, op := range operandRegistry.Spec.Operators { + if op.Name == operator && op.InstallMode == "no-op" { + klog.Infof("The operator %s with 'no-op' installMode is still requested in OperandRegistry, skip reconciliation", operator) + return false + } + } + } + } + return true +} + func (r *CommonServiceReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - For(&apiv3.CommonService{}, builder.WithPredicates(predicate.GenerationChangedPredicate{})). + + controller := ctrl.NewControllerManagedBy(mgr). + // AnnotationChangedPredicate is intended to be used in conjunction with the GenerationChangedPredicate + For(&apiv3.CommonService{}, builder.WithPredicates( + predicate.Or( + predicate.GenerationChangedPredicate{}, + predicate.AnnotationChangedPredicate{}, + predicate.LabelChangedPredicate{}))). Watches( &source.Kind{Type: &corev1.ConfigMap{}}, handler.EnqueueRequestsFromMapFunc(r.mappingToCsRequest()), @@ -395,5 +545,31 @@ func (r *CommonServiceReconciler) SetupWithManager(mgr ctrl.Manager) error { UpdateFunc: func(e event.UpdateEvent) bool { return true }, - })).Complete(r) + })) + if isOpregAPI, err := r.Bootstrap.CheckCRD(constant.OpregAPIGroupVersion, constant.OpregKind); err != nil { + klog.Errorf("Failed to check if OperandRegistry CRD exists: %v", err) + return err + } else if isOpregAPI { + controller = controller.Watches( + &source.Kind{Type: &odlm.OperandRegistry{}}, + handler.EnqueueRequestsFromMapFunc(r.mappingToCsRequestForOperandRegistry()), + builder.WithPredicates(predicate.Funcs{ + UpdateFunc: func(e event.UpdateEvent) bool { + oldOperandRegistry, ok := e.ObjectOld.(*odlm.OperandRegistry) + if !ok { + return false + } + + newOperandRegistry, ok := e.ObjectNew.(*odlm.OperandRegistry) + if !ok { + return false + } + + // Return true if the length of .status.operatorsStatus array has changed, indicating that a operator has been added or removed + return len(oldOperandRegistry.Status.OperatorsStatus) != len(newOperandRegistry.Status.OperatorsStatus) + }, + }, + )) + } + return controller.Complete(r) } diff --git a/controllers/commonservice_controller_test.go b/controllers/commonservice_controller_test.go index 2e169ab12..a375e1e09 100644 --- a/controllers/commonservice_controller_test.go +++ b/controllers/commonservice_controller_test.go @@ -29,9 +29,9 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" - apiv3 "github.com/IBM/ibm-common-service-operator/api/v3" - util "github.com/IBM/ibm-common-service-operator/controllers/common" - "github.com/IBM/ibm-common-service-operator/controllers/constant" + apiv3 "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" ) // +kubebuilder:docs-gen:collapse=Imports diff --git a/controllers/configurationCollector/collector.go b/controllers/configurationCollector/collector.go deleted file mode 100644 index f08aee1f7..000000000 --- a/controllers/configurationCollector/collector.go +++ /dev/null @@ -1,82 +0,0 @@ -// -// Copyright 2022 IBM Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package configurationcollector - -import ( - "context" - "strings" - - storagev1 "k8s.io/api/storage/v1" - - "github.com/IBM/ibm-common-service-operator/controllers/bootstrap" -) - -func Buildconfig(config map[string]string, bs *bootstrap.Bootstrap) map[string]string { - builder := configbuilder{data: config, bs: bs} - updatedConfig := builder.setDefaultStorageClass() - return updatedConfig.data -} - -type configbuilder struct { - data map[string]string - bs *bootstrap.Bootstrap -} - -func (b *configbuilder) setDefaultStorageClass() *configbuilder { - scList := &storagev1.StorageClassList{} - err := b.bs.Reader.List(context.TODO(), scList) - if err != nil { - return b - } - if len(scList.Items) == 0 { - return b - } - - var defaultSC string - var defaultSCList []string - var allSCList []string - - for _, sc := range scList.Items { - if defaultSC == "" { - defaultSC = sc.Name - } - if sc.ObjectMeta.GetAnnotations()["storageclass.kubernetes.io/is-default-class"] == "true" { - defaultSCList = append(defaultSCList, sc.Name) - } - if sc.Provisioner == "kubernetes.io/no-provisioner" { - continue - } - allSCList = append(allSCList, sc.GetName()) - } - - if b.data == nil { - b.data = make(map[string]string) - } - if defaultSC != "" { - b.data["storageclass.default"] = defaultSC - } - - if len(defaultSCList) != 1 { - b.data["storageclass.default.list"] = strings.Join(defaultSCList, ",") - } - - if len(allSCList) != 0 { - b.data["storageclass.list"] = strings.Join(allSCList, ",") - } - - return b -} diff --git a/controllers/configurationcollector/collector.go b/controllers/configurationcollector/collector.go new file mode 100644 index 000000000..c01f7993c --- /dev/null +++ b/controllers/configurationcollector/collector.go @@ -0,0 +1,134 @@ +// +// Copyright 2022 IBM Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package configurationcollector + +import ( + "context" + "reflect" + "strings" + + corev1 "k8s.io/api/core/v1" + storagev1 "k8s.io/api/storage/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/types" + "k8s.io/klog" + + "github.com/IBM/ibm-common-service-operator/v4/controllers/bootstrap" + util "github.com/IBM/ibm-common-service-operator/v4/controllers/common" + "github.com/IBM/ibm-common-service-operator/v4/controllers/constant" +) + +func Buildconfig(config map[string]string, bs *bootstrap.Bootstrap) map[string]string { + builder := configbuilder{data: config, bs: bs} + updatedConfig := builder.setDefaultStorageClass() + return updatedConfig.data +} + +type configbuilder struct { + data map[string]string + bs *bootstrap.Bootstrap +} + +func (b *configbuilder) setDefaultStorageClass() *configbuilder { + scList := &storagev1.StorageClassList{} + err := b.bs.Reader.List(context.TODO(), scList) + if err != nil { + return b + } + if len(scList.Items) == 0 { + return b + } + + var defaultSC string + var defaultSCList []string + var allSCList []string + + for _, sc := range scList.Items { + if defaultSC == "" { + defaultSC = sc.Name + } + if sc.ObjectMeta.GetAnnotations()["storageclass.kubernetes.io/is-default-class"] == "true" { + defaultSCList = append(defaultSCList, sc.Name) + } + if sc.Provisioner == "kubernetes.io/no-provisioner" { + continue + } + allSCList = append(allSCList, sc.GetName()) + } + + if b.data == nil { + b.data = make(map[string]string) + } + if defaultSC != "" { + b.data["storageclass.default"] = defaultSC + } + + if len(defaultSCList) != 1 { + b.data["storageclass.default.list"] = strings.Join(defaultSCList, ",") + } + + if len(allSCList) != 0 { + b.data["storageclass.list"] = strings.Join(allSCList, ",") + } + + return b +} + +// CreateUpdateConfig deploys config builder for global cpp configmap +func CreateUpdateConfig(bs *bootstrap.Bootstrap) error { + config := &corev1.ConfigMap{} + if err := bs.Reader.Get(context.TODO(), types.NamespacedName{Name: constant.IBMCPPCONFIG, Namespace: bs.CSData.ServicesNs}, config); err != nil && !errors.IsNotFound(err) { + klog.Errorf("Failed to get ConfigMap %s/%s: %v", bs.CSData.ServicesNs, constant.IBMCPPCONFIG, err) + return err + } else if errors.IsNotFound(err) { + config.ObjectMeta.Name = constant.IBMCPPCONFIG + config.ObjectMeta.Namespace = bs.CSData.ServicesNs + config.Data = make(map[string]string) + config.Data = Buildconfig(config.Data, bs) + if !(config.Labels != nil && config.Labels[constant.CsManagedLabel] == "true") { + util.EnsureLabelsForConfigMap(config, map[string]string{ + constant.CsManagedLabel: "true", + }) + } + if err := bs.Client.Create(context.TODO(), config); err != nil { + klog.Errorf("Failed to create ConfigMap %s/%s: %v", bs.CSData.ServicesNs, constant.IBMCPPCONFIG, err) + return err + } + klog.Infof("Global CPP config %s/%s is created", bs.CSData.ServicesNs, constant.IBMCPPCONFIG) + } else { + orgConfig := config.DeepCopy() + config.Data = Buildconfig(config.Data, bs) + if !(config.Labels != nil && config.Labels[constant.CsManagedLabel] == "true") { + util.EnsureLabelsForConfigMap(config, map[string]string{ + constant.CsManagedLabel: "true", + }) + } + if !reflect.DeepEqual(orgConfig, config) { + if err := bs.Client.Update(context.TODO(), config); err != nil { + klog.Errorf("Failed to update ConfigMap %s/%s: %v", bs.CSData.ServicesNs, constant.IBMCPPCONFIG, err) + return err + } + klog.Infof("Global CPP config %s/%s is updated", bs.CSData.ServicesNs, constant.IBMCPPCONFIG) + } + } + + if err := bs.PropagateCPPConfig(config); err != nil { + klog.Error(err) + return err + } + return nil +} diff --git a/controllers/constant/certmanager.go b/controllers/constant/certmanager.go index 1de72a0e5..475c55b9b 100644 --- a/controllers/constant/certmanager.go +++ b/controllers/constant/certmanager.go @@ -16,12 +16,23 @@ package constant +// SecretWatchLabel is a string of secrets that watched by cert manager operator labels +const SecretWatchLabel string = "operator.ibm.com/watched-by-cert-manager" + +// Labels and Annotations added by this operator +const ( + OperatorGeneratedAnno = "ibm-cert-manager-operator-generated" + ProperV1Label = "ibm-cert-manager-operator/conditionally-generated-v1" + RefreshCALabel = "ibm-cert-manager-operator/refresh-ca-chain" +) + var ( CertManagerAPIGroupVersionV1Alpha1 = "certmanager.k8s.io/v1alpha1" CertManagerAPIGroupVersionV1 = "cert-manager.io/v1" CertManagerKinds = []string{"Issuer", "Certificate"} CertManagerIssuers = []string{CSSSIssuer, CSCAIssuer} CertManagerCerts = []string{CSCACert} + KeycloakCert = "cs-keycloak-tls-cert" ) // CSCAIssuer is the CR of cs-ca-issuer @@ -83,3 +94,22 @@ spec: duration: 17520h0m0s renewBefore: 5840h0m0s ` + +const KeycloakCertTemplate = ` +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: cs-keycloak-tls-cert + namespace: {{ .ServicesNs }} +spec: + commonName: cs-keycloak-service + dnsNames: + - cs-keycloak-service + - cs-keycloak-service.{{ .ServicesNs }} + - cs-keycloak-service.{{ .ServicesNs }}.svc + - cs-keycloak-service.{{ .ServicesNs }}.svc.cluster.local + issuerRef: + kind: Issuer + name: cs-ca-issuer + secretName: cs-keycloak-tls-secret +` diff --git a/controllers/constant/cloudNativePostgresql.go b/controllers/constant/cloudNativePostgresql.go new file mode 100644 index 000000000..7d6da4312 --- /dev/null +++ b/controllers/constant/cloudNativePostgresql.go @@ -0,0 +1,36 @@ +// +// Copyright 2022 IBM Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package constant + +const EDBImageConfigMap = ` +apiVersion: v1 +kind: ConfigMap +metadata: + name: cloud-native-postgresql-image-list + namespace: "{{ .CPFSNs }}" + labels: + operator.ibm.com/managedByCsOperator: "true" + annotations: + version: {{ .Version }} +data: + ibm-postgresql-16-operand-image: icr.io/cpopen/edb/postgresql:16.4@sha256:d87a804d9bb7558d124bd83a83c261a074c26bccc3fe6ef095cdbe22be29a456 + ibm-postgresql-15-operand-image: icr.io/cpopen/edb/postgresql:15.8@sha256:8f602b668e1174357332374094a93534a2ab132e954badcb82b331c2e04b65da + ibm-postgresql-14-operand-image: icr.io/cpopen/edb/postgresql:14.15@sha256:e027ee5a9aaebd369196c119481a14eba961119a3c3b1748aac06936bcb3afe1 + ibm-postgresql-13-operand-image: icr.io/cpopen/edb/postgresql:13.16@sha256:9fc9cc5dd91c38797397a02736996857d0182e4858ee77aeeb21f855121c9347 + ibm-postgresql-12-operand-image: icr.io/cpopen/edb/postgresql:12.20@sha256:1a5ec719c2f7da6d98374cfa43a03f96a56195416ff0c7443ee255dc92d8a82b + edb-postgres-license-provider-image: cp.icr.io/cp/cpd/edb-postgres-license-provider@sha256:8112cfa96daac82de5a4fdede8fcaecfc41908e7ee22686e0f8818c875784a00 +` diff --git a/controllers/constant/constant.go b/controllers/constant/constant.go index abdd4dda6..7331c2e37 100644 --- a/controllers/constant/constant.go +++ b/controllers/constant/constant.go @@ -46,10 +46,18 @@ const ( SaasConfigMap = "saas-config" // Namespace Scope Operator resource name NsSubResourceName = "nsSubscription" - // Namespace Scope Operator Restricted resource name - NsRestrictedSubResourceName = "nsRestrictedSubscription" // Namespace Scope Operator sub name NsSubName = "ibm-namespace-scope-operator" + // NamespaceScope CRs kind + NssKindCR = "NamespaceScope" + // NamespaceScope CRs api version + NssAPIVersion = "operator.ibm.com/v1" + // NamespaceScopeConfigmapName is the name of ConfigMap which stores the NamespaceScope Info + NamespaceScopeConfigmapName = "namespace-scope" + // NssCRFinalizer is the name for the finalizer to allow for deletion + NssCRFinalizer = "finalizer.nss.operator.ibm.com" + // Namespace Scope Operator Restricted resource name + NsRestrictedSubResourceName = "nsRestrictedSubscription" // Namespace Scope Operator Restricted sub name NsRestrictedSubName = "ibm-namespace-scope-operator-restricted" //DefaultRequeueDuration is the default requeue time duration for request @@ -76,8 +84,6 @@ const ( IBMODLMPackage = "operand-deployment-lifecycle-manager-app" //IBMNSSPackage is the package name of the namespace scope operator IBMNSSPackage = "ibm-namespace-scope-operator" - // NamespaceScopeConfigmapName is the name of ConfigMap which stores the NamespaceScope Info - NamespaceScopeConfigmapName = "namespace-scope" // DevBuildImage is regular expression of the image address of internal dev build for testing DevBuildImage = `^hyc\-cloud\-private\-(.*)\-docker\-local\.artifactory\.swg\-devops\.com\/ibmcom\/ibm\-common\-service\-catalog\:(.*)` // BedrockCatalogsourcePriority is an annotation defined in the catalogsource @@ -90,6 +96,27 @@ const ( CsClonedFromLabel = "operator.ibm.com/common-services.cloned-from" // IBMCPPCONFIG is the name of ibm-cpp-config ConfigMap IBMCPPCONFIG = "ibm-cpp-config" + // OpregAPIGroupVersion is the api group version of OperandRegistry + OpregAPIGroupVersion = "operator.ibm.com/v1alpha1" + // OpregKind is the kind of OperandRegistry + OpregKind = "OperandRegistry" + // OpconKind is the kind of OperandConfig + OpconKind = "OperandConfig" + // DefaultHugePageAllocation is the default huge page allocation + DefaultHugePageAllocation = "100Mi" + // WebhookServiceName is the name of the webhook service used for v3 operator + WebhookServiceName = "ibm-common-service-webhook" + // Secretshare is the name of the secretshare + Secretshare = "secretshare" + // Some WebhookConfigurations + CSWebhookConfig = "ibm-common-service-webhook-configuration" + OperanReqConfig = "ibm-operandrequest-webhook-configuration" + CSMappingConfig = "ibm-cs-ns-mapping-webhook-configuration" +) + +// Bedrock Deployment names for No OLM +var ( + DeploymentsName = []string{"ibm-common-service-operator", "operand-deployment-lifecycle-manager", "ibm-namespace-scope-operator", "ibm-commonui-operator", "ibm-iam-operator"} ) // CsOg is OperatorGroup constent for the common service operator @@ -111,6 +138,8 @@ kind: CommonService metadata: annotations: version: "-1" + labels: + foundationservices.cloudpak.ibm.com: commonservice name: common-service namespace: "{{ .OperatorNs }}" spec: diff --git a/controllers/constant/fipsEnable.go b/controllers/constant/fipsEnable.go index 15f45dec1..5d71655d8 100644 --- a/controllers/constant/fipsEnable.go +++ b/controllers/constant/fipsEnable.go @@ -50,4 +50,24 @@ const FipsEnabledTemplate = ` authentication: config: fipsEnabled: placeholder +- name: ibm-im-operator-v4.3 + spec: + authentication: + config: + fipsEnabled: placeholder +- name: ibm-im-operator-v4.4 + spec: + authentication: + config: + fipsEnabled: placeholder +- name: ibm-im-operator-v4.5 + spec: + authentication: + config: + fipsEnabled: placeholder +- name: ibm-im-operator-v4.6 + spec: + authentication: + config: + fipsEnabled: placeholder ` diff --git a/controllers/constant/hugepages.go b/controllers/constant/hugepages.go new file mode 100644 index 000000000..788842329 --- /dev/null +++ b/controllers/constant/hugepages.go @@ -0,0 +1,49 @@ +// +// Copyright 2022 IBM Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package constant + +const HugePagesTemplate = ` +- name: ibm-im-operator + spec: + authentication: + authService: + resources: + limits: + placeholder1: placeholder2 + clientRegistration: + resources: + limits: + placeholder1: placeholder2 + identityManager: + resources: + limits: + placeholder1: placeholder2 + identityProvider: + resources: + limits: + placeholder1: placeholder2 +- name: common-service-postgresql + resources: + - apiVersion: postgresql.k8s.enterprisedb.io/v1 + data: + spec: + resources: + limits: + placeholder1: placeholder2 + kind: Cluster + name: common-service-db +` diff --git a/controllers/constant/multipleInstancesEnabled.go b/controllers/constant/instanaEnable.go similarity index 70% rename from controllers/constant/multipleInstancesEnabled.go rename to controllers/constant/instanaEnable.go index 04a4935f8..7fbed82d6 100644 --- a/controllers/constant/multipleInstancesEnabled.go +++ b/controllers/constant/instanaEnable.go @@ -1,5 +1,5 @@ // -// Copyright 2022 IBM Corporation +// Copyright 2024 IBM Corporation // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,13 +16,13 @@ package constant -const MultipleInstancesEnabledTemplate = ` -- name: ibm-management-ingress-operator +const InstanaEnableTemplate = ` +- name: ibm-im-operator spec: - managementIngress: - multipleInstancesEnabled: placeholder -- name: ibm-commonui-operator + authentication: + enableInstanaMetricCollection: {{ .InstanaEnable }} +- name: ibm-idp-config-ui-operator spec: commonWebUI: - multipleInstancesEnabled: placeholder + enableInstanaMetricCollection: {{ .InstanaEnable }} ` diff --git a/controllers/constant/keycloakThemes.go b/controllers/constant/keycloakThemes.go new file mode 100644 index 000000000..0a8e76070 --- /dev/null +++ b/controllers/constant/keycloakThemes.go @@ -0,0 +1,34 @@ +// +// Copyright 2022 IBM Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package constant + +const KeycloakThemesJar = `/hack/keycloak-themes/cloudpak-theme.jar` + +const KeycloakThemesConfigMap = ` +apiVersion: v1 +kind: ConfigMap +metadata: + name: cs-keycloak-theme + namespace: "{{ .ServicesNs }}" + labels: + operator.ibm.com/managedByCsOperator: "true" + annotations: + version: {{ .Version }} + themesVersion: {{ .CloudPakThemesVersion }} +binaryData: + cloudpak-theme.jar: {{ .CloudPakThemes }} +` diff --git a/controllers/constant/odlm.go b/controllers/constant/odlm.go index 3dd65daa5..ca50aa245 100644 --- a/controllers/constant/odlm.go +++ b/controllers/constant/odlm.go @@ -23,14 +23,19 @@ import ( utilyaml "github.com/ghodss/yaml" - odlm "github.com/IBM/operand-deployment-lifecycle-manager/api/v1alpha1" + odlm "github.com/IBM/operand-deployment-lifecycle-manager/v4/api/v1alpha1" ) var ( - CSV3OperandRegistry string - CSV3SaasOperandRegistry string - CSV3OperandConfig string - CSV3SaasOperandConfig string + CSV4OperandRegistry string + CSV4SaasOperandRegistry string + CSV4OperandConfig string + CSV4SaasOperandConfig string +) + +const ( + ExcludedCatalog = "certified-operators,community-operators,redhat-marketplace,ibm-cp-automation-foundation-catalog,operatorhubio-catalog" + StatusMonitoredServices = "ibm-idp-config-ui-operator,ibm-mongodb-operator,ibm-im-operator" ) const ( @@ -44,7 +49,8 @@ metadata: operator.ibm.com/managedByCsOperator: "true" annotations: version: {{ .Version }} - excluded-catalogsource: certified-operators,community-operators,redhat-marketplace,redhat-operators,ibm-cp-automation-foundation-catalog,operatorhubio-catalog + excluded-catalogsource: {{ .ExcludedCatalog }} + status-monitored-services: {{ .StatusMonitoredServices }} spec: operators: - name: ibm-im-mongodb-operator-v4.0 @@ -52,22 +58,16 @@ spec: channel: v4.0 packageName: ibm-mongodb-operator-app installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" - name: ibm-im-mongodb-operator-v4.1 namespace: "{{ .CPFSNs }}" channel: v4.1 packageName: ibm-mongodb-operator-app installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" - name: ibm-im-mongodb-operator-v4.2 namespace: "{{ .CPFSNs }}" channel: v4.2 packageName: ibm-mongodb-operator-app installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" ` IMOpReg = ` @@ -80,7 +80,8 @@ metadata: operator.ibm.com/managedByCsOperator: "true" annotations: version: {{ .Version }} - excluded-catalogsource: certified-operators,community-operators,redhat-marketplace,redhat-operators,ibm-cp-automation-foundation-catalog,operatorhubio-catalog + excluded-catalogsource: {{ .ExcludedCatalog }} + status-monitored-services: {{ .StatusMonitoredServices }} spec: operators: - name: ibm-im-operator-v4.0 @@ -89,24 +90,66 @@ spec: packageName: ibm-iam-operator scope: public installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" - name: ibm-im-operator-v4.1 namespace: "{{ .CPFSNs }}" channel: v4.1 packageName: ibm-iam-operator scope: public installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" - name: ibm-im-operator-v4.2 namespace: "{{ .CPFSNs }}" channel: v4.2 packageName: ibm-iam-operator scope: public installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" + - name: ibm-im-operator-v4.3 + namespace: "{{ .CPFSNs }}" + channel: v4.3 + packageName: ibm-iam-operator + scope: public + installPlanApproval: {{ .ApprovalMode }} + - name: ibm-im-operator-v4.4 + namespace: "{{ .CPFSNs }}" + channel: v4.4 + packageName: ibm-iam-operator + scope: public + installPlanApproval: {{ .ApprovalMode }} + - name: ibm-im-operator-v4.5 + namespace: "{{ .CPFSNs }}" + channel: v4.5 + packageName: ibm-iam-operator + scope: public + installPlanApproval: {{ .ApprovalMode }} + - name: ibm-im-operator-v4.6 + namespace: "{{ .CPFSNs }}" + channel: v4.6 + packageName: ibm-iam-operator + scope: public + installPlanApproval: {{ .ApprovalMode }} + - name: ibm-im-operator-v4.7 + namespace: "{{ .CPFSNs }}" + channel: v4.7 + packageName: ibm-iam-operator + scope: public + installPlanApproval: {{ .ApprovalMode }} + - name: ibm-im-operator-v4.8 + namespace: "{{ .CPFSNs }}" + channel: v4.8 + packageName: ibm-iam-operator + scope: public + installPlanApproval: {{ .ApprovalMode }} + - name: ibm-im-operator-v4.9 + namespace: "{{ .CPFSNs }}" + channel: v4.9 + packageName: ibm-iam-operator + scope: public + installPlanApproval: {{ .ApprovalMode }} + - name: ibm-im-operator-v4.10 + namespace: "{{ .CPFSNs }}" + channel: v4.9 + packageName: ibm-iam-operator + scope: public + installPlanApproval: {{ .ApprovalMode }} ` IdpConfigUIOpReg = ` @@ -119,7 +162,8 @@ metadata: operator.ibm.com/managedByCsOperator: "true" annotations: version: {{ .Version }} - excluded-catalogsource: certified-operators,community-operators,redhat-marketplace,redhat-operators,ibm-cp-automation-foundation-catalog,operatorhubio-catalog + excluded-catalogsource: {{ .ExcludedCatalog }} + status-monitored-services: {{ .StatusMonitoredServices }} spec: operators: - name: ibm-idp-config-ui-operator-v4.0 @@ -128,24 +172,48 @@ spec: packageName: ibm-commonui-operator-app scope: public installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" - name: ibm-idp-config-ui-operator-v4.1 namespace: "{{ .CPFSNs }}" channel: v4.1 packageName: ibm-commonui-operator-app scope: public installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" - name: ibm-idp-config-ui-operator-v4.2 namespace: "{{ .CPFSNs }}" channel: v4.2 packageName: ibm-commonui-operator-app scope: public installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" + - name: ibm-idp-config-ui-operator-v4.3 + namespace: "{{ .CPFSNs }}" + channel: v4.3 + packageName: ibm-commonui-operator-app + scope: public + installPlanApproval: {{ .ApprovalMode }} + - name: ibm-idp-config-ui-operator-v4.4 + namespace: "{{ .CPFSNs }}" + channel: v4.4 + packageName: ibm-commonui-operator-app + scope: public + installPlanApproval: {{ .ApprovalMode }} + - name: ibm-idp-config-ui-operator-v4.5 + namespace: "{{ .CPFSNs }}" + channel: v4.5 + packageName: ibm-commonui-operator-app + scope: public + installPlanApproval: {{ .ApprovalMode }} + - name: ibm-idp-config-ui-operator-v4.6 + namespace: "{{ .CPFSNs }}" + channel: v4.6 + packageName: ibm-commonui-operator-app + scope: public + installPlanApproval: {{ .ApprovalMode }} + - name: ibm-idp-config-ui-operator-v4.7 + namespace: "{{ .CPFSNs }}" + channel: v4.7 + packageName: ibm-commonui-operator-app + scope: public + installPlanApproval: {{ .ApprovalMode }} ` PlatformUIOpReg = ` @@ -158,7 +226,8 @@ metadata: operator.ibm.com/managedByCsOperator: "true" annotations: version: {{ .Version }} - excluded-catalogsource: certified-operators,community-operators,redhat-marketplace,redhat-operators,ibm-cp-automation-foundation-catalog,operatorhubio-catalog + excluded-catalogsource: {{ .ExcludedCatalog }} + status-monitored-services: {{ .StatusMonitoredServices }} spec: operators: - name: ibm-platformui-operator-v4.0 @@ -167,24 +236,42 @@ spec: packageName: ibm-zen-operator scope: public installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" - name: ibm-platformui-operator-v4.1 namespace: "{{ .CPFSNs }}" channel: v4.1 packageName: ibm-zen-operator scope: public installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" - name: ibm-platformui-operator-v4.2 namespace: "{{ .CPFSNs }}" channel: v4.2 packageName: ibm-zen-operator scope: public installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" + - name: ibm-platformui-operator-v4.3 + namespace: "{{ .CPFSNs }}" + channel: v4.3 + packageName: ibm-zen-operator + scope: public + installPlanApproval: {{ .ApprovalMode }} + - name: ibm-platformui-operator-v4.4 + namespace: "{{ .CPFSNs }}" + channel: v4.4 + packageName: ibm-zen-operator + scope: public + installPlanApproval: {{ .ApprovalMode }} + - name: ibm-platformui-operator-v6.0 + namespace: "{{ .CPFSNs }}" + channel: v6.0 + packageName: ibm-zen-operator + scope: public + installPlanApproval: {{ .ApprovalMode }} + - name: ibm-platformui-operator-v6.1 + namespace: "{{ .CPFSNs }}" + channel: v6.1 + packageName: ibm-zen-operator + scope: public + installPlanApproval: {{ .ApprovalMode }} ` ) @@ -199,21 +286,54 @@ metadata: operator.ibm.com/managedByCsOperator: "true" annotations: version: {{ .Version }} - excluded-catalogsource: certified-operators,community-operators,redhat-marketplace,redhat-operators,ibm-cp-automation-foundation-catalog,operatorhubio-catalog + excluded-catalogsource: {{ .ExcludedCatalog }} + status-monitored-services: {{ .StatusMonitoredServices }} spec: operators: - - channel: stable-v22 + - channel: stable-v24 + fallbackChannels: + - stable-v22 installPlanApproval: {{ .ApprovalMode }} name: keycloak-operator namespace: "{{ .ServicesNs }}" packageName: rhbk-operator scope: public - channel: stable + fallbackChannels: + - stable-v1.22 installPlanApproval: {{ .ApprovalMode }} name: edb-keycloak namespace: "{{ .CPFSNs }}" packageName: cloud-native-postgresql scope: public + operatorConfig: cloud-native-postgresql-operator-config +` +) + +const ( + CommonServicePGOpReg = ` +apiVersion: operator.ibm.com/v1alpha1 +kind: OperandRegistry +metadata: + name: common-service + namespace: "{{ .ServicesNs }}" + labels: + operator.ibm.com/managedByCsOperator: "true" + annotations: + version: {{ .Version }} + excluded-catalogsource: {{ .ExcludedCatalog }} + status-monitored-services: {{ .StatusMonitoredServices }} +spec: + operators: + - channel: stable-v1.22 + fallbackChannels: + - stable + installPlanApproval: {{ .ApprovalMode }} + name: common-service-postgresql + namespace: "{{ .CPFSNs }}" + packageName: cloud-native-postgresql + scope: public + operatorConfig: cloud-native-postgresql-operator-config ` ) @@ -295,6 +415,118 @@ spec: - name: ibm-im-mongodb-operator-v4.2 - name: ibm-idp-config-ui-operator-v4.2 registry: common-service + - name: ibm-im-operator-v4.3 + spec: + authentication: + config: + onPremMultipleDeploy: {{ .OnPremMultiEnable }} + operandBindInfo: + operand: ibm-im-operator + operandRequest: + requests: + - operands: + - name: ibm-im-mongodb-operator-v4.2 + - name: ibm-idp-config-ui-operator-v4.3 + registry: common-service + - name: ibm-im-operator-v4.4 + spec: + authentication: + config: + onPremMultipleDeploy: {{ .OnPremMultiEnable }} + operandBindInfo: + operand: ibm-im-operator + operandRequest: + requests: + - operands: + - name: ibm-im-mongodb-operator-v4.2 + - name: ibm-idp-config-ui-operator-v4.3 + registry: common-service + - name: ibm-im-operator-v4.5 + spec: + authentication: + config: + onPremMultipleDeploy: {{ .OnPremMultiEnable }} + operandBindInfo: + operand: ibm-im-operator + - name: ibm-im-operator-v4.6 + spec: + authentication: + config: + onPremMultipleDeploy: {{ .OnPremMultiEnable }} + operandBindInfo: + operand: ibm-im-operator + - name: ibm-im-operator-v4.7 + spec: + authentication: + config: + onPremMultipleDeploy: {{ .OnPremMultiEnable }} + operandBindInfo: + operand: ibm-im-operator + - name: ibm-im-operator-v4.8 + spec: + authentication: + config: + onPremMultipleDeploy: {{ .OnPremMultiEnable }} + operandBindInfo: + operand: ibm-im-operator + - name: ibm-im-operator-v4.9 + spec: + authentication: + config: + onPremMultipleDeploy: {{ .OnPremMultiEnable }} + operandBindInfo: + operand: ibm-im-operator + - name: ibm-im-operator-v4.10 + spec: + authentication: + config: + onPremMultipleDeploy: {{ .OnPremMultiEnable }} + operandBindInfo: + operand: ibm-im-operator +` + + UserMgmtOpCon = ` +apiVersion: operator.ibm.com/v1alpha1 +kind: OperandConfig +metadata: + name: common-service + namespace: "{{ .ServicesNs }}" + labels: + operator.ibm.com/managedByCsOperator: "true" + annotations: + version: {{ .Version }} +spec: + services: + - name: ibm-user-management-operator + resources: + - apiVersion: operator.ibm.com/v1alpha1 + labels: + app.kubernetes.io/created-by: ibm-user-management-operator + app.kubernetes.io/instance: accountiam-sample + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: accountiam + app.kubernetes.io/part-of: ibm-user-management-operator + kind: AccountIAM + name: accountiam-sample + - apiVersion: operator.ibm.com/v1alpha1 + data: + spec: + bindings: + public-account-iam-config-dev: + configmap: account-iam-env-configmap-dev + public-bootstrap-creds: + secret: user-mgmt-bootstrap + public-ibmcloudca-secret: + secret: ibmcloud-cluster-ca-secret + public-mcsp-integration-details: + secret: mcsp-im-integration-details + description: Binding information that should be accessible to User Management adopters + operand: ibm-user-management-operator + registry: common-service + registryNamespace: {{ .ServicesNs }} + force: true + kind: OperandBindInfo + name: ibm-user-mgmt-bindinfo ` IdpConfigUIOpCon = ` @@ -324,6 +556,26 @@ spec: commonWebUI: {} switcheritem: {} navconfiguration: {} + - name: ibm-idp-config-ui-operator-v4.3 + spec: + commonWebUI: {} + switcheritem: {} + navconfiguration: {} + - name: ibm-idp-config-ui-operator-v4.4 + spec: + commonWebUI: {} + switcheritem: {} + navconfiguration: {} + - name: ibm-idp-config-ui-operator-v4.5 + spec: + commonWebUI: {} + switcheritem: {} + navconfiguration: {} + - name: ibm-idp-config-ui-operator-v4.6 + spec: + commonWebUI: {} + switcheritem: {} + navconfiguration: {} ` PlatformUIOpCon = ` @@ -339,12 +591,72 @@ metadata: spec: services: - name: ibm-platformui-operator-v4.0 + resources: + - apiVersion: apps/v1 + force: true + kind: Deployment + labels: + operator.ibm.com/opreq-control: 'true' + name: meta-api-deploy + namespace: "{{ .CPFSNs }}" spec: operandBindInfo: {} - name: ibm-platformui-operator-v4.1 + resources: + - apiVersion: apps/v1 + force: true + kind: Deployment + labels: + operator.ibm.com/opreq-control: 'true' + name: meta-api-deploy + namespace: "{{ .CPFSNs }}" spec: operandBindInfo: {} - name: ibm-platformui-operator-v4.2 + resources: + - apiVersion: apps/v1 + force: true + kind: Deployment + labels: + operator.ibm.com/opreq-control: 'true' + name: meta-api-deploy + namespace: "{{ .CPFSNs }}" + spec: + operandBindInfo: {} + - name: ibm-platformui-operator-v4.3 + resources: + - apiVersion: apps/v1 + force: true + kind: Deployment + labels: + operator.ibm.com/opreq-control: 'true' + name: meta-api-deploy + namespace: "{{ .CPFSNs }}" + spec: + operandBindInfo: {} + - name: ibm-platformui-operator-v4.4 + resources: + - apiVersion: apps/v1 + force: true + kind: Deployment + labels: + operator.ibm.com/opreq-control: 'true' + name: meta-api-deploy + namespace: "{{ .CPFSNs }}" + spec: + operandBindInfo: {} + - name: ibm-platformui-operator-v6.0 + resources: + - apiVersion: apps/v1 + force: true + kind: Deployment + labels: + operator.ibm.com/opreq-control: 'true' + name: meta-api-deploy + namespace: "{{ .CPFSNs }}" + spec: + operandBindInfo: {} + - name: ibm-platformui-operator-v6.1 spec: operandBindInfo: {} ` @@ -373,7 +685,7 @@ spec: - name: edb-keycloak registry: common-service registryNamespace: {{ .ServicesNs }} - force: false + force: true kind: OperandRequest name: edb-keycloak-request - apiVersion: operator.ibm.com/v1alpha1 @@ -382,464 +694,260 @@ spec: bindings: public-keycloak-tls-secret: secret: cs-keycloak-tls-secret + public-cs-keycloak-route: + configmap: cs-keycloak-route + public-cs-keycloak-service: + configmap: cs-keycloak-service description: Binding information that should be accessible to Keycloak adopters operand: keycloak-operator registry: common-service registryNamespace: {{ .ServicesNs }} - force: false + force: true kind: OperandBindInfo name: keycloak-bindinfo - - apiVersion: cert-manager.io/v1 - kind: Certificate - name: cs-keycloak-tls-cert - data: - spec: - commonName: cs-keycloak-service - dnsNames: - - cs-keycloak-service - - cs-keycloak-service.{{ .ServicesNs }} - - cs-keycloak-service.{{ .ServicesNs }}.svc - - cs-keycloak-service.{{ .ServicesNs }}.svc.cluster.local - issuerRef: - kind: Issuer - name: cs-ca-issuer - secretName: cs-keycloak-tls-secret - apiVersion: v1 kind: ConfigMap - force: false - name: keycloak-bindinfo - namespace: {{ .OperatorNs }} + name: cs-keycloak-entrypoint data: data: - keycloak-bindinfo.yaml: | - route: - name: keycloak - configmap: keycloak-bindinfo-cs-keycloak-route - data: - HOSTNAME: https://+.spec.host - TERMINATION: .spec.tls.termination - BACKEND_SERVICE: .spec.to.name - service: - name: cs-keycloak-service - configmap: keycloak-bindinfo-cs-keycloak-service - data: - PORT: .spec.ports[0].port - CLUSTER_IP: .spec.clusterIP - SERVICE_NAME: .metadata.name - SERVICE_NAMESPACE: .metadata.namespace - SERVICE_ENDPOINT: https://+.metadata.name+.+.metadata.namespace+.+svc:+.spec.ports[0].port + cs-keycloak-entrypoint.sh: | + #!/usr/bin/env bash + CA_DIR=/mnt/trust-ca + USERPROFILE_DIR=/mnt/user-profile + TRUSTSTORE_DIR=/mnt/truststore + echo "Building the truststore file ..." + cp /etc/pki/java/cacerts ${TRUSTSTORE_DIR}/keycloak-truststore.jks + chmod +w ${TRUSTSTORE_DIR}/keycloak-truststore.jks + echo "Importing default service account certificates ..." + index=0 + while read -r line; do + if [ "$line" = "-----BEGIN CERTIFICATE-----" ]; then + echo "$line" > ${TRUSTSTORE_DIR}/temp_cert.pem + elif [ "$line" = "-----END CERTIFICATE-----" ]; then + echo "$line" >> ${TRUSTSTORE_DIR}/temp_cert.pem + let "index++" + echo "Importing service account certificate entry number ${index} ..." + keytool -importcert -alias "serviceaccount-ca-crt_$index" -file ${TRUSTSTORE_DIR}/temp_cert.pem -keystore ${TRUSTSTORE_DIR}/keycloak-truststore.jks -storepass changeit -noprompt + rm -f ${TRUSTSTORE_DIR}/temp_cert.pem + else + echo "$line" >> ${TRUSTSTORE_DIR}/temp_cert.pem + fi + done < /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + for cert in $(ls ${CA_DIR}); do + echo "Importing ${cert} into the truststore file ..." + keytool -importcert -file ${CA_DIR}/${cert} -keystore ${TRUSTSTORE_DIR}/keycloak-truststore.jks -storepass changeit -alias ${cert} -noprompt + done + echo "Truststore file built, starting Keycloak ..." + "/opt/keycloak/bin/kc.sh" "$@" --spi-truststore-file-file=${TRUSTSTORE_DIR}/keycloak-truststore.jks --spi-truststore-file-password=changeit --spi-truststore-file-hostname-verification-policy=WILDCARD --spi-user-profile-declarative-user-profile-config-file=${USERPROFILE_DIR}/cs-keycloak-user-profile.json - apiVersion: v1 - kind: ConfigMap - name: keycloak-setup-script - namespace: {{ .OperatorNs }} data: - data: - keycloak-setup-script.sh: | - #!/usr/bin/env bash - # - # Copyright 2023 IBM Corporation - # - # Licensed under the Apache License, Version 2.0 (the "License"); - # you may not use this file except in compliance with the License. - # You may obtain a copy of the License at - # - # http://www.apache.org/licenses/LICENSE-2.0 - # - # Unless required by applicable law or agreed to in writing, software - # distributed under the License is distributed on an "AS IS" BASIS, - # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - # See the License for the specific language governing permissions and - # limitations under the License. - # - - # create Certificates for Keycloak - # wait for Secret - # Get secret - # Wait for ODLM to create KeyCloak CR, refresh KeyCloak CR annotation, so it could reload the secret - # Wait for Route to be created(needs to verify if it supports Customization other than what is defined in ODLM template) - # Load Certificate into Route - - - set -o pipefail - set -o errtrace - set -o nounset - - resource_namespace=$(oc get commonservice common-service -n $OPERATOR_NAMESPACE -o jsonpath='{.spec.servicesNamespace}') - if [ -z "$WATCH_NAMESPACE" ] || [ "$WATCH_NAMESPACE" == "''" ]; then - config_namespace_list=$resource_namespace - else - config_namespace_list=$WATCH_NAMESPACE - fi - - function main() { - # # create Certificates for Keycloak - # title "Create Certificates for Keycloak in namespace $resource_namespace" - # cat </dev/null 2>&1 - if [ $? -eq 0 ]; then - success "Secret cs-keycloak-tls-secret found in namespace $resource_namespace" - break - else - if [ $i -eq 30 ]; then - error "Secret cs-keycloak-tls-secret not found in namespace $resource_namespace" - fi - warning "Secret cs-keycloak-tls-secret not found in namespace $resource_namespace, retrying in 10 seconds..." - sleep 10 - fi - done - - # wait for secret keycloak-edb-cluster-app and raise error msg if it does not exist after 5 minutes - title "Wait for Secret keycloak-edb-cluster-app in namespace $resource_namespace" - for i in {1..30}; do - oc get secret keycloak-edb-cluster-app -n "$resource_namespace" >/dev/null 2>&1 - if [ $? -eq 0 ]; then - success "Secret keycloak-edb-cluster-app found in namespace $resource_namespace" - break - else - if [ $i -eq 30 ]; then - error "Secret keycloak-edb-cluster-app not found in namespace $resource_namespace" - fi - warning "Secret keycloak-edb-cluster-app not found in namespace $resource_namespace, retrying in 10 seconds..." - sleep 10 - fi - done - - # Wait for KeyCloak CR named cs-keycloak to be created - title "Wait for KeyCloak CR named cs-keycloak to be created in namespace $resource_namespace" - for i in {1..30}; do - oc get keycloak cs-keycloak -n "$resource_namespace" >/dev/null 2>&1 - if [ $? -eq 0 ]; then - success "KeyCloak CR named cs-keycloak found in namespace $resource_namespace" - break - else - if [ $i -eq 30 ]; then - error "KeyCloak CR named cs-keycloak not found in namespace $resource_namespace" - fi - warning "KeyCloak CR named cs-keycloak not found in namespace $resource_namespace, retrying in 10 seconds..." - sleep 10 - fi - done - - # Refresh KeyCloak CR annotation to allow it to reload the secret - title "Refresh KeyCloak CR annotation to allow it to reload the secret" - oc patch keycloak cs-keycloak -n "$resource_namespace" --type merge -p '{"metadata":{"annotations":{"operator.ibm.com/reloaded-for-tls-secret":"'"$(date '+%Y-%m-%dT%T')"'"}}}' - - ca_crt=$(oc get secret cs-keycloak-tls-secret -n "$resource_namespace" -o jsonpath='{.data.ca\.crt}' | base64 -d) - # Create a route for KeyCloak named keycloak - title "Create a route for KeyCloak named keycloak" - # store contect of route yaml into a file - cat </tmp/configmap.yaml - apiVersion: v1 - kind: ConfigMap - metadata: - name: $configmap_name - namespace: $config_namespace - data: - EOF - - while read -r field; do - key=$(echo "$field" | awk -F ': ' '{print $1}') - complete_path=$(echo "$field" | awk -F ': ' '{print $2}') - echo $complete_path - value="" - parse_schema "$kind" "$resource_name" "$resource_namespace" "$complete_path" value - echo " $key: '$value'" >> /tmp/configmap.yaml - done <<< "$data_fields" - - oc apply -f /tmp/configmap.yaml - - echo "ConfigMap $resource_name created in namespace $config_namespace" - } - - while true; do - if [ -z "$WATCH_NAMESPACE" ] || [ "$WATCH_NAMESPACE" == "''" ]; then - config_namespace_list=$(oc get OperandRequest --all-namespaces -o custom-columns='NAMESPACE:.metadata.namespace' --no-headers | tr '\n' ',' | sed 's/,$//') - else - config_namespace_list=$WATCH_NAMESPACE - fi - while IFS=',' read -ra kind; do - for i in "${kind[@]}"; do - echo $i - resource_name=$(echo "$config_yaml" | yq eval ".$i.name" -) - configmap_name=$(echo "$config_yaml" | yq eval ".$i.configmap" -) - data_fields=$(echo "$config_yaml" | yq eval ".$i.data" -) - - # check if this resource already exists - oc get $i "$resource_name" -n "$resource_namespace" >/dev/null 2>&1 - if [ $? -ne 0 ]; then - echo "Resource $i/$resource_name does not exist in namespace $resource_namespace, skipping..." - continue - fi - - while IFS=',' read -ra config_namespace; do - for j in "${config_namespace[@]}"; do - create_configmap "$i" "$resource_name" "$resource_namespace" "$configmap_name" "$j" "$data_fields" - done - done <<< "$config_namespace_list" - - done - done <<< "$KIND_LIST" - sleep 120 - done - - apiVersion: apps/v1 - kind: Deployment - name: keycloak-bindinfo-deployment - namespace: {{ .OperatorNs }} - force: false + labels: + operator.ibm.com/opreq-control: 'true' + operator.ibm.com/watched-by-cert-manager: '' + data: + stringData: + ca.crt: + templatingValueFrom: + configMapKeyRef: + key: service-ca.crt + name: openshift-service-ca.crt + required: true + tls.crt: + templatingValueFrom: + required: true + secretKeyRef: + key: tls.crt + name: cpfs-opcon-cs-keycloak-tls-secret + tls.key: + templatingValueFrom: + required: true + secretKeyRef: + key: tls.key + name: cpfs-opcon-cs-keycloak-tls-secret + type: kubernetes.io/tls + force: true + kind: Secret + name: cs-keycloak-tls-secret + - apiVersion: route.openshift.io/v1 data: spec: - replicas: 1 - selector: - matchLabels: - app: keycloak-bindinfo - template: - metadata: - labels: - app: keycloak-bindinfo - spec: - containers: - - name: keycloak-bindinfo-container - image: icr.io/cpopen/cpfs/cpfs-utils:latest - command: ["/bin/bash"] - args: ["-c", "/bindinfo-script/keycloak-bindinfo-script.sh"] - volumeMounts: - - name: keycloak-bindinfo-data - mountPath: /bindinfo-data - - name: keycloak-bindinfo-script - mountPath: /bindinfo-script - env: - - name: OPERATOR_NAMESPACE - valueFrom: - fieldRef: - apiVersion: v1 - fieldPath: metadata.namespace - - name: WATCH_NAMESPACE - valueFrom: - configMapKeyRef: - name: namespace-scope - key: namespaces - optional: true - securityContext: - runAsNonRoot: true - seccompProfile: - type: RuntimeDefault - capabilities: - drop: - - ALL - allowPrivilegeEscalation: false - volumes: - - name: keycloak-bindinfo-data - configMap: - name: keycloak-bindinfo - items: - - key: keycloak-bindinfo.yaml - path: keycloak-bindinfo.yaml - - name: keycloak-bindinfo-script - configMap: - name: keycloak-bindinfo-script - defaultMode: 0777 - items: - - key: keycloak-bindinfo-script.sh - path: keycloak-bindinfo-script.sh - securityContext: - runAsNonRoot: true - seccompProfile: - type: RuntimeDefault - serviceAccountName: operand-deployment-lifecycle-manager + host: + templatingValueFrom: + configMapKeyRef: + key: keycloak_route_name + name: ibm-cpp-config + port: + targetPort: 8443 + tls: + caCertificate: + templatingValueFrom: + secretKeyRef: + key: ca.crt + name: keycloak-custom-tls-secret + certificate: + templatingValueFrom: + secretKeyRef: + key: tls.crt + name: keycloak-custom-tls-secret + destinationCACertificate: + templatingValueFrom: + required: true + secretKeyRef: + key: ca.crt + name: cs-keycloak-tls-secret + key: + templatingValueFrom: + secretKeyRef: + key: tls.key + name: keycloak-custom-tls-secret + termination: reencrypt + to: + kind: Service + name: cpfs-opcon-cs-keycloak-service + wildcardPolicy: None + force: true + kind: Route + name: keycloak - apiVersion: k8s.keycloak.org/v2alpha1 data: spec: + proxy: + headers: xforwarded + features: + enabled: + - token-exchange + - admin-fine-grained-authz db: host: keycloak-edb-cluster-rw passwordSecret: @@ -850,33 +958,204 @@ spec: name: keycloak-edb-cluster-app vendor: postgres hostname: - strict: false + hostname: + templatingValueFrom: + objectRef: + apiVersion: route.openshift.io/v1 + kind: Route + name: keycloak + path: .spec.host + required: true http: tlsSecret: cs-keycloak-tls-secret ingress: - className: openshift-default - enabled: true - instances: 1 + enabled: false unsupported: podTemplate: + metadata: + annotations: + cloudpakThemesVersion: + templatingValueFrom: + objectRef: + apiVersion: v1 + kind: ConfigMap + name: cs-keycloak-theme + path: .metadata.annotations.themesVersion + required: true spec: containers: - - resources: - limits: - cpu: 1000m - memory: 1Gi - requests: - cpu: 1000m - memory: 1Gi - force: false + - command: + - /bin/sh + - /mnt/startup/cs-keycloak-entrypoint.sh + volumeMounts: + - mountPath: /mnt/truststore + name: truststore-volume + - mountPath: /mnt/startup + name: startup-volume + - mountPath: /mnt/trust-ca + name: trust-ca-volume + - mountPath: /opt/keycloak/providers + name: cs-keycloak-theme + - mountPath: /mnt/user-profile + name: user-profile-volume + volumes: + - name: truststore-volume + emptyDir: + sizeLimit: 2Mi + - name: startup-volume + configMap: + name: cs-keycloak-entrypoint + - name: trust-ca-volume + configMap: + name: cs-keycloak-ca-certs + optional: true + - name: cs-keycloak-theme + configMap: + items: + - key: cloudpak-theme.jar + path: cloudpak-theme.jar + name: cs-keycloak-theme + - name: user-profile-volume + configMap: + name: cs-keycloak-user-profile + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/arch + operator: In + values: + - amd64 + - ppc64le + - s390x + force: true kind: Keycloak name: cs-keycloak + optionalFields: + - path: .spec.unsupported.podTemplate.spec.containers[0].resources + operation: remove + matchExpressions: + - objectRef: + name: keycloaks.k8s.keycloak.org + apiVersion: apiextensions.k8s.io/v1 + kind: CustomResourceDefinition + key: .spec.versions[0].schema.openAPIV3Schema.properties.spec.properties.resources + operator: Exists + - path: .spec.resources + operation: remove + matchExpressions: + - objectRef: + name: keycloaks.k8s.keycloak.org + apiVersion: apiextensions.k8s.io/v1 + kind: CustomResourceDefinition + key: .spec.versions[0].schema.openAPIV3Schema.properties.spec.properties.resources + operator: DoesNotExist + - apiVersion: v1 + kind: ConfigMap + force: true + name: cs-keycloak-route + data: + data: + HOSTNAME: + templatingValueFrom: + objectRef: + apiVersion: route.openshift.io/v1 + kind: Route + name: keycloak + path: https://+.spec.host + required: true + TERMINATION: + templatingValueFrom: + objectRef: + apiVersion: route.openshift.io/v1 + kind: Route + name: keycloak + path: .spec.tls.termination + required: true + BACKEND_SERVICE: + templatingValueFrom: + objectRef: + apiVersion: route.openshift.io/v1 + kind: Route + name: keycloak + path: .spec.to.name + required: true + - apiVersion: v1 + kind: ConfigMap + force: true + name: cs-keycloak-service + data: + data: + PORT: + templatingValueFrom: + objectRef: + apiVersion: v1 + kind: Service + name: cpfs-opcon-cs-keycloak-service + path: .spec.ports[0].port + required: true + CLUSTER_IP: + templatingValueFrom: + objectRef: + apiVersion: v1 + kind: Service + name: cpfs-opcon-cs-keycloak-service + path: .spec.clusterIP + required: true + SERVICE_NAME: + templatingValueFrom: + objectRef: + apiVersion: v1 + kind: Service + name: cpfs-opcon-cs-keycloak-service + path: .metadata.name + required: true + SERVICE_NAMESPACE: {{ .ServicesNs }} + SERVICE_ENDPOINT: + templatingValueFrom: + objectRef: + apiVersion: v1 + kind: Service + name: cpfs-opcon-cs-keycloak-service + path: https://+.metadata.name+.+.metadata.namespace+.+svc:+.spec.ports[0].port + - apiVersion: k8s.keycloak.org/v2alpha1 + kind: KeycloakRealmImport + name: cs-cloudpak-realm + force: true + ownerReferences: + - apiVersion: k8s.keycloak.org/v2alpha1 + kind: Keycloak + name: cs-keycloak + controller: false + data: + spec: + keycloakCRName: cs-keycloak + realm: + displayName: IBM Cloud Pak + displayNameHtml: "
IBM Cloud Pak
" + enabled: true + id: cloudpak + realm: cloudpak + ssoSessionIdleTimeout: 43200 + ssoSessionMaxLifespan: 43200 + rememberMe: true + passwordPolicy: "length(15) and notUsername(undefined) and notEmail(undefined)" + loginTheme: cloudpak + adminTheme: cloudpak + accountTheme: cloudpak + emailTheme: cloudpak + internationalizationEnabled: true + supportedLocales: [ "en", "de" , "es", "fr", "it", "ja", "ko", "pt_BR", "zh_CN", "zh_TW"] - name: edb-keycloak resources: - apiVersion: batch/v1 kind: Job + force: true name: create-postgres-license-config namespace: "{{ .OperatorNs }}" + labels: + operator.ibm.com/opreq-control: 'true' data: spec: activeDeadlineSeconds: 600 @@ -915,7 +1194,14 @@ spec: data: EDB_LICENSE_KEY: $(base64 /license_keys/edb/EDB_LICENSE_KEY | tr -d '\n') EOF - image: cp.icr.io/cp/cpd/edb-postgres-license-provider@sha256:e683c4bfceb5a99f7971409d4028cf326cdedb007f9cf3daf28b8141835535f1 + image: + templatingValueFrom: + default: + required: true + configMapKeyRef: + name: cloud-native-postgresql-image-list + key: edb-postgres-license-provider-image + namespace: {{ .OperatorNs }} name: edb-license resources: limits: @@ -935,10 +1221,18 @@ spec: - command: - bash - '-c' - - >- + args: + - | kubectl delete pods -l app.kubernetes.io/name=cloud-native-postgresql - image: >- - cp.icr.io/cp/cpd/edb-postgres-license-provider@sha256:e683c4bfceb5a99f7971409d4028cf326cdedb007f9cf3daf28b8141835535f1 + kubectl annotate secret postgresql-operator-controller-manager-config ibm-license-key-applied="EDB Database with IBM License Key" + image: + templatingValueFrom: + default: + required: true + configMapKeyRef: + name: cloud-native-postgresql-image-list + key: edb-postgres-license-provider-image + namespace: {{ .OperatorNs }} name: restart-edb-pod resources: limits: @@ -961,39 +1255,423 @@ spec: securityContext: runAsNonRoot: true serviceAccountName: edb-license-sa + - apiVersion: v1 + kind: ServiceAccount + name: edb-license-sa + namespace: "{{ .OperatorNs }}" + - apiVersion: rbac.authorization.k8s.io/v1 + kind: Role + name: edb-license-role + namespace: "{{ .OperatorNs }}" + data: + rules: + - apiGroups: + - "" + resources: + - pods + - secrets + verbs: + - create + - update + - patch + - get + - list + - delete + - watch + - apiVersion: rbac.authorization.k8s.io/v1 + kind: RoleBinding + name: edb-license-rolebinding + namespace: "{{ .OperatorNs }}" + data: + subjects: + - kind: ServiceAccount + name: edb-license-sa + roleRef: + kind: Role + name: edb-license-role + apiGroup: rbac.authorization.k8s.io - apiVersion: postgresql.k8s.enterprisedb.io/v1 data: spec: + inheritedMetadata: + annotations: + backup.velero.io/backup-volumes: pgdata,pg-wal + labels: + foundationservices.cloudpak.ibm.com: keycloak + description: + templatingValueFrom: + objectRef: + apiVersion: v1 + kind: Secret + name: postgresql-operator-controller-manager-config + path: .metadata.annotations.ibm-license-key-applied + namespace: {{ .OperatorNs }} + required: true bootstrap: initdb: database: keycloak owner: app - imageName: >- - icr.io/cpopen/edb/postgresql:14.7@sha256:d2e21251c5b0e3a4a45bdef592f9293e258124793b529e622808dc010900b7ea + imageName: + templatingValueFrom: + default: + required: true + configMapKeyRef: + name: cloud-native-postgresql-image-list + key: ibm-postgresql-14-operand-image + namespace: {{ .OperatorNs }} + configMapKeyRef: + name: ibm-cpp-config + key: edb-keycloak-operand-image imagePullSecrets: - name: ibm-entitlement-key - instances: 1 - resources: - limits: - cpu: 1000m - memory: 1Gi - requests: - cpu: 1000m - memory: 1Gi logLevel: info primaryUpdateStrategy: unsupervised + primaryUpdateMethod: switchover + enableSuperuserAccess: true + replicationSlots: + highAvailability: + enabled: false storage: size: 1Gi walStorage: size: 1Gi - force: false + force: true + annotations: + k8s.enterprisedb.io/addons: '["velero"]' + k8s.enterprisedb.io/snapshotAllowColdBackupOnPrimary: enabled + productID: 068a62892a1e4db39641342e592daa25 + productMetric: FREE + productName: IBM Cloud Platform Common Services + labels: + foundationservices.cloudpak.ibm.com: keycloak kind: Cluster name: keycloak-edb-cluster ` ) const ( - CSV2OpReg = ` + CommonServicePGOpCon = ` +apiVersion: operator.ibm.com/v1alpha1 +kind: OperandConfig +metadata: + name: common-service + namespace: "{{ .ServicesNs }}" + labels: + operator.ibm.com/managedByCsOperator: "true" + annotations: + version: {{ .Version }} +spec: + services: + - name: common-service-postgresql + resources: + - apiVersion: operator.ibm.com/v1alpha1 + data: + spec: + requests: + - operands: + - name: cloud-native-postgresql-v1.22 + registry: common-service + registryNamespace: {{ .ServicesNs }} + force: true + kind: OperandRequest + name: postgresql-operator-request + - apiVersion: cert-manager.io/v1 + kind: Certificate + name: common-service-db-replica-tls-cert + labels: + app.kubernetes.io/component: common-service-db-replica-tls-cert + component: common-service-db-replica-tls-cert + data: + spec: + commonName: streaming_replica + duration: 2160h0m0s + issuerRef: + kind: Issuer + name: cs-ca-issuer + renewBefore: 720h0m0s + secretName: common-service-db-replica-tls-secret + secretTemplate: + labels: + k8s.enterprisedb.io/reload: '' + usages: + - client auth + - apiVersion: cert-manager.io/v1 + kind: Certificate + labels: + app.kubernetes.io/component: common-service-db-tls-cert + component: common-service-db-tls-cert + name: common-service-db-tls-cert + data: + spec: + dnsNames: + - common-service-db + - common-service-db.{{ .ServicesNs }} + - common-service-db.{{ .ServicesNs }}.svc + - common-service-db-r + - common-service-db-r.{{ .ServicesNs }} + - common-service-db-r.{{ .ServicesNs }}.svc + - common-service-db-ro + - common-service-db-ro.{{ .ServicesNs }} + - common-service-db-ro.{{ .ServicesNs }}.svc + - common-service-db-rw + - common-service-db-rw.{{ .ServicesNs }} + - common-service-db-rw.{{ .ServicesNs }}.svc + duration: 8760h0m0s + issuerRef: + kind: Issuer + name: cs-ca-issuer + renewBefore: 720h0m0s + secretName: common-service-db-tls-secret + secretTemplate: + labels: + k8s.enterprisedb.io/reload: '' + usages: + - server auth + - apiVersion: cert-manager.io/v1 + kind: Certificate + name: common-service-db-im-tls-cert + data: + spec: + commonName: im_user + duration: 2160h0m0s + issuerRef: + kind: Issuer + name: cs-ca-issuer + renewBefore: 720h0m0s + secretName: common-service-db-im-tls-secret + secretTemplate: + labels: + app.kubernetes.io/instance: common-service-db-im-tls-secret + app.kubernetes.io/name: common-service-db-im-tls-secret + usages: + - client auth + - apiVersion: cert-manager.io/v1 + kind: Certificate + name: common-service-db-zen-tls-cert + data: + spec: + commonName: zen_user + duration: 2160h0m0s + issuerRef: + kind: Issuer + name: cs-ca-issuer + renewBefore: 720h0m0s + secretName: common-service-db-zen-tls-secret + secretTemplate: + labels: + app.kubernetes.io/instance: common-service-db-zen-tls-secret + app.kubernetes.io/name: common-service-db-zen-tls-secret + usages: + - client auth + - apiVersion: operator.ibm.com/v1alpha1 + data: + spec: + bindings: + protected-cloudpak-db: + secret: common-service-db-app + protected-zen-db: + configmap: common-service-db-zen + secret: common-service-db-zen-tls-secret + protected-im-db: + configmap: common-service-db-im + secret: common-service-db-im-tls-secret + private-superuser-db: + secret: common-service-db-superuser + description: Binding information that should be accessible to Common Service Postgresql Adopters + operand: common-service-postgresql + registry: common-service + registryNamespace: {{ .ServicesNs }} + force: true + kind: OperandBindInfo + name: common-service-postgresql-bindinfo + - apiVersion: postgresql.k8s.enterprisedb.io/v1 + kind: Cluster + name: common-service-db + force: true + annotations: + productID: 068a62892a1e4db39641342e592daa25 + productMetric: FREE + productName: IBM Cloud Platform Common Services + labels: + foundationservices.cloudpak.ibm.com: cs-db + data: + spec: + inheritedMetadata: + labels: + foundationservices.cloudpak.ibm.com: cs-db + description: + templatingValueFrom: + objectRef: + apiVersion: v1 + kind: Secret + name: postgresql-operator-controller-manager-config + path: .metadata.annotations.ibm-license-key-applied + namespace: {{ .OperatorNs }} + required: true + bootstrap: + initdb: + database: cloudpak + owner: cpadmin + dataChecksums: true + postInitApplicationSQL: + - CREATE USER im_user + - CREATE DATABASE im OWNER im_user + - GRANT ALL PRIVILEGES ON DATABASE im TO im_user + - CREATE USER zen_user + - CREATE DATABASE zen OWNER zen_user + - GRANT ALL PRIVILEGES ON DATABASE zen TO zen_user + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/arch + operator: In + values: + - amd64 + - ppc64le + - s390x + additionalPodAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: k8s.enterprisedb.io/cluster + operator: In + values: + - common-service-db + topologyKey: kubernetes.io/hostname + weight: 50 + podAntiAffinityType: preferred + topologyKey: topology.kubernetes.io/zone + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + - maxSkew: 1 + topologyKey: topology.kubernetes.io/region + whenUnsatisfiable: ScheduleAnyway + imageName: + templatingValueFrom: + default: + required: true + configMapKeyRef: + name: cloud-native-postgresql-image-list + key: ibm-postgresql-16-operand-image + namespace: {{ .OperatorNs }} + imagePullSecrets: + - name: ibm-entitlement-key + logLevel: info + primaryUpdateStrategy: unsupervised + primaryUpdateMethod: switchover + enableSuperuserAccess: true + replicationSlots: + highAvailability: + enabled: true + certificates: + clientCASecret: cs-ca-certificate-secret + replicationTLSSecret: common-service-db-replica-tls-secret + serverCASecret: cs-ca-certificate-secret + serverTLSSecret: common-service-db-tls-secret + startDelay: 120 + stopDelay: 90 + storage: + resizeInUseVolumes: true + size: 10Gi + walStorage: + resizeInUseVolumes: true + size: 10Gi + postgresql: + parameters: + track_activities: "on" + track_counts: "on" + track_io_timing: "on" + pg_stat_statements.track: all + pg_stat_statements.max: "10000" + max_slot_wal_keep_size: "8GB" + pg_hba: + - hostssl cloudpak cpadmin all cert + - hostssl im im_user all cert + - hostssl zen zen_user all cert + - host zen instana_user all scram-sha-256 + - host im instana_user all scram-sha-256 + - apiVersion: v1 + kind: ConfigMap + force: true + name: common-service-db-zen + data: + data: + IS_EMBEDDED: 'true' + DATABASE_PORT: + templatingValueFrom: + objectRef: + apiVersion: v1 + kind: Service + name: common-service-db-rw + path: .spec.ports[0].port + required: true + DATABASE_R_ENDPOINT: + templatingValueFrom: + objectRef: + apiVersion: v1 + kind: Service + name: common-service-db-r + path: .metadata.name+.+.metadata.namespace+.+svc + required: true + DATABASE_RW_ENDPOINT: + templatingValueFrom: + objectRef: + apiVersion: v1 + kind: Service + name: common-service-db-rw + path: .metadata.name+.+.metadata.namespace+.+svc + required: true + DATABASE_NAME: zen + DATABASE_USER: zen_user + DATABASE_CA_CERT: ca.crt + DATABASE_CLIENT_KEY: tls.key + DATABASE_CLIENT_CERT: tls.crt + - apiVersion: v1 + kind: ConfigMap + force: true + name: common-service-db-im + data: + data: + IS_EMBEDDED: 'true' + DATABASE_PORT: + templatingValueFrom: + objectRef: + apiVersion: v1 + kind: Service + name: common-service-db-rw + path: .spec.ports[0].port + required: true + DATABASE_R_ENDPOINT: + templatingValueFrom: + objectRef: + apiVersion: v1 + kind: Service + name: common-service-db-r + path: .metadata.name+.+.metadata.namespace+.+svc + required: true + DATABASE_RW_ENDPOINT: + templatingValueFrom: + objectRef: + apiVersion: v1 + kind: Service + name: common-service-db-rw + path: .metadata.name+.+.metadata.namespace+.+svc + required: true + DATABASE_NAME: im + DATABASE_USER: im_user + DATABASE_CA_CERT: ca.crt + DATABASE_CLIENT_KEY: tls.key + DATABASE_CLIENT_CERT: tls.crt +` +) + +const ( + CSV3OpReg = ` apiVersion: operator.ibm.com/v1alpha1 kind: OperandRegistry metadata: @@ -1003,7 +1681,8 @@ metadata: operator.ibm.com/managedByCsOperator: "true" annotations: version: "{{ .Version }}" - excluded-catalogsource: certified-operators,community-operators,redhat-marketplace,redhat-operators,ibm-cp-automation-foundation-catalog,operatorhubio-catalog + excluded-catalogsource: {{ .ExcludedCatalog }} + status-monitored-services: {{ .StatusMonitoredServices }} spec: operators: - name: ibm-licensing-operator @@ -1012,16 +1691,12 @@ spec: packageName: ibm-licensing-operator-app scope: public installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" installMode: no-op - name: ibm-mongodb-operator namespace: "{{ .ServicesNs }}" channel: v3.23 packageName: ibm-mongodb-operator-app installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" installMode: no-op - name: ibm-cert-manager-operator namespace: "{{ .ServicesNs }}" @@ -1029,8 +1704,6 @@ spec: packageName: ibm-cert-manager-operator scope: public installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" installMode: no-op - name: ibm-iam-operator namespace: "{{ .ServicesNs }}" @@ -1038,8 +1711,6 @@ spec: packageName: ibm-iam-operator scope: public installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" installMode: no-op - name: ibm-healthcheck-operator namespace: "{{ .ServicesNs }}" @@ -1047,8 +1718,6 @@ spec: packageName: ibm-healthcheck-operator-app scope: public installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" installMode: no-op - name: ibm-commonui-operator namespace: "{{ .ServicesNs }}" @@ -1056,8 +1725,6 @@ spec: packageName: ibm-commonui-operator-app scope: public installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" installMode: no-op - name: ibm-management-ingress-operator namespace: "{{ .ServicesNs }}" @@ -1065,8 +1732,6 @@ spec: packageName: ibm-management-ingress-operator-app scope: public installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" installMode: no-op - name: ibm-ingress-nginx-operator namespace: "{{ .ServicesNs }}" @@ -1074,8 +1739,6 @@ spec: packageName: ibm-ingress-nginx-operator-app scope: public installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" installMode: no-op - name: ibm-auditlogging-operator namespace: "{{ .ServicesNs }}" @@ -1083,8 +1746,6 @@ spec: packageName: ibm-auditlogging-operator-app scope: public installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" installMode: no-op - name: ibm-platform-api-operator namespace: "{{ .ServicesNs }}" @@ -1092,8 +1753,6 @@ spec: packageName: ibm-platform-api-operator-app scope: public installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" installMode: no-op - channel: v3.23 name: ibm-monitoring-grafana-operator @@ -1101,8 +1760,6 @@ spec: packageName: ibm-monitoring-grafana-operator-app scope: public installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" installMode: no-op - channel: v3.23 name: ibm-zen-operator @@ -1110,12 +1767,17 @@ spec: packageName: ibm-zen-operator scope: public installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" + installMode: no-op + - channel: v3.23 + name: ibm-zen-cpp-operator + namespace: "{{ .CPFSNs }}" + packageName: zen-cpp-operator + scope: public + installPlanApproval: {{ .ApprovalMode }} installMode: no-op ` - CSV3OpReg = ` + CSV4OpReg = ` apiVersion: operator.ibm.com/v1alpha1 kind: OperandRegistry metadata: @@ -1125,54 +1787,87 @@ metadata: operator.ibm.com/managedByCsOperator: "true" annotations: version: {{ .Version }} - excluded-catalogsource: certified-operators,community-operators,redhat-marketplace,redhat-operators,ibm-cp-automation-foundation-catalog,operatorhubio-catalog + excluded-catalogsource: {{ .ExcludedCatalog }} + status-monitored-services: {{ .StatusMonitoredServices }} spec: operators: + - name: ibm-user-management-operator + namespace: "{{ .CPFSNs }}" + channel: v1.0 + packageName: ibm-user-management-operator + scope: public + installPlanApproval: {{ .ApprovalMode }} + - name: ibm-websphere-liberty + namespace: "{{ .CPFSNs }}" + channel: v1.3 + packageName: ibm-websphere-liberty + scope: public + installPlanApproval: {{ .ApprovalMode }} + - name: ibm-redis-cp-operator + namespace: "{{ .CPFSNs }}" + channel: v1.2 + packageName: ibm-redis-cp + scope: public + installPlanApproval: {{ .ApprovalMode }} - name: ibm-im-operator namespace: "{{ .CPFSNs }}" - channel: {{ .Channel }} + channel: v4.10 packageName: ibm-iam-operator scope: public installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" - name: ibm-im-mongodb-operator namespace: "{{ .CPFSNs }}" channel: v4.2 + installMode: no-op packageName: ibm-mongodb-operator-app installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" - channel: v3 name: ibm-events-operator namespace: "{{ .CPFSNs }}" packageName: ibm-events-operator scope: public installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" + - channel: v5.1 + name: ibm-events-operator-v5.1 + namespace: "{{ .CPFSNs }}" + packageName: ibm-events-operator + scope: public + installPlanApproval: {{ .ApprovalMode }} - name: ibm-platformui-operator namespace: "{{ .CPFSNs }}" - channel: {{ .Channel }} + channel: v6.1 packageName: ibm-zen-operator scope: public installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" - name: ibm-idp-config-ui-operator namespace: "{{ .CPFSNs }}" - channel: {{ .Channel }} + channel: v4.7 packageName: ibm-commonui-operator-app scope: public installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" - channel: stable name: cloud-native-postgresql namespace: "{{ .CPFSNs }}" packageName: cloud-native-postgresql scope: public installPlanApproval: {{ .ApprovalMode }} + operatorConfig: cloud-native-postgresql-operator-config + - channel: stable + name: internal-use-only-edb + namespace: "{{ .CPFSNs }}" + packageName: cloud-native-postgresql + scope: public + installPlanApproval: {{ .ApprovalMode }} + installMode: no-op + - channel: stable-v1.22 + fallbackChannels: + - stable + name: cloud-native-postgresql-v1.22 + namespace: "{{ .CPFSNs }}" + packageName: cloud-native-postgresql + scope: public + installPlanApproval: {{ .ApprovalMode }} + operatorConfig: cloud-native-postgresql-operator-config - channel: alpha name: ibm-user-data-services-operator namespace: "{{ .CPFSNs }}" @@ -1185,6 +1880,18 @@ spec: packageName: ibm-bts-operator scope: public installPlanApproval: {{ .ApprovalMode }} + - channel: v3.34 + name: ibm-bts-operator-v3.34 + namespace: "{{ .CPFSNs }}" + packageName: ibm-bts-operator + scope: public + installPlanApproval: {{ .ApprovalMode }} + - channel: v3.35 + name: ibm-bts-operator-v3.35 + namespace: "{{ .CPFSNs }}" + packageName: ibm-bts-operator + scope: public + installPlanApproval: {{ .ApprovalMode }} - channel: v1.3 name: ibm-automation-flink namespace: "{{ .CPFSNs }}" @@ -1197,17 +1904,23 @@ spec: packageName: ibm-automation-elastic scope: public installPlanApproval: {{ .ApprovalMode }} - - channel: v3.23 - name: ibm-zen-cpp-operator + - channel: v1.1 + name: ibm-elasticsearch-operator namespace: "{{ .CPFSNs }}" - packageName: zen-cpp-operator + packageName: ibm-elasticsearch-operator + scope: public + installPlanApproval: {{ .ApprovalMode}} + - channel: v2.0 + name: ibm-opencontent-flink + namespace: "{{ .CPFSNs }}" + packageName: ibm-opencontent-flink scope: public installPlanApproval: {{ .ApprovalMode }} ` ) const ( - CSV2SaasOpReg = ` + CSV3SaasOpReg = ` apiVersion: operator.ibm.com/v1alpha1 kind: OperandRegistry metadata: @@ -1217,7 +1930,8 @@ metadata: operator.ibm.com/managedByCsOperator: "true" annotations: version: {{ .Version }} - excluded-catalogsource: certified-operators,community-operators,redhat-marketplace,redhat-operators,ibm-cp-automation-foundation-catalog,operatorhubio-catalog + excluded-catalogsource: {{ .ExcludedCatalog }} + status-monitored-services: {{ .StatusMonitoredServices }} spec: operators: - name: ibm-licensing-operator @@ -1226,16 +1940,12 @@ spec: packageName: ibm-licensing-operator-app scope: public installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" installMode: no-op - name: ibm-mongodb-operator namespace: "{{ .ServicesNs }}" channel: v3.23 packageName: ibm-mongodb-operator-app installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" installMode: no-op - name: ibm-cert-manager-operator namespace: "{{ .ServicesNs }}" @@ -1243,8 +1953,6 @@ spec: packageName: ibm-cert-manager-operator scope: public installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" installMode: no-op - name: ibm-iam-operator namespace: "{{ .ServicesNs }}" @@ -1252,8 +1960,6 @@ spec: packageName: ibm-iam-operator scope: public installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" installMode: no-op - name: ibm-management-ingress-operator namespace: "{{ .ServicesNs }}" @@ -1261,8 +1967,6 @@ spec: packageName: ibm-management-ingress-operator-app scope: public installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" installMode: no-op - name: ibm-ingress-nginx-operator namespace: "{{ .ServicesNs }}" @@ -1270,8 +1974,6 @@ spec: packageName: ibm-ingress-nginx-operator-app scope: public installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" installMode: no-op - channel: v3.23 name: ibm-zen-operator @@ -1279,14 +1981,13 @@ spec: packageName: ibm-zen-operator scope: public installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" installMode: no-op ` +) - CSV3SaasOpReg = ` +const CSV4OpCon = ` apiVersion: operator.ibm.com/v1alpha1 -kind: OperandRegistry +kind: OperandConfig metadata: name: common-service namespace: "{{ .ServicesNs }}" @@ -1294,80 +1995,15 @@ metadata: operator.ibm.com/managedByCsOperator: "true" annotations: version: {{ .Version }} - excluded-catalogsource: certified-operators,community-operators,redhat-marketplace,redhat-operators,ibm-cp-automation-foundation-catalog,operatorhubio-catalog spec: - operators: - - name: ibm-im-operator - namespace: "{{ .CPFSNs }}" - channel: {{ .Channel }} - packageName: ibm-iam-operator - scope: public - installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" - - name: ibm-im-mongodb-operator - namespace: "{{ .CPFSNs }}" - channel: v4.2s - packageName: ibm-mongodb-operator-app - installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" - - channel: v3 - name: ibm-events-operator - namespace: "{{ .CPFSNs }}" - packageName: ibm-events-operator - scope: public - installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" - - name: ibm-platformui-operator - namespace: "{{ .CPFSNs }}" - channel: {{ .Channel }} - packageName: ibm-zen-operator - scope: public - installPlanApproval: {{ .ApprovalMode }} - sourceName: {{ .CatalogSourceName }} - sourceNamespace: "{{ .CatalogSourceNs }}" - - channel: v3 - name: ibm-bts-operator - namespace: "{{ .CPFSNs }}" - packageName: ibm-bts-operator - scope: public - installPlanApproval: {{ .ApprovalMode }} - - channel: v1.3 - name: ibm-automation-flink - namespace: "{{ .CPFSNs }}" - packageName: ibm-automation-flink - scope: public - installPlanApproval: {{ .ApprovalMode }} - - channel: v1.3 - name: ibm-automation-elastic - namespace: "{{ .CPFSNs }}" - packageName: ibm-automation-elastic - scope: public - installPlanApproval: {{ .ApprovalMode }} -` -) - -const CSV3OpCon = ` -apiVersion: operator.ibm.com/v1alpha1 -kind: OperandConfig -metadata: - name: common-service - namespace: "{{ .ServicesNs }}" - labels: - operator.ibm.com/managedByCsOperator: "true" - annotations: - version: {{ .Version }} -spec: - services: - - name: ibm-licensing-operator - spec: - operandBindInfo: {} - - name: ibm-mongodb-operator - spec: - mongoDB: {} - operandRequest: {} + services: + - name: ibm-licensing-operator + spec: + operandBindInfo: {} + - name: ibm-mongodb-operator + spec: + mongoDB: {} + operandRequest: {} - name: ibm-im-mongodb-operator spec: mongoDB: {} @@ -1379,12 +2015,6 @@ spec: onPremMultipleDeploy: {{ .OnPremMultiEnable }} operandBindInfo: operand: ibm-im-operator - operandRequest: - requests: - - operands: - - name: ibm-im-mongodb-operator - - name: ibm-idp-config-ui-operator - registry: common-service - name: ibm-iam-operator spec: authentication: @@ -1414,6 +2044,9 @@ spec: commonWebUI: {} switcheritem: {} navconfiguration: {} + - name: ibm-cert-manager-operator + spec: + certManager: {} - name: ibm-management-ingress-operator spec: managementIngress: {} @@ -1424,6 +2057,7 @@ spec: nginxIngress: {} - name: ibm-auditlogging-operator spec: + auditLogging: {} operandBindInfo: {} operandRequest: {} - name: ibm-platform-api-operator @@ -1444,6 +2078,8 @@ spec: kind: Job name: create-postgres-license-config namespace: "{{ .OperatorNs }}" + labels: + operator.ibm.com/opreq-control: 'true' data: spec: activeDeadlineSeconds: 600 @@ -1482,7 +2118,14 @@ spec: data: EDB_LICENSE_KEY: $(base64 /license_keys/edb/EDB_LICENSE_KEY | tr -d '\n') EOF - image: cp.icr.io/cp/cpd/edb-postgres-license-provider@sha256:e683c4bfceb5a99f7971409d4028cf326cdedb007f9cf3daf28b8141835535f1 + image: + templatingValueFrom: + default: + required: true + configMapKeyRef: + name: cloud-native-postgresql-image-list + key: edb-postgres-license-provider-image + namespace: {{ .OperatorNs }} name: edb-license resources: limits: @@ -1502,10 +2145,18 @@ spec: - command: - bash - '-c' - - >- + args: + - | kubectl delete pods -l app.kubernetes.io/name=cloud-native-postgresql - image: >- - cp.icr.io/cp/cpd/edb-postgres-license-provider@sha256:e683c4bfceb5a99f7971409d4028cf326cdedb007f9cf3daf28b8141835535f1 + kubectl annotate secret postgresql-operator-controller-manager-config ibm-license-key-applied="EDB Database with IBM License Key" + image: + templatingValueFrom: + default: + required: true + configMapKeyRef: + name: cloud-native-postgresql-image-list + key: edb-postgres-license-provider-image + namespace: {{ .OperatorNs }} name: restart-edb-pod resources: limits: @@ -1563,18 +2214,14 @@ spec: kind: Role name: edb-license-role apiGroup: rbac.authorization.k8s.io - - name: ibm-bts-operator - spec: - operandRequest: - requests: - - operands: - - name: ibm-im-operator - registry: common-service - - name: ibm-zen-operator - spec: - operandBindInfo: {} + - name: cloud-native-postgresql-v1.22 resources: - apiVersion: batch/v1 + kind: Job + name: create-postgres-license-config + namespace: "{{ .OperatorNs }}" + labels: + operator.ibm.com/opreq-control: 'true' data: spec: activeDeadlineSeconds: 600 @@ -1586,146 +2233,144 @@ spec: productMetric: FREE productName: IBM Cloud Platform Common Services spec: + imagePullSecrets: + - name: ibm-entitlement-key affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - - matchExpressions: - - key: kubernetes.io/arch - operator: In - values: - - amd64 - - ppc64le - - s390x + - matchExpressions: + - key: kubernetes.io/arch + operator: In + values: + - amd64 + - ppc64le + - s390x + initContainers: + - command: + - bash + - -c + - | + cat << EOF | kubectl apply -f - + apiVersion: v1 + kind: Secret + type: Opaque + metadata: + name: postgresql-operator-controller-manager-config + data: + EDB_LICENSE_KEY: $(base64 /license_keys/edb/EDB_LICENSE_KEY | tr -d '\n') + EOF + image: + templatingValueFrom: + default: + required: true + configMapKeyRef: + name: cloud-native-postgresql-image-list + key: edb-postgres-license-provider-image + namespace: {{ .OperatorNs }} + name: edb-license + resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 100m + memory: 50Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + readOnlyRootFilesystem: false containers: - - command: - - bash - - '-c' - - bash /setup/pre-zen.sh - env: - - name: common_services_namespace - valueFrom: - fieldRef: - fieldPath: metadata.namespace - image: {{ .ZenOperatorImage }} - name: pre-zen-job - resources: - limits: - cpu: 500m - memory: 512Mi - requests: - cpu: 100m - memory: 50Mi - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - privileged: false - readOnlyRootFilesystem: false + - command: + - bash + - '-c' + args: + - | + kubectl delete pods -l app.kubernetes.io/name=cloud-native-postgresql + kubectl annotate secret postgresql-operator-controller-manager-config ibm-license-key-applied="EDB Database with IBM License Key" + image: + templatingValueFrom: + default: + required: true + configMapKeyRef: + name: cloud-native-postgresql-image-list + key: edb-postgres-license-provider-image + namespace: {{ .OperatorNs }} + name: restart-edb-pod + resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 100m + memory: 50Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + readOnlyRootFilesystem: false + hostIPC: false + hostNetwork: false + hostPID: false restartPolicy: OnFailure securityContext: runAsNonRoot: true - serviceAccount: operand-deployment-lifecycle-manager - serviceAccountName: operand-deployment-lifecycle-manager - terminationGracePeriodSeconds: 30 - force: true - kind: Job - name: pre-zen-operand-config-job + serviceAccountName: edb-license-sa + - apiVersion: v1 + kind: ServiceAccount + name: edb-license-sa namespace: "{{ .OperatorNs }}" - - name: ibm-platformui-operator - spec: - operandBindInfo: {} -` - -const CSV3SaasOpCon = ` -apiVersion: operator.ibm.com/v1alpha1 -kind: OperandConfig -metadata: - name: common-service - namespace: "{{ .ServicesNs }}" - labels: - operator.ibm.com/managedByCsOperator: "true" - annotations: - version: {{ .Version }} -spec: - services: - - name: ibm-licensing-operator - spec: - operandBindInfo: {} - - name: ibm-mongodb-operator - spec: - mongoDB: {} - operandRequest: {} - - name: ibm-im-mongodb-operator - spec: - mongoDB: {} - operandRequest: {} - - name: ibm-im-operator + - apiVersion: rbac.authorization.k8s.io/v1 + kind: Role + name: edb-license-role + namespace: "{{ .OperatorNs }}" + data: + rules: + - apiGroups: + - "" + resources: + - pods + - secrets + verbs: + - create + - update + - patch + - get + - list + - delete + - watch + - apiVersion: rbac.authorization.k8s.io/v1 + kind: RoleBinding + name: edb-license-rolebinding + namespace: "{{ .OperatorNs }}" + data: + subjects: + - kind: ServiceAccount + name: edb-license-sa + roleRef: + kind: Role + name: edb-license-role + apiGroup: rbac.authorization.k8s.io + - name: ibm-bts-operator spec: - authentication: - config: - onPremMultipleDeploy: {{ .OnPremMultiEnable }} - operandBindInfo: - operand: ibm-im-operator - bindings: {} operandRequest: requests: - operands: - - name: ibm-im-mongodb-operator - - name: ibm-idp-config-ui-operator + - name: ibm-im-operator registry: common-service - - name: ibm-iam-operator + - name: ibm-bts-operator-v3.34 spec: - authentication: - config: - ibmCloudSaas: true - oidcclientwatcher: {} - pap: {} - policycontroller: {} - policydecision: {} - secretwatcher: {} - securityonboarding: {} - operandBindInfo: {} - operandRequest: {} - - name: ibm-healthcheck-operator - spec: - healthService: {} - mustgatherService: {} - mustgatherConfig: {} - - name: ibm-commonui-operator - spec: - commonWebUI: {} - switcheritem: {} - operandRequest: {} - navconfiguration: {} - operandBindInfo: {} - - name: ibm-idp-config-ui-operator - spec: - commonWebUI: {} - switcheritem: {} - navconfiguration: {} - - name: ibm-management-ingress-operator - spec: - managementIngress: {} - operandBindInfo: {} - operandRequest: {} - - name: ibm-ingress-nginx-operator - spec: - nginxIngress: {} - - name: ibm-auditlogging-operator - spec: - operandBindInfo: {} - operandRequest: {} - - name: ibm-platform-api-operator - spec: - platformApi: {} - operandRequest: {} - - name: ibm-monitoring-grafana-operator - spec: - grafana: {} - operandRequest: {} - - name: ibm-bts-operator + operandRequest: + requests: + - operands: + - name: ibm-im-operator + registry: common-service + - name: ibm-bts-operator-v3.35 spec: operandRequest: requests: @@ -1733,68 +2378,16 @@ spec: - name: ibm-im-operator registry: common-service - name: ibm-zen-operator - spec: - operandBindInfo: {} resources: - - apiVersion: batch/v1 - data: - spec: - activeDeadlineSeconds: 600 - backoffLimit: 5 - template: - metadata: - annotations: - productID: 068a62892a1e4db39641342e592daa25 - productMetric: FREE - productName: IBM Cloud Platform Common Services - spec: - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: kubernetes.io/arch - operator: In - values: - - amd64 - - ppc64le - - s390x - containers: - - command: - - bash - - '-c' - - bash /setup/pre-zen.sh - env: - - name: common_services_namespace - valueFrom: - fieldRef: - fieldPath: metadata.namespace - image: {{ .ZenOperatorImage }} - name: pre-zen-job - resources: - limits: - cpu: 500m - memory: 512Mi - requests: - cpu: 100m - memory: 50Mi - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - privileged: false - readOnlyRootFilesystem: false - restartPolicy: OnFailure - securityContext: - runAsNonRoot: true - serviceAccount: operand-deployment-lifecycle-manager - serviceAccountName: operand-deployment-lifecycle-manager - terminationGracePeriodSeconds: 30 + - apiVersion: apps/v1 force: true - kind: Job - name: pre-zen-operand-config-job - namespace: "{{ .OperatorNs }}" + kind: Deployment + labels: + operator.ibm.com/opreq-control: 'true' + name: meta-api-deploy + namespace: "{{ .ServicesNs }}" + spec: + operandBindInfo: {} - name: ibm-platformui-operator spec: operandBindInfo: {} @@ -1807,7 +2400,7 @@ metadata: name: operand-deployment-lifecycle-manager-app namespace: "{{ .CPFSNs }}" spec: - channel: v4.2 + channel: v4.4 installPlanApproval: {{ .ApprovalMode }} name: ibm-odlm source: {{ .CatalogSourceName }} @@ -1815,9 +2408,8 @@ spec: ` // ConcatenateRegistries concatenate the two YAML strings and return the new YAML string -func ConcatenateRegistries(baseRegistryTemplate, insertedRegistryTemplate string, data interface{}) (string, error) { - baseRegistry := &odlm.OperandRegistry{} - insertedRegistry := &odlm.OperandRegistry{} +func ConcatenateRegistries(baseRegistryTemplate string, insertedRegistryTemplateList []string, data interface{}) (string, error) { + baseRegistry := odlm.OperandRegistry{} var template []byte var err error @@ -1829,19 +2421,22 @@ func ConcatenateRegistries(baseRegistryTemplate, insertedRegistryTemplate string return "", fmt.Errorf("failed to fetch data of OprandRegistry %v: %v", baseRegistry, err) } - // unmarshal second OprandRegistry - if template, err = applyTemplate(insertedRegistryTemplate, data); err != nil { - return "", err - } - if err := utilyaml.Unmarshal(template, &insertedRegistry); err != nil { - return "", fmt.Errorf("failed to fetch data of OprandRegistry %v: %v", insertedRegistry, err) - } - var newOperators []odlm.Operator - newOperators = append(newOperators, baseRegistry.Spec.Operators...) - newOperators = append(newOperators, insertedRegistry.Spec.Operators...) + for _, registryTemplate := range insertedRegistryTemplateList { + insertedRegistry := odlm.OperandRegistry{} + + if template, err = applyTemplate(registryTemplate, data); err != nil { + return "", err + } + if err := utilyaml.Unmarshal(template, &insertedRegistry); err != nil { + return "", fmt.Errorf("failed to fetch data of OprandRegistry %v/%v: %v", insertedRegistry.Namespace, insertedRegistry.Name, err) + } + + newOperators = append(newOperators, insertedRegistry.Spec.Operators...) + } + // add new operators to baseRegistry + baseRegistry.Spec.Operators = append(baseRegistry.Spec.Operators, newOperators...) - baseRegistry.Spec.Operators = newOperators opregBytes, err := utilyaml.Marshal(baseRegistry) if err != nil { return "", err @@ -1851,9 +2446,8 @@ func ConcatenateRegistries(baseRegistryTemplate, insertedRegistryTemplate string } // ConcatenateConfigs concatenate the two YAML strings and return the new YAML string -func ConcatenateConfigs(baseConfigTemplate, insertedConfigTemplate string, data interface{}) (string, error) { - baseConfig := &odlm.OperandConfig{} - insertedConfig := &odlm.OperandConfig{} +func ConcatenateConfigs(baseConfigTemplate string, insertedConfigTemplateList []string, data interface{}) (string, error) { + baseConfig := odlm.OperandConfig{} var template []byte var err error @@ -1865,19 +2459,21 @@ func ConcatenateConfigs(baseConfigTemplate, insertedConfigTemplate string, data return "", fmt.Errorf("failed to fetch data of OprandConfig %v: %v", baseConfig, err) } - // unmarshal second OprandConfig - if template, err = applyTemplate(insertedConfigTemplate, data); err != nil { - return "", err - } - if err := utilyaml.Unmarshal(template, &insertedConfig); err != nil { - return "", fmt.Errorf("failed to fetch data of OprandConfig %v: %v", insertedConfig, err) - } - var newServices []odlm.ConfigService - newServices = append(newServices, baseConfig.Spec.Services...) - newServices = append(newServices, insertedConfig.Spec.Services...) + for _, configTemplate := range insertedConfigTemplateList { + insertedConfig := odlm.OperandConfig{} + if template, err = applyTemplate(configTemplate, data); err != nil { + return "", err + } + if err := utilyaml.Unmarshal(template, &insertedConfig); err != nil { + return "", fmt.Errorf("failed to fetch data of OprandConfig %v/%v: %v", insertedConfig.Namespace, insertedConfig.Name, err) + } + + newServices = append(newServices, insertedConfig.Spec.Services...) + } + // add new services to baseConfig + baseConfig.Spec.Services = append(baseConfig.Spec.Services, newServices...) - baseConfig.Spec.Services = newServices opconBytes, err := utilyaml.Marshal(baseConfig) if err != nil { return "", err diff --git a/controllers/constant/odlm_operatorconfig.go b/controllers/constant/odlm_operatorconfig.go new file mode 100644 index 000000000..f4ad73325 --- /dev/null +++ b/controllers/constant/odlm_operatorconfig.go @@ -0,0 +1,216 @@ +// +// Copyright 2024 IBM Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package constant + +const PostGresOperatorConfig = ` +apiVersion: operator.ibm.com/v1alpha1 +kind: OperatorConfig +metadata: + name: cloud-native-postgresql-operator-config + namespace: "{{ .ServicesNs }}" + labels: + operator.ibm.com/managedByCsOperator: "true" + operator.ibm.com/experimental: "true" + annotations: + version: {{ .Version }} +spec: + services: + - name: edb-keycloak + replicas: placeholder-size + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/arch + operator: In + values: + - amd64 + - ppc64le + - s390x + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 90 + podAffinityTerm: + topologyKey: topology.kubernetes.io/zone + labelSelector: + matchExpressions: + - key: app.kubernetes.io/name + operator: In + values: + - cloud-native-postgresql + - weight: 50 + podAffinityTerm: + topologyKey: kubernetes.io/hostname + labelSelector: + matchExpressions: + - key: app.kubernetes.io/name + operator: In + values: + - cloud-native-postgresql + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + labelSelector: + matchLabels: + app.kubernetes.io/name: cloud-native-postgresql + - maxSkew: 1 + topologyKey: topology.kubernetes.io/region + whenUnsatisfiable: ScheduleAnyway + labelSelector: + matchLabels: + app.kubernetes.io/name: cloud-native-postgresql + - name: cloud-native-postgresql + replicas: placeholder-size + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/arch + operator: In + values: + - amd64 + - ppc64le + - s390x + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 90 + podAffinityTerm: + topologyKey: topology.kubernetes.io/zone + labelSelector: + matchExpressions: + - key: app.kubernetes.io/name + operator: In + values: + - cloud-native-postgresql + - weight: 50 + podAffinityTerm: + topologyKey: kubernetes.io/hostname + labelSelector: + matchExpressions: + - key: app.kubernetes.io/name + operator: In + values: + - cloud-native-postgresql + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + labelSelector: + matchLabels: + app.kubernetes.io/name: cloud-native-postgresql + - maxSkew: 1 + topologyKey: topology.kubernetes.io/region + whenUnsatisfiable: ScheduleAnyway + labelSelector: + matchLabels: + app.kubernetes.io/name: cloud-native-postgresql + - name: common-service-postgresql + replicas: placeholder-size + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/arch + operator: In + values: + - amd64 + - ppc64le + - s390x + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 90 + podAffinityTerm: + topologyKey: topology.kubernetes.io/zone + labelSelector: + matchExpressions: + - key: app.kubernetes.io/name + operator: In + values: + - cloud-native-postgresql + - weight: 50 + podAffinityTerm: + topologyKey: kubernetes.io/hostname + labelSelector: + matchExpressions: + - key: app.kubernetes.io/name + operator: In + values: + - cloud-native-postgresql + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + labelSelector: + matchLabels: + app.kubernetes.io/name: cloud-native-postgresql + - maxSkew: 1 + topologyKey: topology.kubernetes.io/region + whenUnsatisfiable: ScheduleAnyway + labelSelector: + matchLabels: + app.kubernetes.io/name: cloud-native-postgresql + - name: cloud-native-postgresql-v1.22 + replicas: placeholder-size + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/arch + operator: In + values: + - amd64 + - ppc64le + - s390x + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 90 + podAffinityTerm: + topologyKey: topology.kubernetes.io/zone + labelSelector: + matchExpressions: + - key: app.kubernetes.io/name + operator: In + values: + - cloud-native-postgresql + - weight: 50 + podAffinityTerm: + topologyKey: kubernetes.io/hostname + labelSelector: + matchExpressions: + - key: app.kubernetes.io/name + operator: In + values: + - cloud-native-postgresql + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + labelSelector: + matchLabels: + app.kubernetes.io/name: cloud-native-postgresql + - maxSkew: 1 + topologyKey: topology.kubernetes.io/region + whenUnsatisfiable: ScheduleAnyway + labelSelector: + matchLabels: + app.kubernetes.io/name: cloud-native-postgresql +` diff --git a/controllers/constant/serviceLabel.go b/controllers/constant/serviceLabel.go new file mode 100644 index 000000000..2b27ca852 --- /dev/null +++ b/controllers/constant/serviceLabel.go @@ -0,0 +1,111 @@ +// +// Copyright 2022 IBM Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package constant + +// still need flink and elastic +const ServiceLabelTemplate = ` +- name: ibm-im-mongodb-operator + spec: + mongoDB: + labels: + placeholder1: placeholder2 +- name: ibm-im-mongodb-operator-v4.0 + spec: + mongoDB: + labels: + placeholder1: placeholder2 +- name: ibm-im-mongodb-operator-v4.1 + spec: + mongoDB: + labels: + placeholder1: placeholder2 +- name: ibm-im-mongodb-operator-v4.2 + spec: + mongoDB: + labels: + placeholder1: placeholder2 +- name: ibm-im-operator + spec: + authentication: + labels: + placeholder1: placeholder2 +- name: ibm-im-operator-v4.0 + spec: + authentication: + labels: + placeholder1: placeholder2 +- name: ibm-im-operator-v4.1 + spec: + authentication: + labels: + placeholder1: placeholder2 +- name: ibm-im-operator-v4.2 + spec: + authentication: + labels: + placeholder1: placeholder2 +- name: ibm-im-operator-v4.3 + spec: + authentication: + labels: + placeholder1: placeholder2 +- name: ibm-im-operator-v4.4 + spec: + authentication: + labels: + placeholder1: placeholder2 +- name: ibm-im-operator-v4.5 + spec: + authentication: + labels: + placeholder1: placeholder2 +- name: ibm-im-operator-v4.6 + spec: + authentication: + labels: + placeholder1: placeholder2 +- name: ibm-idp-config-ui-operator-v4.0 + spec: + commonWebUI: + labels: + placeholder1: placeholder2 +- name: ibm-idp-config-ui-operator-v4.1 + spec: + commonWebUI: + labels: + placeholder1: placeholder2 +- name: ibm-idp-config-ui-operator-v4.2 + spec: + commonWebUI: + labels: + placeholder1: placeholder2 +- name: ibm-idp-config-ui-operator-v4.3 + spec: + commonWebUI: + labels: + placeholder1: placeholder2 +- name: ibm-idp-config-ui-operator-v4.4 + spec: + commonWebUI: + labels: + placeholder1: placeholder2 +- name: ibm-idp-config-ui-operator-v4.5 + spec: + commonWebUI: + labels: + placeholder1: placeholder2 +` diff --git a/controllers/constant/storageclass.go b/controllers/constant/storageclass.go index 84c25ae69..41f4a59fe 100644 --- a/controllers/constant/storageclass.go +++ b/controllers/constant/storageclass.go @@ -38,4 +38,26 @@ const StorageClassTemplate = ` mustgatherService: persistentVolumeClaim: storageClassName: placeholder +- name: edb-keycloak + resources: + - apiVersion: postgresql.k8s.enterprisedb.io/v1 + data: + spec: + storage: + storageClass: placeholder + walStorage: + storageClass: placeholder + kind: Cluster + name: keycloak-edb-cluster +- name: common-service-postgresql + resources: + - apiVersion: postgresql.k8s.enterprisedb.io/v1 + data: + spec: + storage: + storageClass: placeholder + walStorage: + storageClass: placeholder + kind: Cluster + name: common-service-db ` diff --git a/controllers/deploy/manager.go b/controllers/deploy/manager.go index 10e3adae2..1462fbedf 100644 --- a/controllers/deploy/manager.go +++ b/controllers/deploy/manager.go @@ -19,6 +19,7 @@ package deploy import ( "context" "fmt" + "os" "time" olmv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1" @@ -32,7 +33,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/manager" - util "github.com/IBM/ibm-common-service-operator/controllers/common" + util "github.com/IBM/ibm-common-service-operator/v4/controllers/common" ) type Manager struct { @@ -165,6 +166,10 @@ func (d *Manager) GetDeployment() (*appsv1.Deployment, error) { // DeleteOperator delete operator's csv and subscription from specific namespace func (d *Manager) DeleteOperator(name, namespace string) error { + if os.Getenv("NO_OLM") == "true" { + klog.V(2).Infof("skip delete operator in no-olm environment") + return nil + } // Get existing operator's subscription subName := name subNs := namespace diff --git a/controllers/goroutines/cleanup_deprecated_services.go b/controllers/goroutines/cleanup_deprecated_services.go deleted file mode 100644 index d3af06988..000000000 --- a/controllers/goroutines/cleanup_deprecated_services.go +++ /dev/null @@ -1,254 +0,0 @@ -// -// Copyright 2022 IBM Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package goroutines - -import ( - "context" - "time" - - olmv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1" - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/klog" - "sigs.k8s.io/controller-runtime/pkg/client" - - "github.com/IBM/ibm-common-service-operator/controllers/bootstrap" - util "github.com/IBM/ibm-common-service-operator/controllers/common" -) - -const ( - namespaceScope = "namespaceScope" - // clusterScope = "clusterScope" -) - -var deprecatedServicesMap = map[string][]*bootstrap.Resource{ - "ibm-monitoring-exporters-operator": { - { - Name: "ibm-monitoring", - Version: "v1alpha1", - Group: "monitoring.operator.ibm.com", - Kind: "Exporter", - Scope: namespaceScope, - }, - { - Name: "monitoring-exporters-operator-request", - Version: "v1alpha1", - Group: "operator.ibm.com", - Kind: "OperandRequest", - Scope: namespaceScope, - }, - }, - "ibm-monitoring-prometheusext-operator": { - { - Name: "ibm-monitoring", - Version: "v1alpha1", - Group: "monitoring.operator.ibm.com", - Kind: "PrometheusExt", - Scope: namespaceScope, - }, - { - Name: "monitoring-prometheus-ext-operator-request", - Version: "v1alpha1", - Group: "operator.ibm.com", - Kind: "OperandRequest", - Scope: namespaceScope, - }, - }, - // "ibm-metering-operator": { - // { - // Name: "metering", - // Version: "v1alpha1", - // Group: "operator.ibm.com", - // Kind: "Metering", - // Scope: namespaceScope, - // }, - // { - // Name: "meteringui", - // Version: "v1alpha1", - // Group: "operator.ibm.com", - // Kind: "MeteringUI", - // Scope: namespaceScope, - // }, - // { - // Name: "meteringreportserver", - // Version: "v1alpha1", - // Group: "operator.ibm.com", - // Kind: "MeteringReportServer", - // Scope: clusterScope, - // }, - // { - // Name: "ibm-metering-bindinfo", - // Version: "v1alpha1", - // Group: "operator.ibm.com", - // Kind: "OperandBindInfo", - // Scope: namespaceScope, - // }, - // { - // Name: "ibm-metering-request", - // Version: "v1alpha1", - // Group: "operator.ibm.com", - // Kind: "OperandRequest", - // Scope: namespaceScope, - // }, - // }, - "ibm-elastic-stack-operator": { - { - Name: "logging", - Version: "v1alpha1", - Group: "elasticstack.ibm.com", - Kind: "ElasticStack", - Scope: namespaceScope, - }, - { - Name: "ibm-elastic-stack-bindinfo", - Version: "v1alpha1", - Group: "operator.ibm.com", - Kind: "OperandBindInfo", - Scope: namespaceScope, - }, - { - Name: "ibm-elastic-stack-request", - Version: "v1alpha1", - Group: "operator.ibm.com", - Kind: "OperandRequest", - Scope: namespaceScope, - }, - }, - "ibm-catalog-ui-operator": { - { - Name: "catalog-ui", - Version: "v1alpha1", - Group: "operator.ibm.com", - Kind: "CatalogUI", - Scope: namespaceScope, - }, - { - Name: "catalog-ui-request", - Version: "v1alpha1", - Group: "operator.ibm.com", - Kind: "OperandRequest", - Scope: namespaceScope, - }, - }, - "ibm-helm-api-operator": { - { - Name: "helm-api", - Version: "v1alpha1", - Group: "operator.ibm.com", - Kind: "HelmAPI", - Scope: namespaceScope, - }, - { - Name: "helm-api-request", - Version: "v1alpha1", - Group: "operator.ibm.com", - Kind: "OperandRequest", - Scope: namespaceScope, - }, - }, - "ibm-helm-repo-operator": { - { - Name: "helm-repo", - Version: "v1alpha1", - Group: "operator.ibm.com", - Kind: "HelmRepo", - Scope: namespaceScope, - }, - { - Name: "helm-repo-request", - Version: "v1alpha1", - Group: "operator.ibm.com", - Kind: "OperandRequest", - Scope: namespaceScope, - }, - }, -} - -// CleanUpDeprecatedServices will clean up deprecated services' CRD, operandBindInfo, operandRequest, subscription, CSV -func CleanUpDeprecatedServices(bs *bootstrap.Bootstrap) { - for { - opreg, err := bs.GetOperandRegistry(ctx, "common-service", bs.CSData.CPFSNs) - if err == nil && opreg != nil { - if opreg.GetAnnotations() != nil && opreg.GetAnnotations()["version"] == bs.CSData.Version { - for service, resourcesList := range deprecatedServicesMap { - getResourceFailed := false - for _, resource := range resourcesList { - operatorNs, err := util.GetOperatorNamespace() - if err != nil { - getResourceFailed = true - continue - } - - if err := bs.Cleanup(operatorNs, resource); err != nil { - getResourceFailed = true - continue - } - } - - // delete sub & csv - if !getResourceFailed { - if err := deleteSubscription(bs, service, MasterNamespace); err != nil { - klog.Errorf("Delete subscription failed: %v", err) - continue - } - } - } - } else { - klog.Info("Skipped cleaning deprecated services, wait for latest OperandRegistry common-service ready, retry in 2 minutes.") - } - } - time.Sleep(2 * time.Minute) - } -} - -func deleteSubscription(bs *bootstrap.Bootstrap, name, namespace string) error { - key := types.NamespacedName{Name: name, Namespace: namespace} - sub := &olmv1alpha1.Subscription{} - if err := bs.Reader.Get(context.TODO(), key, sub); err != nil { - if errors.IsNotFound(err) { - return nil - } - klog.Errorf("Failed to get subscription %s/%s", namespace, name) - return client.IgnoreNotFound(err) - } - - klog.Infof("Deleting subscription %s/%s", namespace, name) - - // Delete csv - csvName := sub.Status.InstalledCSV - if csvName != "" { - csv := &olmv1alpha1.ClusterServiceVersion{ - ObjectMeta: metav1.ObjectMeta{ - Name: csvName, - Namespace: namespace, - }, - } - if err := bs.Client.Delete(context.TODO(), csv); err != nil && !errors.IsNotFound(err) { - klog.Errorf("Failed to delete Cluster Service Version: %v", err) - return err - } - } - - // Delete subscription - if err := bs.Client.Delete(context.TODO(), sub); err != nil && !errors.IsNotFound(err) { - klog.Errorf("Failed to delete subscription: %s", err) - return err - } - - return nil -} diff --git a/controllers/goroutines/cleanup_resources.go b/controllers/goroutines/cleanup_resources.go new file mode 100644 index 000000000..dc0e87104 --- /dev/null +++ b/controllers/goroutines/cleanup_resources.go @@ -0,0 +1,143 @@ +// +// Copyright 2022 IBM Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package goroutines + +import ( + "time" + + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/types" + "k8s.io/klog" + + "github.com/IBM/ibm-common-service-operator/v4/controllers/bootstrap" + util "github.com/IBM/ibm-common-service-operator/v4/controllers/common" + "github.com/IBM/ibm-common-service-operator/v4/controllers/constant" +) + +const ( + mongodbPreloadCm = "mongodb-preload-endpoint" + mongodbStatefulSet = "icp-mongodb" +) + +// Cleanup_Keycloak_Cert will delete Keycloak Certificate when OperandConfig is updated to new version +func CleanupKeycloakCert(bs *bootstrap.Bootstrap) { + for { + // wait ODLM OperandConfig CR resources + if err := bs.WaitResourceReady("operator.ibm.com/v1alpha1", "OperandConfig"); err != nil { + klog.Error("Failed to wait for resource ready with kind: OperandConfig, apiGroupVersion: operator.ibm.com/v1alpha1") + time.Sleep(5 * time.Second) + continue + } + + opcon, err := bs.GetOperandConfig(ctx, "common-service", bs.CSData.ServicesNs) + if err != nil || opcon == nil { + time.Sleep(5 * time.Second) + continue + } + + // check if OperandConfig's annotation version is updated + if opcon.Annotations != nil { + v1IsLarger, convertErr := util.CompareVersion(bs.CSData.Version, opcon.Annotations["version"]) + if convertErr != nil { + klog.Errorf("Failed to convert version for OperandConfig: %v", convertErr) + time.Sleep(5 * time.Second) + continue + } + // if OperandConfig's version is updated to the same as CS version or larger, delete Keycloak Certificate + if !v1IsLarger { + // check if cert-manager CRD does not exist, then skip cert-manager related controllers initialization + exist, err := bs.CheckCRD(constant.CertManagerAPIGroupVersionV1, "Certificate") + if err != nil { + klog.Errorf("Failed to check if cert-manager CRD exists: %v", err) + time.Sleep(5 * time.Second) + continue + } + if !exist { + klog.Infof("cert-manager CRD does not exist, skip deleting Keycloak Certificate %s", constant.KeycloakCert) + } else if exist { + if err := bs.DeleteFromYaml(constant.KeycloakCertTemplate, bs.CSData); err != nil { + klog.Errorf("Failed to delete Keycloak Certificate %s: %v", constant.KeycloakCert, err) + time.Sleep(5 * time.Second) + continue + } + } + } + } + + time.Sleep(2 * time.Minute) + } +} + +// Cleanup_MongoDB_Preload_CM will delete mongodb-preload-endpoint ConfigMap when icp-mongodb StatefulSet has owner reference +func CleanupMongodbPreloadCm(bs *bootstrap.Bootstrap) { + for { + // check if icp-mongodb StatefulSet exists + statefulSet := &unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": "apps/v1", + "kind": "StatefulSet", + "metadata": map[string]interface{}{ + "name": mongodbStatefulSet, + "namespace": bs.CSData.ServicesNs, + }, + }, + } + if err := bs.Reader.Get(ctx, types.NamespacedName{Name: mongodbStatefulSet, Namespace: bs.CSData.ServicesNs}, statefulSet); err != nil { + if errors.IsNotFound(err) { + klog.Infof("StatefulSet %s does not exist in %s, skip deleting %s ConfigMap", mongodbStatefulSet, bs.CSData.ServicesNs, mongodbPreloadCm) + break + } else { + klog.Errorf("Failed to get StatefulSet %s: %v, retrying...", mongodbStatefulSet, err) + time.Sleep(5 * time.Second) + continue + } + } + + // check if icp-mongodb StatefulSet has owner reference, delete mongodb-preload-endpoint ConfigMap + if (statefulSet.GetOwnerReferences() != nil) && (len(statefulSet.GetOwnerReferences()) > 0) { + preloadCm := &unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": "v1", + "kind": "ConfigMap", + "metadata": map[string]interface{}{ + "name": mongodbPreloadCm, + "namespace": bs.CSData.ServicesNs, + }, + }, + } + if err := bs.Client.Delete(ctx, preloadCm); err != nil { + if errors.IsNotFound(err) { + klog.Infof("ConfigMap %s does not exist in %s, skip deleting", mongodbPreloadCm, bs.CSData.ServicesNs) + break + } + klog.Errorf("Failed to delete ConfigMap %s: %v, retrying...", mongodbPreloadCm, err) + time.Sleep(5 * time.Second) + continue + } + klog.Infof("ConfigMap %s in %s is deleted for the preparation of MongoDB migration.", mongodbPreloadCm, bs.CSData.ServicesNs) + break + } + klog.Infof("StatefulSet %s does not have owner reference, skip deleting %s ConfigMap", mongodbStatefulSet, mongodbPreloadCm) + break + } +} + +func CleanupResources(bs *bootstrap.Bootstrap) { + go CleanupKeycloakCert(bs) + go CleanupMongodbPreloadCm(bs) +} diff --git a/controllers/goroutines/cppConfig.go b/controllers/goroutines/cppConfig.go deleted file mode 100644 index ded7102ff..000000000 --- a/controllers/goroutines/cppConfig.go +++ /dev/null @@ -1,70 +0,0 @@ -// -// Copyright 2022 IBM Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package goroutines - -import ( - "context" - "reflect" - "time" - - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" - "k8s.io/klog" - - "github.com/IBM/ibm-common-service-operator/controllers/bootstrap" - collector "github.com/IBM/ibm-common-service-operator/controllers/configurationCollector" - "github.com/IBM/ibm-common-service-operator/controllers/constant" -) - -// CreateUpdateConfig deploys config builder for global cpp configmap -func CreateUpdateConfig(bs *bootstrap.Bootstrap) { - - for { - config := &corev1.ConfigMap{} - if err := bs.Client.Get(context.TODO(), types.NamespacedName{Name: constant.IBMCPPCONFIG, Namespace: bs.CSData.ServicesNs}, config); err != nil && !errors.IsNotFound(err) { - continue - } else if errors.IsNotFound(err) { - config.ObjectMeta.Name = constant.IBMCPPCONFIG - config.ObjectMeta.Namespace = bs.CSData.ServicesNs - config.Data = make(map[string]string) - config.Data = collector.Buildconfig(config.Data, bs) - if err := bs.Client.Create(context.TODO(), config); err != nil { - time.Sleep(1 * time.Second) - continue - } - klog.Infof("Global CPP config %s/%s is created", bs.CSData.ServicesNs, constant.IBMCPPCONFIG) - } else { - orgConfig := config.DeepCopy() - config.Data = collector.Buildconfig(config.Data, bs) - if !reflect.DeepEqual(orgConfig, config) { - if err := bs.Client.Update(context.TODO(), config); err != nil { - time.Sleep(1 * time.Second) - continue - } - klog.Infof("Global CPP config %s/%s is updated", bs.CSData.ServicesNs, constant.IBMCPPCONFIG) - } - if err := bs.PropagateCPPConfig(config); err != nil { - klog.Error(err) - time.Sleep(1 * time.Second) - continue - } - } - time.Sleep(10 * time.Minute) - } - -} diff --git a/controllers/goroutines/namespacescope.go b/controllers/goroutines/namespacescope.go deleted file mode 100644 index 5e1073545..000000000 --- a/controllers/goroutines/namespacescope.go +++ /dev/null @@ -1,143 +0,0 @@ -// -// Copyright 2022 IBM Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package goroutines - -import ( - "context" - "strings" - "time" - - gset "github.com/deckarep/golang-set" - olmv1 "github.com/operator-framework/api/pkg/operators/v1" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" - "k8s.io/klog" - "sigs.k8s.io/controller-runtime/pkg/client" - - "github.com/IBM/ibm-common-service-operator/controllers/bootstrap" - util "github.com/IBM/ibm-common-service-operator/controllers/common" -) - -var ctx = context.Background() - -func SyncUpNSSConfigMap(bs *bootstrap.Bootstrap) { - for { - //get ConfigMap of namespace-scope - nssConfigMap := &corev1.ConfigMap{} - namespaceScopeKey := types.NamespacedName{Name: "namespace-scope", Namespace: bs.CSData.CPFSNs} - if err := bs.Reader.Get(ctx, namespaceScopeKey, nssConfigMap); err != nil { - if errors.IsNotFound(err) { - // Backward compatible upgrade from version 3.4.x and fresh installation in CP 3.0 - if err := bs.CreateNsScopeConfigmap(); err != nil { - klog.Errorf("Failed to create Namespace Scope ConfigMap: %v, retry in 5 seconds", err) - time.Sleep(5 * time.Second) - continue - } - } else { - klog.Errorf("Failed to get configmap %s: %v, retry in 10 seconds", namespaceScopeKey.String(), err) - time.Sleep(10 * time.Second) - continue - } - } else { - // get targetNamespace from OperatorGroup - existOG := &olmv1.OperatorGroupList{} - if err := bs.Reader.List(context.TODO(), existOG, &client.ListOptions{Namespace: bs.CSData.CPFSNs}); err != nil { - klog.Errorf("Failed to get OperatorGroup in %s namespace: %v, retry in 10 seconds", bs.CSData.CPFSNs, err) - time.Sleep(10 * time.Second) - continue - } - if len(existOG.Items) != 1 { - klog.Errorf("The number of OperatorGroup in %s namespace is incorrect, Only one OperatorGroup is allowed in one namespace", bs.CSData.CPFSNs) - time.Sleep(10 * time.Second) - continue - } - - originalOG := &existOG.Items[0] - originalOGNs := originalOG.Status.Namespaces - - // get NamespaceScope from ConfigMap - originalNSSCMNs := strings.Split(nssConfigMap.Data["namespaces"], ",") - - OGNsSet := gset.NewSet() - NSSCMNsSet := gset.NewSet() - mergeNsSet := gset.NewSet() - for _, ns := range originalOGNs { - mergeNsSet.Add(ns) - OGNsSet.Add(ns) - } - for _, ns := range originalNSSCMNs { - mergeNsSet.Add(ns) - NSSCMNsSet.Add(ns) - } - - // if the existing version is empty or less than 4.0.0, NSS ConfigMap value will be copied to OperatorGroup. - // Otherwise, NSS ConfigMap's value will not impact OperatorGroup - v1IsLarger, convertErr := util.CompareVersion("4.0.0", nssConfigMap.GetAnnotations()["version"]) - if convertErr != nil { - klog.Errorf("Failed to compare the version in ConfigMap %s: %v, retry again in 10 seconds", namespaceScopeKey.String(), err) - time.Sleep(10 * time.Second) - continue - } - // only happened during upgrade from Cloud Pak 2.0 to Cloud Pak 3.0 - if !mergeNsSet.Equal(OGNsSet) && v1IsLarger { - mergeNsMems := mergeNsSet.ToSlice() - var targetNsMems []string - for _, ns := range mergeNsMems { - targetNsMems = append(targetNsMems, ns.(string)) - } - originalOG.Spec.TargetNamespaces = targetNsMems - if err := bs.Client.Update(ctx, originalOG); err != nil { - klog.Errorf("Failed to update OperatorGroup %s/%s: %v, retry again in 10 seconds", originalOG.GetNamespace(), originalOG.GetName(), err) - time.Sleep(10 * time.Second) - continue - } - - // tag version in ConfigMap whenever the OperatorGroup is updated due to the synchronization in upgrade. - // It avoids OperatorGroup's targetNamespace manipulation via NSS ConfigMap after upgrade - if nssConfigMap.GetAnnotations() == nil { - nssConfigMap.SetAnnotations(make(map[string]string)) - } - nssConfigMap.Annotations["version"] = bs.CSData.Version - if err := bs.Client.Update(ctx, nssConfigMap); err != nil { - klog.Errorf("Failed to update ConfigMap %s: %v, retry again in 10 seconds", namespaceScopeKey.String(), err) - time.Sleep(10 * time.Second) - continue - } - } else if !OGNsSet.Equal(NSSCMNsSet) { // This helps to seed targetNamespaces from OperatorGroup into NSS ConfigMap, it will not happen during upgrade - OGNsMems := OGNsSet.ToSlice() - var targetNsMems []string - for _, ns := range OGNsMems { - targetNsMems = append(targetNsMems, ns.(string)) - } - nssConfigMap.Data["namespaces"] = strings.Join(targetNsMems[:], ",") - if nssConfigMap.GetAnnotations() == nil { - nssConfigMap.SetAnnotations(make(map[string]string)) - } - nssConfigMap.Annotations["version"] = bs.CSData.Version - if err := bs.Client.Update(ctx, nssConfigMap); err != nil { - klog.Errorf("Failed to update ConfigMap %s: %v, retry again in 10 seconds", namespaceScopeKey.String(), err) - time.Sleep(10 * time.Second) - continue - } - // Consider restart the pod if it is necessary - } - } - - } - -} diff --git a/controllers/goroutines/no_olm_operator_status.go b/controllers/goroutines/no_olm_operator_status.go new file mode 100644 index 000000000..c1d70d407 --- /dev/null +++ b/controllers/goroutines/no_olm_operator_status.go @@ -0,0 +1,101 @@ +// +// Copyright 2022 IBM Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package goroutines + +import ( + "context" + "time" + + appsv1 "k8s.io/api/apps/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/types" + "k8s.io/klog" + + apiv3 "github.com/IBM/ibm-common-service-operator/v4/api/v3" + "github.com/IBM/ibm-common-service-operator/v4/controllers/bootstrap" + "github.com/IBM/ibm-common-service-operator/v4/controllers/constant" +) + +var ctx_NoOLM = context.Background() + +// UpdateCsCrStatus will update cs cr status according to each bedrock operator +func UpdateNoOLMCsCrStatus(bs *bootstrap.Bootstrap) { + for { + instance := &apiv3.CommonService{} + if err := bs.Reader.Get(ctx_NoOLM, types.NamespacedName{Name: "common-service", Namespace: bs.CSData.OperatorNs}, instance); err != nil { + if !errors.IsNotFound(err) { + klog.Warningf("Faild to get CommonService CR %v/%v: %v", instance.GetNamespace(), instance.GetName(), err) + } + time.Sleep(5 * time.Second) + continue + } + + var operatorSlice []apiv3.BedrockOperator + + for _, name := range constant.DeploymentsName { + var opt apiv3.BedrockOperator + var err error + + opt, err = getNoOLMBedrockOperator(bs, name, bs.CSData.CPFSNs) + + if err == nil { + operatorSlice = append(operatorSlice, opt) + } else if !errors.IsNotFound(err) { + klog.Errorf("Failed to check operator %s: %v", name, err) + } + } + + // update status for each operators: BedrockOperators list + instance.Status.BedrockOperators = operatorSlice + + // update operators overall status: OverallStatus + instance.Status.OverallStatus = "Succeeded" + for _, opt := range operatorSlice { + if opt.OperatorStatus != "Succeeded" { + instance.Status.OverallStatus = "NotReady" + break + } + } + + if err := bs.Client.Status().Update(ctx_NoOLM, instance); err != nil { + klog.Warning(err) + } + + time.Sleep(2 * time.Minute) + } +} + +func getNoOLMBedrockOperator(bs *bootstrap.Bootstrap, name, namespace string) (apiv3.BedrockOperator, error) { + var opt apiv3.BedrockOperator + opt.Name = name + + // fetch subscription + deployment := &appsv1.Deployment{} + deploymentKey := types.NamespacedName{ + Name: name, + Namespace: namespace, + } + if err := bs.Client.Get(ctx_NoOLM, deploymentKey, deployment); err != nil { + return opt, err + } + + if deployment.Status.ReadyReplicas != *deployment.Spec.Replicas { + opt.Troubleshooting = "Operator status is not healthy, please check " + constant.GeneralTroubleshooting + " for more information" + } + + return opt, nil +} diff --git a/controllers/goroutines/operator_status.go b/controllers/goroutines/operator_status.go index 56ab21424..7d57fc1b1 100644 --- a/controllers/goroutines/operator_status.go +++ b/controllers/goroutines/operator_status.go @@ -17,6 +17,7 @@ package goroutines import ( + "context" "fmt" "strings" "time" @@ -26,11 +27,13 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/klog" - apiv3 "github.com/IBM/ibm-common-service-operator/api/v3" - "github.com/IBM/ibm-common-service-operator/controllers/bootstrap" - "github.com/IBM/ibm-common-service-operator/controllers/constant" + apiv3 "github.com/IBM/ibm-common-service-operator/v4/api/v3" + "github.com/IBM/ibm-common-service-operator/v4/controllers/bootstrap" + "github.com/IBM/ibm-common-service-operator/v4/controllers/constant" ) +var ctx = context.Background() + // UpdateCsCrStatus will update cs cr status according to each bedrock operator func UpdateCsCrStatus(bs *bootstrap.Bootstrap) { for { diff --git a/controllers/goroutines/variables.go b/controllers/goroutines/variables.go deleted file mode 100644 index d93295539..000000000 --- a/controllers/goroutines/variables.go +++ /dev/null @@ -1,39 +0,0 @@ -// -// Copyright 2022 IBM Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package goroutines - -import "github.com/IBM/ibm-common-service-operator/controllers/constant" - -var ( - OperatorAPIGroupVersion = "operator.ibm.com/v1" - - SecretShareAPIGroupVersion = "ibmcpcs.ibm.com/v1" - SecretShareKind = "SecretShare" - SecretShareCppName = constant.IBMCPPCONFIG - - IAMSaaSDeployNames = []string{"platform-identity-management", "platform-identity-provider", "platform-auth-service"} - IAMDeployNames = []string{"platform-identity-management", "platform-identity-provider", "platform-auth-service"} - IAMJobNames = []string{"oidc-client-registration"} - - NSSKinds = []string{"NamespaceScope"} - NSSCRList = []string{"common-service", "nss-odlm-scope"} - NSSSourceCR = "common-service" - NSSTargetCR = "nss-odlm-scope" - - MasterNamespace string - ServicesNamespace string -) diff --git a/controllers/goroutines/waitToCreateCsCR.go b/controllers/goroutines/waitToCreateCsCR.go index 09bf51428..2a75336dd 100644 --- a/controllers/goroutines/waitToCreateCsCR.go +++ b/controllers/goroutines/waitToCreateCsCR.go @@ -24,13 +24,13 @@ import ( "k8s.io/klog" - "github.com/IBM/ibm-common-service-operator/controllers/bootstrap" + "github.com/IBM/ibm-common-service-operator/v4/controllers/bootstrap" ) -// CreateUpdateConfig deploys config builder for global cpp configmap +// WaitToCreateCsCR waits for the creation of the CommonService CR in the operator namespace. func WaitToCreateCsCR(bs *bootstrap.Bootstrap) { for { - klog.Infof("Creating CommonService CR in the namespace %s", bs.CSData.OperatorNs) + klog.Infof("Start to Create CommonService CR in the namespace %s", bs.CSData.OperatorNs) if err := bs.CreateCsCR(); err != nil { if strings.Contains(fmt.Sprint(err), "failed to call webhook") { klog.Infof("Webhook Server not ready, waiting for it to be ready : %v", err) @@ -44,5 +44,4 @@ func WaitToCreateCsCR(bs *bootstrap.Bootstrap) { } } - } diff --git a/controllers/operandconfig.go b/controllers/operandconfig.go index 164881292..a18e47860 100644 --- a/controllers/operandconfig.go +++ b/controllers/operandconfig.go @@ -21,21 +21,19 @@ import ( "encoding/json" "fmt" "reflect" - "strings" utilyaml "github.com/ghodss/yaml" "github.com/mohae/deepcopy" - "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/selection" "k8s.io/apimachinery/pkg/types" "k8s.io/klog" "sigs.k8s.io/controller-runtime/pkg/client" - apiv3 "github.com/IBM/ibm-common-service-operator/api/v3" - util "github.com/IBM/ibm-common-service-operator/controllers/common" - "github.com/IBM/ibm-common-service-operator/controllers/constant" - "github.com/IBM/ibm-common-service-operator/controllers/rules" + apiv3 "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" + "github.com/IBM/ibm-common-service-operator/v4/controllers/rules" ) var ( @@ -99,42 +97,90 @@ func mergeProfileController(serviceControllerMappingSummary, serviceControllerMa return serviceControllerMappingSummary } -func mergeCSCRs(csSummary, csCR, ruleSlice []interface{}, serviceControllerMappingSummary map[string]string) []interface{} { +func mergeCSCRs(csSummary, csCR, ruleSlice []interface{}, serviceControllerMappingSummary map[string]string, opconNs string) []interface{} { for _, operator := range csCR { summaryCR := getItemByName(csSummary, operator.(map[string]interface{})["name"].(string)) rules := getItemByName(ruleSlice, operator.(map[string]interface{})["name"].(string)) - if summaryCR == nil || summaryCR.(map[string]interface{})["spec"] == nil { + if summaryCR == nil { summaryCR = map[string]interface{}{ - "name": operator.(map[string]interface{})["name"].(string), - "spec": map[string]interface{}{}, + "name": operator.(map[string]interface{})["name"].(string), + "spec": map[string]interface{}{}, + "resources": []interface{}{}, } + } else if summaryCR.(map[string]interface{})["spec"] == nil { + summaryCR.(map[string]interface{})["spec"] = map[string]interface{}{} + } else if summaryCR.(map[string]interface{})["resources"] == nil { + summaryCR.(map[string]interface{})["resources"] = []interface{}{} } serviceController := serviceControllerMappingSummary["profileController"] if controller, ok := serviceControllerMappingSummary[operator.(map[string]interface{})["name"].(string)]; ok { serviceController = controller } - for cr, spec := range operator.(map[string]interface{})["spec"].(map[string]interface{}) { - if _, ok := nonDefaultProfileController[serviceController]; ok { - // clean up merged CS CR - operator.(map[string]interface{})["spec"].(map[string]interface{})[cr] = resetResourceInTemplate(spec.(map[string]interface{}), cr, rules) - } - if summaryCR.(map[string]interface{})["spec"].(map[string]interface{})[cr] == nil { - summaryCR.(map[string]interface{})["spec"].(map[string]interface{})[cr] = map[string]interface{}{} + if operator.(map[string]interface{})["spec"] != nil { + for cr, spec := range operator.(map[string]interface{})["spec"].(map[string]interface{}) { + if _, ok := nonDefaultProfileController[serviceController]; ok { + // clean up merged CS CR + operator.(map[string]interface{})["spec"].(map[string]interface{})[cr] = resetResourceInTemplate(spec.(map[string]interface{}), cr, rules) + } + if summaryCR.(map[string]interface{})["spec"].(map[string]interface{})[cr] == nil { + summaryCR.(map[string]interface{})["spec"].(map[string]interface{})[cr] = map[string]interface{}{} + } + if rules != nil && rules.(map[string]interface{})["spec"] != nil && rules.(map[string]interface{})["spec"].(map[string]interface{})[cr] != nil { + ruleForCR := rules.(map[string]interface{})["spec"].(map[string]interface{})[cr].(map[string]interface{}) + sizeForCR := summaryCR.(map[string]interface{})["spec"].(map[string]interface{})[cr].(map[string]interface{}) + summaryCR.(map[string]interface{})["spec"].(map[string]interface{})[cr] = mergeCRsIntoOperandConfig(sizeForCR, spec.(map[string]interface{}), ruleForCR, false, false) + } } - if rules != nil && rules.(map[string]interface{})["spec"] != nil && rules.(map[string]interface{})["spec"].(map[string]interface{})[cr] != nil { - ruleForCR := rules.(map[string]interface{})["spec"].(map[string]interface{})[cr].(map[string]interface{}) - sizeForCR := summaryCR.(map[string]interface{})["spec"].(map[string]interface{})[cr].(map[string]interface{}) - summaryCR.(map[string]interface{})["spec"].(map[string]interface{})[cr] = mergeCRsIntoOperandConfig(sizeForCR, spec.(map[string]interface{}), ruleForCR, false, false) + csSummary = setSpecByName(csSummary, operator.(map[string]interface{})["name"].(string), summaryCR.(map[string]interface{})["spec"]) + } + + // check if operator.(map[string]interface{})["resources"] is nil + if operator.(map[string]interface{})["resources"] != nil { + for i, opResource := range operator.(map[string]interface{})["resources"].([]interface{}) { + var apiVersion, kind, name, namespace string + if opResource.(map[string]interface{})["apiVersion"] != nil { + apiVersion = opResource.(map[string]interface{})["apiVersion"].(string) + } + if opResource.(map[string]interface{})["kind"] != nil { + kind = opResource.(map[string]interface{})["kind"].(string) + } + if opResource.(map[string]interface{})["name"] != nil { + name = opResource.(map[string]interface{})["name"].(string) + } + if opResource.(map[string]interface{})["namespace"] != nil { + namespace = opResource.(map[string]interface{})["namespace"].(string) + } + // check if above 4 fields are all set + if apiVersion == "" || kind == "" || name == "" { + klog.Warningf("Skipping merging resource %s/%s/%s/%s, because apiVersion, kind or name is not set", apiVersion, kind, name, namespace) + continue + } + // check if namespace is set, if not, set it to OperandConfig namespace + if namespace == "" { + namespace = opconNs + } + if summaryCR == nil || summaryCR.(map[string]interface{})["resources"] == nil { + continue + } + newResource := getItemByGVKNameNamespace(summaryCR.(map[string]interface{})["resources"].([]interface{}), opconNs, apiVersion, kind, name, namespace) + if newResource != nil { + if _, ok := nonDefaultProfileController[serviceController]; ok { + if isOpResourceExists(newResource) { + klog.Info("### DEBUG: deleting key") + newResource.(map[string]interface{})["data"].(map[string]interface{})["spec"].(map[string]interface{})["resources"].(map[string]interface{})["limits"].(map[string]interface{})["cpu"] = struct{}{} + } + } + operator.(map[string]interface{})["resources"].([]interface{})[i] = mergeCRsIntoOperandConfigWithDefaultRules(opResource.(map[string]interface{}), newResource.(map[string]interface{}), false) + } } + csSummary = setResByName(csSummary, operator.(map[string]interface{})["name"].(string), operator.(map[string]interface{})["resources"].([]interface{})) } - csSummary = setSpecByName(csSummary, operator.(map[string]interface{})["name"].(string), summaryCR.(map[string]interface{})["spec"]) } return csSummary } // mergeCRsIntoOperandConfig merges CRs by specific rules func mergeCRsIntoOperandConfigWithDefaultRules(defaultMap map[string]interface{}, changedMap map[string]interface{}, directAssign bool) map[string]interface{} { - // TODO: Apply default rules for key := range defaultMap { if reflect.DeepEqual(defaultMap[key], changedMap[key]) { continue @@ -183,18 +229,40 @@ func mergeChangedMap(key string, defaultMap interface{}, changedMap interface{}, mergeChangedMap(newKey, defaultMapRef[newKey], changedMapRef[newKey], finalMap[key].(map[string]interface{}), directAssign) } } + case []interface{}: + //Check that the changed map value doesn't contain this map at all and is nil + if changedMap == nil { + finalMap[key] = defaultMap + } else if _, ok := changedMap.([]interface{}); ok { //Check that the changed map value is also a []interface + defaultMapRef := defaultMap + changedMapRef := changedMap.([]interface{}) + for i := range defaultMapRef { + if _, ok := defaultMapRef[i].(map[string]interface{}); ok { + if len(changedMapRef) <= i { + finalMap[key] = append(finalMap[key].([]interface{}), defaultMapRef[i]) + } else { + + for newKey := range defaultMapRef[i].(map[string]interface{}) { + mergeChangedMap(newKey, defaultMapRef[i].(map[string]interface{})[newKey], changedMapRef[i].(map[string]interface{})[newKey], finalMap[key].([]interface{})[i].(map[string]interface{}), directAssign) + } + } + } + } + } default: //Check if the value was set, otherwise set it if changedMap == nil { finalMap[key] = defaultMap } else { var comparableKeys = map[string]bool{ - "replicas": true, - "cpu": true, - "memory": true, - "profile": true, - "fipsEnabled": true, - "fips_enabled": true, + "replicas": true, + "cpu": true, + "memory": true, + "profile": true, + "fipsEnabled": true, + "fips_enabled": true, + "instances": true, + "max_connections": true, } if _, ok := comparableKeys[key]; ok { if directAssign { @@ -221,6 +289,18 @@ func mergeChangedMapWithExtremeSize(key string, defaultMap interface{}, changedM mergeChangedMapWithExtremeSize(newKey, defaultMapRef[newKey], changedMapRef[newKey], finalMap[key].(map[string]interface{}), extreme) } } + case []interface{}: + if _, ok := defaultMap.([]interface{}); ok { + defaultMapRef := defaultMap.([]interface{}) + changedMapRef := changedMap.([]interface{}) + for i := range changedMapRef { + for newKey := range changedMapRef[i].(map[string]interface{}) { + if _, ok := defaultMapRef[i].(map[string]interface{}); ok { + mergeChangedMapWithExtremeSize(newKey, defaultMapRef[i].(map[string]interface{})[newKey], changedMapRef[i].(map[string]interface{})[newKey], finalMap[key].([]interface{})[i].(map[string]interface{}), extreme) + } + } + } + } default: //Check if the value was set, otherwise set it if changedMap != nil && defaultMap != nil { @@ -260,6 +340,26 @@ func deepMergeTwoMaps(key string, defaultMap interface{}, changedMap interface{} deepMergeTwoMaps(newKey, defaultMapRef[newKey], changedMapRef[newKey], finalMap[key].(map[string]interface{})) } } + case []interface{}: + //Check that the changed map value doesn't contain this map at all and is nil + if changedMap == nil { + finalMap[key] = defaultMap + } else if _, ok := changedMap.([]interface{}); ok { //Check that the changed map value is also a []interface + defaultMapRef := defaultMap + changedMapRef := changedMap.([]interface{}) + for i := range defaultMapRef { + if _, ok := defaultMapRef[i].(map[string]interface{}); ok { + if len(changedMapRef) <= i { + finalMap[key] = append(finalMap[key].([]interface{}), defaultMapRef[i]) + } else { + + for newKey := range defaultMapRef[i].(map[string]interface{}) { + deepMergeTwoMaps(newKey, defaultMapRef[i].(map[string]interface{})[newKey], changedMapRef[i].(map[string]interface{})[newKey], finalMap[key].([]interface{})[i].(map[string]interface{})) + } + } + } + } + } default: //Check if the value was set, otherwise set it if changedMap == nil { @@ -279,7 +379,7 @@ func (r *CommonServiceReconciler) updateOperandConfig(ctx context.Context, newCo return true, err } - // Keep a version of existing config for comparasion later + // Keep a version of existing config for comparison later opconServices := opcon.Object["spec"].(map[string]interface{})["services"].([]interface{}) existingOpconServices := deepcopy.Copy(opconServices) @@ -304,32 +404,76 @@ func (r *CommonServiceReconciler) updateOperandConfig(ctx context.Context, newCo // Fetch newConfigForOperator and rules for an operator rules := getItemByName(ruleSlice, opService.(map[string]interface{})["name"].(string)) - for cr, spec := range opService.(map[string]interface{})["spec"].(map[string]interface{}) { - if _, ok := nonDefaultProfileController[serviceController]; ok { - // clean up OperandConfig - opService.(map[string]interface{})["spec"].(map[string]interface{})[cr] = resetResourceInTemplate(spec.(map[string]interface{}), cr, rules) - } + if opService.(map[string]interface{})["spec"] != nil && newConfigForOperator.(map[string]interface{})["spec"] != nil { + for cr, spec := range opService.(map[string]interface{})["spec"].(map[string]interface{}) { + if _, ok := nonDefaultProfileController[serviceController]; ok { + // clean up OperandConfig + opService.(map[string]interface{})["spec"].(map[string]interface{})[cr] = resetResourceInTemplate(spec.(map[string]interface{}), cr, rules) + } - if newConfigForOperator.(map[string]interface{})["spec"].(map[string]interface{})[cr] == nil { - continue + if newConfigForOperator.(map[string]interface{})["spec"].(map[string]interface{})[cr] == nil { + continue + } + newConfigForCR := newConfigForOperator.(map[string]interface{})["spec"].(map[string]interface{})[cr].(map[string]interface{}) + + overwrite := true + if rules != nil && rules.(map[string]interface{})["spec"] != nil && rules.(map[string]interface{})["spec"].(map[string]interface{})[cr] != nil { + ruleForCR := rules.(map[string]interface{})["spec"].(map[string]interface{})[cr].(map[string]interface{}) + opService.(map[string]interface{})["spec"].(map[string]interface{})[cr] = mergeCRsIntoOperandConfig(spec.(map[string]interface{}), newConfigForCR, ruleForCR, overwrite, true) + } else { + if overwrite { + opService.(map[string]interface{})["spec"].(map[string]interface{})[cr] = mergeCRsIntoOperandConfigWithDefaultRules(spec.(map[string]interface{}), newConfigForCR, false) + } + } } - newConfigForCR := newConfigForOperator.(map[string]interface{})["spec"].(map[string]interface{})[cr].(map[string]interface{}) + } - var overwrite bool - if opcon.Object["status"] != nil && opcon.Object["status"].(map[string]interface{})["serviceStatus"] != nil { - overwrite = checkCRFromOperandConfig(opcon.Object["status"].(map[string]interface{})["serviceStatus"].(map[string]interface{}), opService.(map[string]interface{})["name"].(string), cr) - } else { - overwrite = true - } - if rules != nil && rules.(map[string]interface{})["spec"] != nil && rules.(map[string]interface{})["spec"].(map[string]interface{})[cr] != nil { - ruleForCR := rules.(map[string]interface{})["spec"].(map[string]interface{})[cr].(map[string]interface{}) - opService.(map[string]interface{})["spec"].(map[string]interface{})[cr] = mergeCRsIntoOperandConfig(spec.(map[string]interface{}), newConfigForCR, ruleForCR, overwrite, true) - } else { - if overwrite { - opService.(map[string]interface{})["spec"].(map[string]interface{})[cr] = mergeCRsIntoOperandConfigWithDefaultRules(spec.(map[string]interface{}), newConfigForCR, false) + if opService.(map[string]interface{})["resources"] != nil { + if opResources, ok := opService.(map[string]interface{})["resources"].([]interface{}); ok { + for i, opResource := range opResources { + // get resource by checking apiVersion, kind, name, namespace + var apiVersion, kind, name, namespace string + if opResource.(map[string]interface{})["apiVersion"] != nil { + apiVersion = opResource.(map[string]interface{})["apiVersion"].(string) + } + if opResource.(map[string]interface{})["kind"] != nil { + kind = opResource.(map[string]interface{})["kind"].(string) + } + if opResource.(map[string]interface{})["name"] != nil { + name = opResource.(map[string]interface{})["name"].(string) + } + if opResource.(map[string]interface{})["namespace"] != nil { + namespace = opResource.(map[string]interface{})["namespace"].(string) + } + // check if above 4 fields are all set + if apiVersion == "" || kind == "" || name == "" { + klog.Warningf("Skipping merging resource %s/%s/%s/%s, because apiVersion, kind or name is not set", apiVersion, kind, name, namespace) + continue + } + // check if namespace is set, if not, set it to OperandConfig namespace + if namespace == "" { + namespace = opconKey.Namespace + } + + if newConfigForOperator.(map[string]interface{})["resources"] == nil { + continue + } + + newResource := getItemByGVKNameNamespace(newConfigForOperator.(map[string]interface{})["resources"].([]interface{}), opconKey.Namespace, apiVersion, kind, name, namespace) + if newResource != nil { + if _, ok := nonDefaultProfileController[serviceController]; ok { + if isOpResourceExists(newResource) { + klog.Info("### DEBUG: deleting key") + newResource.(map[string]interface{})["data"].(map[string]interface{})["spec"].(map[string]interface{})["resources"].(map[string]interface{})["limits"].(map[string]interface{})["cpu"] = struct{}{} + } + } + opResources[i] = mergeCRsIntoOperandConfigWithDefaultRules(opResource.(map[string]interface{}), newResource.(map[string]interface{}), true) + } } + opService.(map[string]interface{})["resources"] = opResources } } + } // Checking all the common service CRs to get the minimal(unique largest) size @@ -366,20 +510,18 @@ func (r *CommonServiceReconciler) updateOperandConfig(ctx context.Context, newCo return isEqual, nil } -func checkCRFromOperandConfig(serviceStatus map[string]interface{}, operatorName, crName string) bool { - opStatus, ok := serviceStatus[operatorName] - if !ok { - return true +func isOpResourceExists(opResource interface{}) bool { + if opResource.(map[string]interface{})["data"] == nil { + klog.Info("### DEBUG: data not exists") + return false } - - if opStatus.(map[string]interface{})["customResourceStatus"] == nil { - return true + if opResource.(map[string]interface{})["data"].(map[string]interface{})["spec"] == nil { + klog.Info("### DEBUG: data not exists") + return false } - - for cr := range opStatus.(map[string]interface{})["customResourceStatus"].(map[string]interface{}) { - if strings.EqualFold(cr, crName) { - return false - } + if opResource.(map[string]interface{})["data"].(map[string]interface{})["spec"].(map[string]interface{})["resources"] == nil { + klog.Info("### DEBUG: resources not exists") + return false } return true } @@ -408,20 +550,7 @@ func (r *CommonServiceReconciler) getExtremeizes(ctx context.Context, opconServi continue } - inScope := true - cm, err := util.GetCmOfMapCs(r.Reader) - if err == nil { - csScope, err := util.GetCsScope(cm, r.Bootstrap.CSData.CPFSNs) - if err != nil { - return configSummary, err - } - inScope = r.checkScope(csScope, cs.GetNamespace()) - } else if !errors.IsNotFound(err) { - klog.Errorf("Failed to get common-service-maps: %v", err) - return configSummary, err - } - - csConfigs, serviceControllerMapping, err := r.getNewConfigs(&cs, inScope) + csConfigs, serviceControllerMapping, err := r.getNewConfigs(&cs) if err != nil { return []interface{}{}, err } @@ -430,29 +559,76 @@ func (r *CommonServiceReconciler) getExtremeizes(ctx context.Context, opconServi tmpConfigsSlice[len(tmpConfigsSlice)] = csConfigs } for _, csConfigs := range tmpConfigsSlice { - configSummary = mergeCSCRs(configSummary, csConfigs, ruleSlice, serviceControllerMappingSummary) + configSummary = mergeCSCRs(configSummary, csConfigs, ruleSlice, serviceControllerMappingSummary, r.CSData.ServicesNs) } for _, opService := range opconServices { crSummary := getItemByName(configSummary, opService.(map[string]interface{})["name"].(string)) - if opService.(map[string]interface{})["spec"] == nil { - continue - } + rules := getItemByName(ruleSlice, opService.(map[string]interface{})["name"].(string)) serviceController := serviceControllerMappingSummary["profileController"] if controller, ok := serviceControllerMappingSummary[opService.(map[string]interface{})["name"].(string)]; ok { serviceController = controller } - for cr, spec := range opService.(map[string]interface{})["spec"].(map[string]interface{}) { - if _, ok := nonDefaultProfileController[serviceController]; ok { - // clean up OperandConfig - opService.(map[string]interface{})["spec"].(map[string]interface{})[cr] = resetResourceInTemplate(spec.(map[string]interface{}), cr, rules) + + if opService.(map[string]interface{})["spec"] != nil { + for cr, spec := range opService.(map[string]interface{})["spec"].(map[string]interface{}) { + if _, ok := nonDefaultProfileController[serviceController]; ok { + // clean up OperandConfig + opService.(map[string]interface{})["spec"].(map[string]interface{})[cr] = resetResourceInTemplate(spec.(map[string]interface{}), cr, rules) + } + if crSummary == nil || crSummary.(map[string]interface{})["spec"] == nil || crSummary.(map[string]interface{})["spec"].(map[string]interface{})[cr] == nil { + continue + } + serviceForCR := crSummary.(map[string]interface{})["spec"].(map[string]interface{})[cr].(map[string]interface{}) + opService.(map[string]interface{})["spec"].(map[string]interface{})[cr] = shrinkSize(spec.(map[string]interface{}), serviceForCR, extreme) } - if crSummary == nil || crSummary.(map[string]interface{})["spec"] == nil || crSummary.(map[string]interface{})["spec"].(map[string]interface{})[cr] == nil { - continue + } + + if opService.(map[string]interface{})["resources"] != nil { + if opResources, ok := opService.(map[string]interface{})["resources"].([]interface{}); ok { + for i, opResource := range opResources { + // get resource by checking apiVersion, kind, name, namespace + var apiVersion, kind, name, namespace string + if opResource.(map[string]interface{})["apiVersion"] != nil { + apiVersion = opResource.(map[string]interface{})["apiVersion"].(string) + } + if opResource.(map[string]interface{})["kind"] != nil { + kind = opResource.(map[string]interface{})["kind"].(string) + } + if opResource.(map[string]interface{})["name"] != nil { + name = opResource.(map[string]interface{})["name"].(string) + } + if opResource.(map[string]interface{})["namespace"] != nil { + namespace = opResource.(map[string]interface{})["namespace"].(string) + } + // check if above 4 fields are all set + if apiVersion == "" || kind == "" || name == "" { + klog.Warningf("Skipping merging resource %s/%s/%s/%s, because apiVersion, kind or name is not set", apiVersion, kind, name, namespace) + continue + } + // check if namespace is set, if not, set it to OperandConfig namespace + if namespace == "" { + namespace = r.CSData.ServicesNs + } + + if crSummary == nil || crSummary.(map[string]interface{})["resources"] == nil { + continue + } + + summarizedRes := getItemByGVKNameNamespace(crSummary.(map[string]interface{})["resources"].([]interface{}), r.CSData.ServicesNs, apiVersion, kind, name, namespace) + if summarizedRes != nil { + if _, ok := nonDefaultProfileController[serviceController]; ok { + if isOpResourceExists(summarizedRes) { + klog.Info("### DEBUG: deleting key") + summarizedRes.(map[string]interface{})["data"].(map[string]interface{})["spec"].(map[string]interface{})["resources"].(map[string]interface{})["limits"].(map[string]interface{})["cpu"] = struct{}{} + } + } + opResources[i] = shrinkSize(opResource.(map[string]interface{}), summarizedRes.(map[string]interface{}), extreme) + } + } + opService.(map[string]interface{})["resources"] = opResources } - serviceForCR := crSummary.(map[string]interface{})["spec"].(map[string]interface{})[cr].(map[string]interface{}) - opService.(map[string]interface{})["spec"].(map[string]interface{})[cr] = shrinkSize(spec.(map[string]interface{}), serviceForCR, extreme) } } @@ -533,6 +709,20 @@ func setSpecByName(slice []interface{}, name string, spec interface{}) []interfa return append(slice, newItem) } +func setResByName(slice []interface{}, name string, resources []interface{}) []interface{} { + for _, item := range slice { + if item.(map[string]interface{})["name"].(string) == name { + item.(map[string]interface{})["resources"] = resources + return slice + } + } + newItem := map[string]interface{}{ + "name": name, + "resources": resources, + } + return append(slice, newItem) +} + // Check if the request's NamespacedName is the "master" CR func (r *CommonServiceReconciler) checkNamespace(key string) bool { return key == r.Bootstrap.CSData.OperatorNs+"/common-service" @@ -544,17 +734,6 @@ func (r *CommonServiceReconciler) updatePhase(ctx context.Context, instance *api return r.Client.Status().Update(ctx, instance) } -// checkScope checks whether the namespace is in scope -func (r *CommonServiceReconciler) checkScope(csScope []string, key string) bool { - inScope := false - if !r.Bootstrap.MultiInstancesEnable || len(csScope) == 0 { - inScope = true - } else { - inScope = util.Contains(csScope, key) - } - return inScope -} - func resetResourceInTemplate(changedMap map[string]interface{}, cr string, rules interface{}) map[string]interface{} { var rulesForCR map[string]interface{} if rules != nil && rules.(map[string]interface{})["spec"] != nil && rules.(map[string]interface{})["spec"].(map[string]interface{})[cr] != nil { @@ -595,3 +774,22 @@ func resetChangedMap(key string, changedMap interface{}, rulesForCR, finalMap ma } } } + +func getItemByGVKNameNamespace(opResources []interface{}, opconNs, apiVersion, kind, name, namespace string) interface{} { + for _, opResource := range opResources { + if opResource.(map[string]interface{})["apiVersion"].(string) == apiVersion && + opResource.(map[string]interface{})["kind"].(string) == kind && + opResource.(map[string]interface{})["name"].(string) == name { + if opResNs, ok := opResource.(map[string]interface{})["namespace"]; ok { + if opResNs.(string) == namespace { + return opResource + } + } else { + if opconNs == namespace { + return opResource + } + } + } + } + return nil +} diff --git a/controllers/operatorconfig.go b/controllers/operatorconfig.go new file mode 100644 index 000000000..d35a64219 --- /dev/null +++ b/controllers/operatorconfig.go @@ -0,0 +1,123 @@ +// +// Copyright 2024 IBM Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package controllers + +import ( + "context" + "errors" + "fmt" + "strings" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/types" + "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" +) + +func (r *CommonServiceReconciler) updateOperatorConfig(ctx context.Context, configList []v3.OperatorConfig) (bool, error) { + klog.Info("Applying OperatorConfig") + + if configList == nil { + if err := r.clearAllUserManaged(ctx); err != nil { + return false, err + } + return true, nil + } + + // TODO: remove when this feature is generalized to all other operators + for _, c := range configList { + config := c + packageName, err := r.fetchPackageNameFromOpReg(ctx, config.Name) + if err != nil { + return false, err + } + 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 + } + } + + operatorConfig := &odlm.OperatorConfig{} + if err := r.Reader.Get(ctx, types.NamespacedName{ + Name: "test-operator-config", + Namespace: r.Bootstrap.CSData.ServicesNs, + }, operatorConfig); err != nil { + if !apierrors.IsNotFound(err) { + klog.Errorf("failed to get OperatorConfig %s/%s: %v", operatorConfig.GetNamespace(), operatorConfig.GetName(), err) + return true, err + } + } + replicas := *configList[0].Replicas + replacer := strings.NewReplacer("placeholder-size", fmt.Sprintf("%d", replicas)) + updatedConfig := replacer.Replace(constant.PostGresOperatorConfig) + klog.V(2).Infof("OperatorConfig to be applied will be: %v", updatedConfig) + + if err := r.Bootstrap.InstallOrUpdateOperatorConfig(updatedConfig, true); err != nil { + return false, err + } + return false, nil +} + +func (r *CommonServiceReconciler) fetchPackageNameFromOpReg(ctx context.Context, name string) (string, error) { + registry, err := r.GetOperandRegistry(ctx, "common-service", r.CSData.ServicesNs) + if err != nil { + return "", err + } + + for _, r := range registry.Spec.Operators { + operator := r + if operator.Name == name { + return operator.PackageName, nil + } + } + 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) +} diff --git a/controllers/recocile_pause.go b/controllers/recocile_pause.go new file mode 100644 index 000000000..a038bff02 --- /dev/null +++ b/controllers/recocile_pause.go @@ -0,0 +1,73 @@ +// +// Copyright 2022 IBM Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package controllers + +import ( + "k8s.io/klog" + + apiv3 "github.com/IBM/ibm-common-service-operator/v4/api/v3" +) + +const ( + PauseRequestAnnoKey = "commonservices.operator.ibm.com/pause" + SelfPauseRequestAnnoKey = "commonservices.operator.ibm.com/self-pause" + PauseRequestValue = "true" +) + +func (r *CommonServiceReconciler) reconcilePauseRequest(instance *apiv3.CommonService) bool { + + //klog.Info("Request Stage: ReconcilePauseRequest") + + // if the given CommnService CR has not been existing + if instance == nil { + return false + } + + // check if there is a pause request annotation in the CommonService CR + return r.pauseRequestExists(instance) + + // future implementation: TO DO + // check and set pauseExpire annotation + // if the time is expired, remove the pause annotation +} + +func (r *CommonServiceReconciler) pauseRequestExists(instance *apiv3.CommonService) bool { + klog.Info("Checking annotations for pause request") + + // if there is pause or self-pause request annotation in the CommonService CR, pause request takes precedence over self-pause request + var pauseRequestFound bool + var selfpauseRequestFound bool + if instance.ObjectMeta.Annotations != nil { + for key := range instance.ObjectMeta.Annotations { + if key == PauseRequestAnnoKey { + pauseRequestFound = true + klog.Infof("Found pause request annotation: %v", instance.ObjectMeta.Annotations[PauseRequestAnnoKey]) + } else if key == SelfPauseRequestAnnoKey { + selfpauseRequestFound = true + klog.Infof("Found self-pause request annotation: %v", instance.ObjectMeta.Annotations[SelfPauseRequestAnnoKey]) + } + } + // Pause request takes precedence over self-pause request + if pauseRequestFound { + return instance.ObjectMeta.Annotations[PauseRequestAnnoKey] == PauseRequestValue + } else if selfpauseRequestFound { + return instance.ObjectMeta.Annotations[SelfPauseRequestAnnoKey] == PauseRequestValue + } + return false + } + return false +} diff --git a/controllers/render_template.go b/controllers/render_template.go index 30bba572b..3860cb7e5 100644 --- a/controllers/render_template.go +++ b/controllers/render_template.go @@ -17,23 +17,33 @@ package controllers import ( + "bytes" + "context" + "encoding/json" + "fmt" "strconv" "strings" + "text/template" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/types" "k8s.io/klog" - "github.com/IBM/ibm-common-service-operator/controllers/constant" - "github.com/IBM/ibm-common-service-operator/controllers/size" + apiv3 "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" + "github.com/IBM/ibm-common-service-operator/v4/controllers/size" ) -var ( - clusterScopeOperators = []string{"ibm-cert-manager-operator", "ibm-licensing-operator"} -) - -func (r *CommonServiceReconciler) getNewConfigs(cs *unstructured.Unstructured, inScope bool) ([]interface{}, map[string]string, error) { +func (r *CommonServiceReconciler) getNewConfigs(cs *unstructured.Unstructured) ([]interface{}, map[string]string, error) { var newConfigs []interface{} var err error + + csObject := &apiv3.CommonService{} + if err := r.Client.Get(context.TODO(), types.NamespacedName{Name: cs.GetName(), Namespace: cs.GetNamespace()}, csObject); err != nil { + return nil, nil, err + } + // Update storageclass in OperandConfig if cs.Object["spec"].(map[string]interface{})["storageClass"] != nil { klog.Info("Applying storageClass configuration") @@ -44,6 +54,28 @@ func (r *CommonServiceReconciler) getNewConfigs(cs *unstructured.Unstructured, i newConfigs = append(newConfigs, storageConfig...) } + // Update EnableInstanaMetricCollection in OperandConfig + if cs.Object["spec"].(map[string]interface{})["enableInstanaMetricCollection"] != nil { + klog.Info("Applying enableInstanaMetricCollection configuration") + + t := template.Must(template.New("template InstanaEnable").Parse(constant.InstanaEnableTemplate)) + var tmplWriter bytes.Buffer + instanaEnable := struct { + InstanaEnable bool + }{ + InstanaEnable: cs.Object["spec"].(map[string]interface{})["enableInstanaMetricCollection"].(bool), + } + if err := t.Execute(&tmplWriter, instanaEnable); err != nil { + return nil, nil, err + } + s := tmplWriter.String() + instanaConfig, err := convertStringToSlice(s) + if err != nil { + return nil, nil, err + } + newConfigs = append(newConfigs, instanaConfig...) + } + // Update routeHost if cs.Object["spec"].(map[string]interface{})["routeHost"] != nil { klog.Info("Applying routeHost configuration") @@ -64,16 +96,6 @@ func (r *CommonServiceReconciler) getNewConfigs(cs *unstructured.Unstructured, i newConfigs = append(newConfigs, adminUsernameConfig...) } - // Update multipleInstancesEnabled when multi-instances - if r.Bootstrap.MultiInstancesEnable { - klog.Info("Applying multipleInstancesEnabled configuration") - multipleinstancesenabledConfig, err := convertStringToSlice(strings.ReplaceAll(constant.MultipleInstancesEnabledTemplate, "placeholder", "true")) - if err != nil { - return nil, nil, err - } - newConfigs = append(newConfigs, multipleinstancesenabledConfig...) - } - // if there is a fipsEnabled field for overall if enabled := cs.Object["spec"].(map[string]interface{})["fipsEnabled"]; enabled != nil { klog.Info("Applying fips configuration") @@ -85,6 +107,33 @@ func (r *CommonServiceReconciler) getNewConfigs(cs *unstructured.Unstructured, i newConfigs = append(newConfigs, fipsEnabledConfig...) } + // if there is a hugepage setting enabled + if hugespages := cs.Object["spec"].(map[string]interface{})["hugepages"]; hugespages != nil { + klog.Info("Applying hugepages configuration") + if enable := hugespages.(map[string]interface{})["enable"]; enable != nil && enable.(bool) { + hugePagesStruct, err := UnmarshalHugePages(hugespages) + if err != nil { + return nil, nil, err + } + for size, allocation := range hugePagesStruct.HugePagesSizes { + if !strings.HasPrefix(size, "hugepages-") { + return nil, nil, fmt.Errorf("invalid hugepage size format: %s", size) + } + + if allocation == "" { + allocation = constant.DefaultHugePageAllocation + } + replacer := strings.NewReplacer("placeholder1", size, "placeholder2", allocation) + hugePagesConfig, err := convertStringToSlice(replacer.Replace(constant.HugePagesTemplate)) + if err != nil { + return nil, nil, err + } + newConfigs = append(newConfigs, hugePagesConfig...) + } + + } + } + // Update storageclass for API Catalog if features := cs.Object["spec"].(map[string]interface{})["features"]; features != nil { if apiCatalog := features.(map[string]interface{})["apiCatalog"]; apiCatalog != nil { @@ -98,6 +147,19 @@ func (r *CommonServiceReconciler) getNewConfigs(cs *unstructured.Unstructured, i } } + if labels := cs.Object["spec"].(map[string]interface{})["labels"]; labels != nil { + klog.Info("Applying label configuration") + labelset := csObject.Spec.Labels + for key, value := range labelset { + replacer := strings.NewReplacer("placeholder1", key, "placeholder2", value) + labelConfig, err := convertStringToSlice(replacer.Replace(constant.ServiceLabelTemplate)) + if err != nil { + return nil, nil, err + } + newConfigs = append(newConfigs, labelConfig...) + } + } + klog.Info("Applying size configuration") var sizeConfigs []interface{} serviceControllerMapping := make(map[string]string) @@ -108,49 +170,38 @@ func (r *CommonServiceReconciler) getNewConfigs(cs *unstructured.Unstructured, i switch cs.Object["spec"].(map[string]interface{})["size"] { case "starterset", "starter": - sizeConfigs, serviceControllerMapping, err = applySizeTemplate(cs, size.StarterSet, serviceControllerMapping, inScope) + sizeConfigs, serviceControllerMapping, err = applySizeTemplate(cs, size.StarterSet, serviceControllerMapping, r.CSData.ServicesNs) if err != nil { return sizeConfigs, serviceControllerMapping, err } case "small": - sizeConfigs, serviceControllerMapping, err = applySizeTemplate(cs, size.Small, serviceControllerMapping, inScope) + sizeConfigs, serviceControllerMapping, err = applySizeTemplate(cs, size.Small, serviceControllerMapping, r.CSData.ServicesNs) if err != nil { return sizeConfigs, serviceControllerMapping, err } case "medium": - sizeConfigs, serviceControllerMapping, err = applySizeTemplate(cs, size.Medium, serviceControllerMapping, inScope) + sizeConfigs, serviceControllerMapping, err = applySizeTemplate(cs, size.Medium, serviceControllerMapping, r.CSData.ServicesNs) if err != nil { return sizeConfigs, serviceControllerMapping, err } case "large", "production": - sizeConfigs, serviceControllerMapping, err = applySizeTemplate(cs, size.Large, serviceControllerMapping, inScope) + sizeConfigs, serviceControllerMapping, err = applySizeTemplate(cs, size.Large, serviceControllerMapping, r.CSData.ServicesNs) if err != nil { return sizeConfigs, serviceControllerMapping, err } default: - sizeConfigs, serviceControllerMapping = applySizeConfigs(cs, serviceControllerMapping, inScope) + sizeConfigs, serviceControllerMapping = applySizeConfigs(cs, serviceControllerMapping) } newConfigs = append(newConfigs, sizeConfigs...) return newConfigs, serviceControllerMapping, nil } -func applySizeConfigs(cs *unstructured.Unstructured, serviceControllerMapping map[string]string, inScope bool) ([]interface{}, map[string]string) { +func applySizeConfigs(cs *unstructured.Unstructured, serviceControllerMapping map[string]string) ([]interface{}, map[string]string) { var dest []interface{} + if cs.Object["spec"].(map[string]interface{})["services"] != nil { for _, configSize := range cs.Object["spec"].(map[string]interface{})["services"].([]interface{}) { - if !inScope { - isClusterScope := false - for _, operator := range clusterScopeOperators { - if configSize.(map[string]interface{})["name"].(string) == operator { - isClusterScope = true - break - } - } - if !isClusterScope { - continue - } - } if controller, ok := configSize.(map[string]interface{})["managementStrategy"]; ok { serviceControllerMapping[configSize.(map[string]interface{})["name"].(string)] = controller.(string) } @@ -161,7 +212,7 @@ func applySizeConfigs(cs *unstructured.Unstructured, serviceControllerMapping ma return dest, serviceControllerMapping } -func applySizeTemplate(cs *unstructured.Unstructured, sizeTemplate string, serviceControllerMapping map[string]string, inScope bool) ([]interface{}, map[string]string, error) { +func applySizeTemplate(cs *unstructured.Unstructured, sizeTemplate string, serviceControllerMapping map[string]string, opconNs string) ([]interface{}, map[string]string, error) { var src []interface{} if cs.Object["spec"].(map[string]interface{})["services"] != nil { @@ -174,20 +225,11 @@ func applySizeTemplate(cs *unstructured.Unstructured, sizeTemplate string, servi klog.Errorf("convert size to interface slice: %v", err) return nil, nil, err } - var newSizes []interface{} - if !inScope { - // delete all namespace-scoped operator's template - for _, configSize := range sizes { - for _, operator := range clusterScopeOperators { - if configSize.(map[string]interface{})["name"].(string) == operator { - newSizes = append(newSizes, configSize) - } - } - } - sizes = newSizes - } - for _, configSize := range sizes { + for i, configSize := range sizes { + if configSize == nil { + continue + } config := getItemByName(src, configSize.(map[string]interface{})["name"].(string)) if config == nil { continue @@ -195,12 +237,68 @@ func applySizeTemplate(cs *unstructured.Unstructured, sizeTemplate string, servi if controller, ok := config.(map[string]interface{})["managementStrategy"]; ok { serviceControllerMapping[configSize.(map[string]interface{})["name"].(string)] = controller.(string) } - if configSize == nil { - continue + // check if configSize['spec'] and config['spec'] are not nil + if configSize.(map[string]interface{})["spec"] != nil && config.(map[string]interface{})["spec"] != nil { + for cr, size := range mergeSizeProfile(configSize.(map[string]interface{})["spec"].(map[string]interface{}), config.(map[string]interface{})["spec"].(map[string]interface{})) { + configSize.(map[string]interface{})["spec"].(map[string]interface{})[cr] = size + } } - for cr, size := range mergeSizeProfile(configSize.(map[string]interface{})["spec"].(map[string]interface{}), config.(map[string]interface{})["spec"].(map[string]interface{})) { - configSize.(map[string]interface{})["spec"].(map[string]interface{})[cr] = size + // check if configSize['resources'] and config['resources'] are not nil + if configSize.(map[string]interface{})["resources"] != nil && config.(map[string]interface{})["resources"] != nil { + // loop through configSize['resources'] and config['resources'] + for i, res := range configSize.(map[string]interface{})["resources"].([]interface{}) { + var apiVersion, kind, name, namespace string + if res.(map[string]interface{})["apiVersion"] != nil { + apiVersion = res.(map[string]interface{})["apiVersion"].(string) + } + if res.(map[string]interface{})["kind"] != nil { + kind = res.(map[string]interface{})["kind"].(string) + } + if res.(map[string]interface{})["name"] != nil { + name = res.(map[string]interface{})["name"].(string) + } + if res.(map[string]interface{})["namespace"] != nil { + namespace = res.(map[string]interface{})["namespace"].(string) + } + // check if above 4 fields are all set + if apiVersion == "" || kind == "" || name == "" { + klog.Warningf("Skipping merging resource %s/%s/%s/%s, because apiVersion, kind or name is not set", apiVersion, kind, name, namespace) + continue + } + // check if namespace is set, if not, set it to OperandConfig namespace + if namespace == "" { + namespace = opconNs + } + newConfig := getItemByGVKNameNamespace(config.(map[string]interface{})["resources"].([]interface{}), opconNs, apiVersion, kind, name, namespace) + if newConfig != nil { + configSize.(map[string]interface{})["resources"].([]interface{})[i] = mergeSizeProfile(res.(map[string]interface{}), newConfig.(map[string]interface{})) + } + } + sizes[i].(map[string]interface{})["resources"] = configSize.(map[string]interface{})["resources"] } } return sizes, serviceControllerMapping, nil } + +// UnmarshalHugePages unmarshals the hugepages map to HugePages struct +func UnmarshalHugePages(hugespages interface{}) (*apiv3.HugePages, error) { + hugespagesBytes, err := json.Marshal(hugespages) + if err != nil { + return nil, err + } + + hugePagesStruct := &apiv3.HugePages{} + if err := json.Unmarshal(hugespagesBytes, hugePagesStruct); err != nil { + return nil, err + } + + hugespagesBytesSanitized, err := json.Marshal(util.SanitizeData(hugespages, "string", true)) + if err != nil { + return nil, err + } + if err := json.Unmarshal(hugespagesBytesSanitized, &hugePagesStruct.HugePagesSizes); err != nil { + return nil, err + } + + return hugePagesStruct, nil +} diff --git a/controllers/render_template_test.go b/controllers/render_template_test.go new file mode 100644 index 000000000..fec60a207 --- /dev/null +++ b/controllers/render_template_test.go @@ -0,0 +1,71 @@ +// +// Copyright 2022 IBM Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package controllers + +import ( + "testing" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + apiv3 "github.com/IBM/ibm-common-service-operator/v4/api/v3" +) + +var _ = Describe("Render Template", func() { + Describe("unmarshalHugePages", func() { + It("should unmarshal the input map into a HugePages struct", func() { + hugePages := map[string]interface{}{ + "enable": true, + "hugepages-2Gi": "", + "hugepages-2Mi": "1Gi", + } + + hugePagesStruct, err := UnmarshalHugePages(hugePages) + Expect(err).To(BeNil()) + Expect(hugePagesStruct).To(Equal(&apiv3.HugePages{ + HugePagesSizes: map[string]string{ + "hugepages-2Gi": "", + "hugepages-2Mi": "1Gi", + }, + })) + }) + + It("should unmarshal the input map into a HugePages struct and sanitize the invalid value", func() { + hugePages := map[string]interface{}{ + "enable": true, + "replica": 1, // invalid value + "hugepages-2Gi": "", + "hugepages-2Mi": "1Gi", + } + + hugePagesStruct, err := UnmarshalHugePages(hugePages) + Expect(err).To(BeNil()) + Expect(hugePagesStruct).To(Equal(&apiv3.HugePages{ + Enable: true, + HugePagesSizes: map[string]string{ + "hugepages-2Gi": "", + "hugepages-2Mi": "1Gi", + }, + })) + }) + }) +}) + +func TestRenderTemplate(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Render Template Suite") +} diff --git a/controllers/rules/rules.go b/controllers/rules/rules.go index a1f347347..54f092347 100644 --- a/controllers/rules/rules.go +++ b/controllers/rules/rules.go @@ -74,6 +74,26 @@ const ConfigurationRules = ` cpu: LARGEST_VALUE memory: LARGEST_VALUE ephemeral-storage: LARGEST_VALUE +- name: common-service-postgresql + resources: + - apiVersion: postgresql.k8s.enterprisedb.io/v1 + kind: Cluster + name: common-service-db + data: + spec: + instances: LARGEST_VALUE + resources: + limits: + cpu: LARGEST_VALUE + memory: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + requests: + ephemeral-storage: LARGEST_VALUE + cpu: LARGEST_VALUE + memory: LARGEST_VALUE + postgresql: + parameters: + max_connections: LARGEST_VALUE - name: ibm-im-mongodb-operator spec: mongoDB: @@ -543,6 +563,230 @@ const ConfigurationRules = ` cpu: LARGEST_VALUE ephemeral-storage: LARGEST_VALUE memory: LARGEST_VALUE +- name: ibm-im-operator-v4.3 + spec: + authentication: + config: + fipsEnabled: LARGEST_VALUE + replicas: LARGEST_VALUE + authService: + resources: + limits: + cpu: LARGEST_VALUE + memory: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + requests: + cpu: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + memory: LARGEST_VALUE + clientRegistration: + resources: + limits: + cpu: LARGEST_VALUE + memory: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + requests: + cpu: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + memory: LARGEST_VALUE + identityManager: + resources: + limits: + cpu: LARGEST_VALUE + memory: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + requests: + cpu: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + memory: LARGEST_VALUE + identityProvider: + resources: + limits: + cpu: LARGEST_VALUE + memory: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + requests: + cpu: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + memory: LARGEST_VALUE + initMongodb: + resources: + limits: + cpu: LARGEST_VALUE + memory: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + requests: + cpu: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + memory: LARGEST_VALUE +- name: ibm-im-operator-v4.4 + spec: + authentication: + config: + fipsEnabled: LARGEST_VALUE + replicas: LARGEST_VALUE + authService: + resources: + limits: + cpu: LARGEST_VALUE + memory: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + requests: + cpu: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + memory: LARGEST_VALUE + clientRegistration: + resources: + limits: + cpu: LARGEST_VALUE + memory: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + requests: + cpu: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + memory: LARGEST_VALUE + identityManager: + resources: + limits: + cpu: LARGEST_VALUE + memory: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + requests: + cpu: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + memory: LARGEST_VALUE + identityProvider: + resources: + limits: + cpu: LARGEST_VALUE + memory: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + requests: + cpu: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + memory: LARGEST_VALUE + initMongodb: + resources: + limits: + cpu: LARGEST_VALUE + memory: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + requests: + cpu: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + memory: LARGEST_VALUE +- name: ibm-im-operator-v4.5 + spec: + authentication: + config: + fipsEnabled: LARGEST_VALUE + replicas: LARGEST_VALUE + authService: + resources: + limits: + cpu: LARGEST_VALUE + memory: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + requests: + cpu: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + memory: LARGEST_VALUE + clientRegistration: + resources: + limits: + cpu: LARGEST_VALUE + memory: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + requests: + cpu: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + memory: LARGEST_VALUE + identityManager: + resources: + limits: + cpu: LARGEST_VALUE + memory: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + requests: + cpu: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + memory: LARGEST_VALUE + identityProvider: + resources: + limits: + cpu: LARGEST_VALUE + memory: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + requests: + cpu: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + memory: LARGEST_VALUE + initMongodb: + resources: + limits: + cpu: LARGEST_VALUE + memory: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + requests: + cpu: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + memory: LARGEST_VALUE +- name: ibm-im-operator-v4.6 + spec: + authentication: + config: + fipsEnabled: LARGEST_VALUE + replicas: LARGEST_VALUE + authService: + resources: + limits: + cpu: LARGEST_VALUE + memory: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + requests: + cpu: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + memory: LARGEST_VALUE + clientRegistration: + resources: + limits: + cpu: LARGEST_VALUE + memory: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + requests: + cpu: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + memory: LARGEST_VALUE + identityManager: + resources: + limits: + cpu: LARGEST_VALUE + memory: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + requests: + cpu: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + memory: LARGEST_VALUE + identityProvider: + resources: + limits: + cpu: LARGEST_VALUE + memory: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + requests: + cpu: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + memory: LARGEST_VALUE + initMongodb: + resources: + limits: + cpu: LARGEST_VALUE + memory: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + requests: + cpu: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + memory: LARGEST_VALUE - name: ibm-management-ingress-operator spec: managementIngress: @@ -746,6 +990,78 @@ const ConfigurationRules = ` cpu: LARGEST_VALUE memory: LARGEST_VALUE ephemeral-storage: LARGEST_VALUE +- name: ibm-idp-config-ui-operator-v4.3 + spec: + commonWebUI: + replicas: LARGEST_VALUE + resources: + requests: + memory: LARGEST_VALUE + cpu: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + limits: + memory: LARGEST_VALUE + cpu: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + commonWebUIConfig: + dashboardData: + resources: + limits: + cpu: LARGEST_VALUE + memory: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + requests: + cpu: LARGEST_VALUE + memory: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE +- name: ibm-idp-config-ui-operator-v4.4 + spec: + commonWebUI: + replicas: LARGEST_VALUE + resources: + requests: + memory: LARGEST_VALUE + cpu: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + limits: + memory: LARGEST_VALUE + cpu: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + commonWebUIConfig: + dashboardData: + resources: + limits: + cpu: LARGEST_VALUE + memory: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + requests: + cpu: LARGEST_VALUE + memory: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE +- name: ibm-idp-config-ui-operator-v4.5 + spec: + commonWebUI: + replicas: LARGEST_VALUE + resources: + requests: + memory: LARGEST_VALUE + cpu: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + limits: + memory: LARGEST_VALUE + cpu: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + commonWebUIConfig: + dashboardData: + resources: + limits: + cpu: LARGEST_VALUE + memory: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + requests: + cpu: LARGEST_VALUE + memory: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE - name: ibm-platform-api-operator spec: platformApi: @@ -845,4 +1161,49 @@ const ConfigurationRules = ` spec: apicatalogmanager: profile: LARGEST_VALUE +- name: edb-keycloak + resources: + - apiVersion: postgresql.k8s.enterprisedb.io/v1 + kind: Cluster + name: keycloak-edb-cluster + data: + spec: + instances: LARGEST_VALUE + resources: + limits: + cpu: LARGEST_VALUE + memory: LARGEST_VALUE + requests: + cpu: LARGEST_VALUE + memory: LARGEST_VALUE +- name: keycloak-operator + resources: + - apiVersion: k8s.keycloak.org/v2alpha1 + kind: Keycloak + name: cs-keycloak + data: + spec: + instances: LARGEST_VALUE + resources: + limits: + cpu: LARGEST_VALUE + memory: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + requests: + cpu: LARGEST_VALUE + memory: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + unsupported: + podTemplate: + spec: + containers: + - resources: + limits: + cpu: LARGEST_VALUE + memory: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE + requests: + cpu: LARGEST_VALUE + memory: LARGEST_VALUE + ephemeral-storage: LARGEST_VALUE ` diff --git a/controllers/size/large_amd64.go b/controllers/size/large_amd64.go index 2e2d4c702..40772b397 100644 --- a/controllers/size/large_amd64.go +++ b/controllers/size/large_amd64.go @@ -68,6 +68,26 @@ const Large = ` limits: cpu: 1000m memory: 350Mi +- name: common-service-postgresql + resources: + - apiVersion: postgresql.k8s.enterprisedb.io/v1 + kind: Cluster + name: common-service-db + data: + spec: + instances: 2 + resources: + limits: + cpu: 750m + memory: 1650Mi + ephemeral-storage: 700Mi + requests: + ephemeral-storage: 200Mi + cpu: 225m + memory: 600Mi + postgresql: + parameters: + max_connections: "1100" - name: ibm-im-mongodb-operator spec: mongoDB: @@ -449,6 +469,166 @@ const Large = ` ephemeral-storage: 256Mi cpu: 570m memory: 250Mi +- name: ibm-im-operator-v4.3 + spec: + authentication: + replicas: 3 + authService: + resources: + limits: + cpu: 2000m + memory: 1090Mi + requests: + ephemeral-storage: 256Mi + cpu: 600m + memory: 540Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 50Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 1270Mi + requests: + ephemeral-storage: 256Mi + cpu: 260m + memory: 240Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 920Mi + requests: + ephemeral-storage: 256Mi + cpu: 570m + memory: 250Mi +- name: ibm-im-operator-v4.4 + spec: + authentication: + replicas: 3 + authService: + resources: + limits: + cpu: 2000m + memory: 1090Mi + requests: + ephemeral-storage: 256Mi + cpu: 600m + memory: 540Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 50Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 1270Mi + requests: + ephemeral-storage: 256Mi + cpu: 260m + memory: 240Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 920Mi + requests: + ephemeral-storage: 256Mi + cpu: 570m + memory: 250Mi +- name: ibm-im-operator-v4.5 + spec: + authentication: + replicas: 3 + authService: + resources: + limits: + cpu: 2000m + memory: 1090Mi + requests: + ephemeral-storage: 256Mi + cpu: 600m + memory: 540Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 50Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 1270Mi + requests: + ephemeral-storage: 256Mi + cpu: 260m + memory: 240Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 920Mi + requests: + ephemeral-storage: 256Mi + cpu: 570m + memory: 250Mi +- name: ibm-im-operator-v4.6 + spec: + authentication: + replicas: 3 + authService: + resources: + limits: + cpu: 2000m + memory: 1090Mi + requests: + ephemeral-storage: 256Mi + cpu: 600m + memory: 540Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 50Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 1270Mi + requests: + ephemeral-storage: 256Mi + cpu: 260m + memory: 240Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 920Mi + requests: + ephemeral-storage: 256Mi + cpu: 570m + memory: 250Mi - name: ibm-management-ingress-operator spec: managementIngress: @@ -583,6 +763,42 @@ const Large = ` limits: memory: 660Mi cpu: 1000m +- name: ibm-idp-config-ui-operator-v4.3 + spec: + commonWebUI: + replicas: 3 + resources: + requests: + ephemeral-storage: 256Mi + memory: 490Mi + cpu: 450m + limits: + memory: 660Mi + cpu: 1000m +- name: ibm-idp-config-ui-operator-v4.4 + spec: + commonWebUI: + replicas: 3 + resources: + requests: + ephemeral-storage: 256Mi + memory: 490Mi + cpu: 450m + limits: + memory: 660Mi + cpu: 1000m +- name: ibm-idp-config-ui-operator-v4.5 + spec: + commonWebUI: + replicas: 3 + resources: + requests: + ephemeral-storage: 256Mi + memory: 490Mi + cpu: 450m + limits: + memory: 660Mi + cpu: 1000m - name: ibm-platform-api-operator spec: platformApi: @@ -674,4 +890,49 @@ const Large = ` spec: apicatalogmanager: profile: large +- name: edb-keycloak + resources: + - apiVersion: postgresql.k8s.enterprisedb.io/v1 + kind: Cluster + name: keycloak-edb-cluster + data: + spec: + instances: 3 + resources: + limits: + cpu: 750m + memory: 1500Mi + requests: + cpu: 750m + memory: 1500Mi +- name: keycloak-operator + resources: + - apiVersion: k8s.keycloak.org/v2alpha1 + kind: Keycloak + name: cs-keycloak + data: + spec: + instances: 3 + resources: + limits: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 512Mi + requests: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 256Mi + unsupported: + podTemplate: + spec: + containers: + - resources: + limits: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 512Mi + requests: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 256Mi ` diff --git a/controllers/size/large_ppc64le.go b/controllers/size/large_ppc64le.go index f93c1daf8..d87503236 100644 --- a/controllers/size/large_ppc64le.go +++ b/controllers/size/large_ppc64le.go @@ -68,6 +68,26 @@ const Large = ` limits: cpu: 1000m memory: 350Mi +- name: common-service-postgresql + resources: + - apiVersion: postgresql.k8s.enterprisedb.io/v1 + kind: Cluster + name: common-service-db + data: + spec: + instances: 2 + resources: + limits: + cpu: 1500m + memory: 3072Mi + ephemeral-storage: 1024Mi + requests: + ephemeral-storage: 500Mi + cpu: 384m + memory: 768Mi + postgresql: + parameters: + max_connections: "1100" - name: ibm-im-mongodb-operator spec: mongoDB: @@ -449,6 +469,166 @@ const Large = ` cpu: 410m memory: 335Mi replicas: 3 +- name: ibm-im-operator-v4.3 + spec: + authentication: + authService: + resources: + limits: + cpu: 3000m + memory: 1201Mi + requests: + ephemeral-storage: 256Mi + cpu: 725m + memory: 695Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 300Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 645Mi + requests: + ephemeral-storage: 256Mi + cpu: 340m + memory: 385Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 480Mi + requests: + ephemeral-storage: 256Mi + cpu: 410m + memory: 335Mi + replicas: 3 +- name: ibm-im-operator-v4.4 + spec: + authentication: + authService: + resources: + limits: + cpu: 3000m + memory: 1201Mi + requests: + ephemeral-storage: 256Mi + cpu: 725m + memory: 695Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 300Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 645Mi + requests: + ephemeral-storage: 256Mi + cpu: 340m + memory: 385Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 480Mi + requests: + ephemeral-storage: 256Mi + cpu: 410m + memory: 335Mi + replicas: 3 +- name: ibm-im-operator-v4.5 + spec: + authentication: + authService: + resources: + limits: + cpu: 3000m + memory: 1201Mi + requests: + ephemeral-storage: 256Mi + cpu: 725m + memory: 695Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 300Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 645Mi + requests: + ephemeral-storage: 256Mi + cpu: 340m + memory: 385Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 480Mi + requests: + ephemeral-storage: 256Mi + cpu: 410m + memory: 335Mi + replicas: 3 +- name: ibm-im-operator-v4.6 + spec: + authentication: + authService: + resources: + limits: + cpu: 3000m + memory: 1201Mi + requests: + ephemeral-storage: 256Mi + cpu: 725m + memory: 695Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 300Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 645Mi + requests: + ephemeral-storage: 256Mi + cpu: 340m + memory: 385Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 480Mi + requests: + ephemeral-storage: 256Mi + cpu: 410m + memory: 335Mi + replicas: 3 - name: ibm-management-ingress-operator spec: managementIngress: @@ -583,6 +763,42 @@ const Large = ` ephemeral-storage: 256Mi cpu: 300m memory: 384Mi +- name: ibm-idp-config-ui-operator-v4.3 + spec: + commonWebUI: + replicas: 3 + resources: + limits: + cpu: 1000m + memory: 1225Mi + requests: + ephemeral-storage: 256Mi + cpu: 300m + memory: 384Mi +- name: ibm-idp-config-ui-operator-v4.4 + spec: + commonWebUI: + replicas: 3 + resources: + limits: + cpu: 1000m + memory: 1225Mi + requests: + ephemeral-storage: 256Mi + cpu: 300m + memory: 384Mi +- name: ibm-idp-config-ui-operator-v4.5 + spec: + commonWebUI: + replicas: 3 + resources: + limits: + cpu: 1000m + memory: 1225Mi + requests: + ephemeral-storage: 256Mi + cpu: 300m + memory: 384Mi - name: ibm-platform-api-operator spec: platformApi: @@ -674,4 +890,49 @@ const Large = ` spec: apicatalogmanager: profile: large +- name: edb-keycloak + resources: + - apiVersion: postgresql.k8s.enterprisedb.io/v1 + kind: Cluster + name: keycloak-edb-cluster + data: + spec: + instances: 3 + resources: + limits: + cpu: 750m + memory: 1500Mi + requests: + cpu: 750m + memory: 1500Mi +- name: keycloak-operator + resources: + - apiVersion: k8s.keycloak.org/v2alpha1 + kind: Keycloak + name: cs-keycloak + data: + spec: + instances: 3 + resources: + limits: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 512Mi + requests: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 256Mi + unsupported: + podTemplate: + spec: + containers: + - resources: + limits: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 512Mi + requests: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 256Mi ` diff --git a/controllers/size/large_s390x.go b/controllers/size/large_s390x.go index fc1cdca47..6cfb184c5 100644 --- a/controllers/size/large_s390x.go +++ b/controllers/size/large_s390x.go @@ -68,6 +68,26 @@ const Large = ` limits: cpu: 1000m memory: 350Mi +- name: common-service-postgresql + resources: + - apiVersion: postgresql.k8s.enterprisedb.io/v1 + kind: Cluster + name: common-service-db + data: + spec: + instances: 2 + resources: + limits: + cpu: 1500m + memory: 3072Mi + ephemeral-storage: 1024Mi + requests: + ephemeral-storage: 500Mi + cpu: 384m + memory: 768Mi + postgresql: + parameters: + max_connections: "1100" - name: ibm-im-mongodb-operator spec: mongoDB: @@ -449,6 +469,166 @@ const Large = ` cpu: 410m memory: 335Mi replicas: 3 +- name: ibm-im-operator-v4.3 + spec: + authentication: + authService: + resources: + limits: + cpu: 2000m + memory: 745Mi + requests: + ephemeral-storage: 256Mi + cpu: 725m + memory: 695Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 50Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 530Mi + requests: + ephemeral-storage: 256Mi + cpu: 340m + memory: 385Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 480Mi + requests: + ephemeral-storage: 256Mi + cpu: 410m + memory: 335Mi + replicas: 3 +- name: ibm-im-operator-v4.4 + spec: + authentication: + authService: + resources: + limits: + cpu: 2000m + memory: 745Mi + requests: + ephemeral-storage: 256Mi + cpu: 725m + memory: 695Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 50Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 530Mi + requests: + ephemeral-storage: 256Mi + cpu: 340m + memory: 385Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 480Mi + requests: + ephemeral-storage: 256Mi + cpu: 410m + memory: 335Mi + replicas: 3 +- name: ibm-im-operator-v4.5 + spec: + authentication: + authService: + resources: + limits: + cpu: 2000m + memory: 745Mi + requests: + ephemeral-storage: 256Mi + cpu: 725m + memory: 695Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 50Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 530Mi + requests: + ephemeral-storage: 256Mi + cpu: 340m + memory: 385Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 480Mi + requests: + ephemeral-storage: 256Mi + cpu: 410m + memory: 335Mi + replicas: 3 +- name: ibm-im-operator-v4.6 + spec: + authentication: + authService: + resources: + limits: + cpu: 2000m + memory: 745Mi + requests: + ephemeral-storage: 256Mi + cpu: 725m + memory: 695Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 50Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 530Mi + requests: + ephemeral-storage: 256Mi + cpu: 340m + memory: 385Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 480Mi + requests: + ephemeral-storage: 256Mi + cpu: 410m + memory: 335Mi + replicas: 3 - name: ibm-management-ingress-operator spec: managementIngress: @@ -583,6 +763,42 @@ const Large = ` ephemeral-storage: 256Mi cpu: 300m memory: 384Mi +- name: ibm-idp-config-ui-operator-v4.3 + spec: + commonWebUI: + replicas: 3 + resources: + limits: + cpu: 1000m + memory: 430Mi + requests: + ephemeral-storage: 256Mi + cpu: 300m + memory: 384Mi +- name: ibm-idp-config-ui-operator-v4.4 + spec: + commonWebUI: + replicas: 3 + resources: + limits: + cpu: 1000m + memory: 430Mi + requests: + ephemeral-storage: 256Mi + cpu: 300m + memory: 384Mi +- name: ibm-idp-config-ui-operator-v4.5 + spec: + commonWebUI: + replicas: 3 + resources: + limits: + cpu: 1000m + memory: 430Mi + requests: + ephemeral-storage: 256Mi + cpu: 300m + memory: 384Mi - name: ibm-platform-api-operator spec: platformApi: @@ -674,4 +890,49 @@ const Large = ` spec: apicatalogmanager: profile: large +- name: edb-keycloak + resources: + - apiVersion: postgresql.k8s.enterprisedb.io/v1 + kind: Cluster + name: keycloak-edb-cluster + data: + spec: + instances: 3 + resources: + limits: + cpu: 750m + memory: 1500Mi + requests: + cpu: 750m + memory: 1500Mi +- name: keycloak-operator + resources: + - apiVersion: k8s.keycloak.org/v2alpha1 + kind: Keycloak + name: cs-keycloak + data: + spec: + instances: 3 + resources: + limits: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 512Mi + requests: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 256Mi + unsupported: + podTemplate: + spec: + containers: + - resources: + limits: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 512Mi + requests: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 256Mi ` diff --git a/controllers/size/medium_amd64.go b/controllers/size/medium_amd64.go index 5ebf72974..3a8a5d6b0 100644 --- a/controllers/size/medium_amd64.go +++ b/controllers/size/medium_amd64.go @@ -68,6 +68,26 @@ const Medium = ` limits: cpu: 1000m memory: 350Mi +- name: common-service-postgresql + resources: + - apiVersion: postgresql.k8s.enterprisedb.io/v1 + kind: Cluster + name: common-service-db + data: + spec: + instances: 2 + resources: + limits: + cpu: 500m + memory: 1024Mi + ephemeral-storage: 512Mi + requests: + ephemeral-storage: 128Mi + cpu: 150m + memory: 384Mi + postgresql: + parameters: + max_connections: "750" - name: ibm-im-mongodb-operator-v4.0 spec: mongoDB: @@ -449,6 +469,166 @@ const Medium = ` ephemeral-storage: 256Mi cpu: 570m memory: 250Mi +- name: ibm-im-operator-v4.3 + spec: + authentication: + replicas: 2 + authService: + resources: + limits: + cpu: 1000m + memory: 1090Mi + requests: + ephemeral-storage: 256Mi + cpu: 600m + memory: 540Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 50Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 1260Mi + requests: + ephemeral-storage: 256Mi + cpu: 260m + memory: 240Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 920Mi + requests: + ephemeral-storage: 256Mi + cpu: 570m + memory: 250Mi +- name: ibm-im-operator-v4.4 + spec: + authentication: + replicas: 2 + authService: + resources: + limits: + cpu: 1000m + memory: 1090Mi + requests: + ephemeral-storage: 256Mi + cpu: 600m + memory: 540Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 50Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 1260Mi + requests: + ephemeral-storage: 256Mi + cpu: 260m + memory: 240Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 920Mi + requests: + ephemeral-storage: 256Mi + cpu: 570m + memory: 250Mi +- name: ibm-im-operator-v4.5 + spec: + authentication: + replicas: 2 + authService: + resources: + limits: + cpu: 1000m + memory: 1090Mi + requests: + ephemeral-storage: 256Mi + cpu: 600m + memory: 540Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 50Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 1260Mi + requests: + ephemeral-storage: 256Mi + cpu: 260m + memory: 240Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 920Mi + requests: + ephemeral-storage: 256Mi + cpu: 570m + memory: 250Mi +- name: ibm-im-operator-v4.6 + spec: + authentication: + replicas: 2 + authService: + resources: + limits: + cpu: 1000m + memory: 1090Mi + requests: + ephemeral-storage: 256Mi + cpu: 600m + memory: 540Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 50Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 1260Mi + requests: + ephemeral-storage: 256Mi + cpu: 260m + memory: 240Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 920Mi + requests: + ephemeral-storage: 256Mi + cpu: 570m + memory: 250Mi - name: ibm-management-ingress-operator spec: managementIngress: @@ -583,6 +763,42 @@ const Medium = ` limits: memory: 660Mi cpu: 1000m +- name: ibm-idp-config-ui-operator-v4.3 + spec: + commonWebUI: + replicas: 2 + resources: + requests: + ephemeral-storage: 256Mi + memory: 480Mi + cpu: 450m + limits: + memory: 660Mi + cpu: 1000m +- name: ibm-idp-config-ui-operator-v4.4 + spec: + commonWebUI: + replicas: 2 + resources: + requests: + ephemeral-storage: 256Mi + memory: 480Mi + cpu: 450m + limits: + memory: 660Mi + cpu: 1000m +- name: ibm-idp-config-ui-operator-v4.5 + spec: + commonWebUI: + replicas: 2 + resources: + requests: + ephemeral-storage: 256Mi + memory: 480Mi + cpu: 450m + limits: + memory: 660Mi + cpu: 1000m - name: ibm-platform-api-operator spec: platformApi: @@ -674,4 +890,49 @@ const Medium = ` spec: apicatalogmanager: profile: medium +- name: edb-keycloak + resources: + - apiVersion: postgresql.k8s.enterprisedb.io/v1 + kind: Cluster + name: keycloak-edb-cluster + data: + spec: + instances: 2 + resources: + limits: + cpu: 500m + memory: 1024Mi + requests: + cpu: 500m + memory: 1024Mi +- name: keycloak-operator + resources: + - apiVersion: k8s.keycloak.org/v2alpha1 + kind: Keycloak + name: cs-keycloak + data: + spec: + instances: 2 + resources: + limits: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 512Mi + requests: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 256Mi + unsupported: + podTemplate: + spec: + containers: + - resources: + limits: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 512Mi + requests: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 256Mi ` diff --git a/controllers/size/medium_ppc64le.go b/controllers/size/medium_ppc64le.go index 14d06b762..a5ca2095a 100644 --- a/controllers/size/medium_ppc64le.go +++ b/controllers/size/medium_ppc64le.go @@ -68,6 +68,26 @@ const Medium = ` limits: cpu: 1000m memory: 350Mi +- name: common-service-postgresql + resources: + - apiVersion: postgresql.k8s.enterprisedb.io/v1 + kind: Cluster + name: common-service-db + data: + spec: + instances: 2 + resources: + limits: + cpu: 500m + memory: 1024Mi + ephemeral-storage: 512Mi + requests: + ephemeral-storage: 128Mi + cpu: 150m + memory: 384Mi + postgresql: + parameters: + max_connections: "750" - name: ibm-im-mongodb-operator spec: mongoDB: @@ -449,6 +469,166 @@ const Medium = ` cpu: 320m memory: 250Mi replicas: 2 +- name: ibm-im-operator-v4.3 + spec: + authentication: + authService: + resources: + limits: + cpu: 2000m + memory: 1193Mi + requests: + ephemeral-storage: 256Mi + cpu: 230m + memory: 695Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 300Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 639Mi + requests: + ephemeral-storage: 256Mi + cpu: 100m + memory: 140Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 438Mi + requests: + ephemeral-storage: 256Mi + cpu: 320m + memory: 250Mi + replicas: 2 +- name: ibm-im-operator-v4.4 + spec: + authentication: + authService: + resources: + limits: + cpu: 2000m + memory: 1193Mi + requests: + ephemeral-storage: 256Mi + cpu: 230m + memory: 695Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 300Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 639Mi + requests: + ephemeral-storage: 256Mi + cpu: 100m + memory: 140Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 438Mi + requests: + ephemeral-storage: 256Mi + cpu: 320m + memory: 250Mi + replicas: 2 +- name: ibm-im-operator-v4.5 + spec: + authentication: + authService: + resources: + limits: + cpu: 2000m + memory: 1193Mi + requests: + ephemeral-storage: 256Mi + cpu: 230m + memory: 695Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 300Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 639Mi + requests: + ephemeral-storage: 256Mi + cpu: 100m + memory: 140Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 438Mi + requests: + ephemeral-storage: 256Mi + cpu: 320m + memory: 250Mi + replicas: 2 +- name: ibm-im-operator-v4.6 + spec: + authentication: + authService: + resources: + limits: + cpu: 2000m + memory: 1193Mi + requests: + ephemeral-storage: 256Mi + cpu: 230m + memory: 695Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 300Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 639Mi + requests: + ephemeral-storage: 256Mi + cpu: 100m + memory: 140Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 438Mi + requests: + ephemeral-storage: 256Mi + cpu: 320m + memory: 250Mi + replicas: 2 - name: ibm-management-ingress-operator spec: managementIngress: @@ -583,6 +763,42 @@ const Medium = ` ephemeral-storage: 256Mi cpu: 300m memory: 376Mi +- name: ibm-idp-config-ui-operator-v4.3 + spec: + commonWebUI: + replicas: 2 + resources: + limits: + cpu: 1000m + memory: 1225Mi + requests: + ephemeral-storage: 256Mi + cpu: 300m + memory: 376Mi +- name: ibm-idp-config-ui-operator-v4.4 + spec: + commonWebUI: + replicas: 2 + resources: + limits: + cpu: 1000m + memory: 1225Mi + requests: + ephemeral-storage: 256Mi + cpu: 300m + memory: 376Mi +- name: ibm-idp-config-ui-operator-v4.5 + spec: + commonWebUI: + replicas: 2 + resources: + limits: + cpu: 1000m + memory: 1225Mi + requests: + ephemeral-storage: 256Mi + cpu: 300m + memory: 376Mi - name: ibm-platform-api-operator spec: platformApi: @@ -674,4 +890,49 @@ const Medium = ` spec: apicatalogmanager: profile: medium +- name: edb-keycloak + resources: + - apiVersion: postgresql.k8s.enterprisedb.io/v1 + kind: Cluster + name: keycloak-edb-cluster + data: + spec: + instances: 2 + resources: + limits: + cpu: 500m + memory: 1024Mi + requests: + cpu: 500m + memory: 1024Mi +- name: keycloak-operator + resources: + - apiVersion: k8s.keycloak.org/v2alpha1 + kind: Keycloak + name: cs-keycloak + data: + spec: + instances: 2 + resources: + limits: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 512Mi + requests: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 256Mi + unsupported: + podTemplate: + spec: + containers: + - resources: + limits: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 512Mi + requests: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 256Mi ` diff --git a/controllers/size/medium_s390x.go b/controllers/size/medium_s390x.go index 6ecace525..474e129f4 100644 --- a/controllers/size/medium_s390x.go +++ b/controllers/size/medium_s390x.go @@ -68,6 +68,26 @@ const Medium = ` limits: cpu: 1000m memory: 350Mi +- name: common-service-postgresql + resources: + - apiVersion: postgresql.k8s.enterprisedb.io/v1 + kind: Cluster + name: common-service-db + data: + spec: + instances: 2 + resources: + limits: + cpu: 500m + memory: 1024Mi + ephemeral-storage: 512Mi + requests: + ephemeral-storage: 128Mi + cpu: 150m + memory: 384Mi + postgresql: + parameters: + max_connections: "750" - name: ibm-im-mongodb-operator spec: mongoDB: @@ -449,6 +469,166 @@ const Medium = ` cpu: 320m memory: 250Mi replicas: 2 +- name: ibm-im-operator-v4.3 + spec: + authentication: + authService: + resources: + limits: + cpu: 1000m + memory: 745Mi + requests: + ephemeral-storage: 256Mi + cpu: 230m + memory: 695Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 50Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 525Mi + requests: + ephemeral-storage: 256Mi + cpu: 100m + memory: 140Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 355Mi + requests: + ephemeral-storage: 256Mi + cpu: 320m + memory: 250Mi + replicas: 2 +- name: ibm-im-operator-v4.4 + spec: + authentication: + authService: + resources: + limits: + cpu: 1000m + memory: 745Mi + requests: + ephemeral-storage: 256Mi + cpu: 230m + memory: 695Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 50Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 525Mi + requests: + ephemeral-storage: 256Mi + cpu: 100m + memory: 140Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 355Mi + requests: + ephemeral-storage: 256Mi + cpu: 320m + memory: 250Mi + replicas: 2 +- name: ibm-im-operator-v4.5 + spec: + authentication: + authService: + resources: + limits: + cpu: 1000m + memory: 745Mi + requests: + ephemeral-storage: 256Mi + cpu: 230m + memory: 695Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 50Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 525Mi + requests: + ephemeral-storage: 256Mi + cpu: 100m + memory: 140Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 355Mi + requests: + ephemeral-storage: 256Mi + cpu: 320m + memory: 250Mi + replicas: 2 +- name: ibm-im-operator-v4.6 + spec: + authentication: + authService: + resources: + limits: + cpu: 1000m + memory: 745Mi + requests: + ephemeral-storage: 256Mi + cpu: 230m + memory: 695Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 50Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 525Mi + requests: + ephemeral-storage: 256Mi + cpu: 100m + memory: 140Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 355Mi + requests: + ephemeral-storage: 256Mi + cpu: 320m + memory: 250Mi + replicas: 2 - name: ibm-management-ingress-operator spec: managementIngress: @@ -583,6 +763,42 @@ const Medium = ` ephemeral-storage: 256Mi cpu: 300m memory: 376Mi +- name: ibm-idp-config-ui-operator-v4.3 + spec: + commonWebUI: + replicas: 2 + resources: + limits: + cpu: 1000m + memory: 430Mi + requests: + ephemeral-storage: 256Mi + cpu: 300m + memory: 376Mi +- name: ibm-idp-config-ui-operator-v4.4 + spec: + commonWebUI: + replicas: 2 + resources: + limits: + cpu: 1000m + memory: 430Mi + requests: + ephemeral-storage: 256Mi + cpu: 300m + memory: 376Mi +- name: ibm-idp-config-ui-operator-v4.5 + spec: + commonWebUI: + replicas: 2 + resources: + limits: + cpu: 1000m + memory: 430Mi + requests: + ephemeral-storage: 256Mi + cpu: 300m + memory: 376Mi - name: ibm-platform-api-operator spec: platformApi: @@ -674,4 +890,49 @@ const Medium = ` spec: apicatalogmanager: profile: medium +- name: edb-keycloak + resources: + - apiVersion: postgresql.k8s.enterprisedb.io/v1 + kind: Cluster + name: keycloak-edb-cluster + data: + spec: + instances: 2 + resources: + limits: + cpu: 500m + memory: 1024Mi + requests: + cpu: 500m + memory: 1024Mi +- name: keycloak-operator + resources: + - apiVersion: k8s.keycloak.org/v2alpha1 + kind: Keycloak + name: cs-keycloak + data: + spec: + instances: 2 + resources: + limits: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 512Mi + requests: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 256Mi + unsupported: + podTemplate: + spec: + containers: + - resources: + limits: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 512Mi + requests: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 256Mi ` diff --git a/controllers/size/small_amd64.go b/controllers/size/small_amd64.go index e7dc51252..6ebefbe14 100644 --- a/controllers/size/small_amd64.go +++ b/controllers/size/small_amd64.go @@ -68,6 +68,26 @@ const Small = ` limits: cpu: 1000m memory: 350Mi +- name: common-service-postgresql + resources: + - apiVersion: postgresql.k8s.enterprisedb.io/v1 + kind: Cluster + name: common-service-db + data: + spec: + instances: 2 + resources: + limits: + cpu: 200m + memory: 768Mi + ephemeral-storage: 512Mi + requests: + ephemeral-storage: 128Mi + cpu: 75m + memory: 256Mi + postgresql: + parameters: + max_connections: "600" - name: ibm-im-mongodb-operator spec: mongoDB: @@ -449,6 +469,166 @@ const Small = ` ephemeral-storage: 256Mi cpu: 570m memory: 250Mi +- name: ibm-im-operator-v4.3 + spec: + authentication: + replicas: 1 + authService: + resources: + limits: + cpu: 1000m + memory: 1090Mi + requests: + ephemeral-storage: 256Mi + cpu: 600m + memory: 650Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 50Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 410Mi + requests: + ephemeral-storage: 256Mi + cpu: 260m + memory: 240Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 420Mi + requests: + ephemeral-storage: 256Mi + cpu: 570m + memory: 250Mi +- name: ibm-im-operator-v4.4 + spec: + authentication: + replicas: 1 + authService: + resources: + limits: + cpu: 1000m + memory: 1090Mi + requests: + ephemeral-storage: 256Mi + cpu: 600m + memory: 650Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 50Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 410Mi + requests: + ephemeral-storage: 256Mi + cpu: 260m + memory: 240Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 420Mi + requests: + ephemeral-storage: 256Mi + cpu: 570m + memory: 250Mi +- name: ibm-im-operator-v4.5 + spec: + authentication: + replicas: 1 + authService: + resources: + limits: + cpu: 1000m + memory: 1090Mi + requests: + ephemeral-storage: 256Mi + cpu: 600m + memory: 650Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 50Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 410Mi + requests: + ephemeral-storage: 256Mi + cpu: 260m + memory: 240Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 420Mi + requests: + ephemeral-storage: 256Mi + cpu: 570m + memory: 250Mi +- name: ibm-im-operator-v4.6 + spec: + authentication: + replicas: 1 + authService: + resources: + limits: + cpu: 1000m + memory: 1090Mi + requests: + ephemeral-storage: 256Mi + cpu: 600m + memory: 650Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 50Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 410Mi + requests: + ephemeral-storage: 256Mi + cpu: 260m + memory: 240Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 420Mi + requests: + ephemeral-storage: 256Mi + cpu: 570m + memory: 250Mi - name: ibm-management-ingress-operator spec: managementIngress: @@ -583,6 +763,42 @@ const Small = ` limits: memory: 440Mi cpu: 1000m +- name: ibm-idp-config-ui-operator-v4.3 + spec: + commonWebUI: + replicas: 1 + resources: + requests: + ephemeral-storage: 256Mi + memory: 256Mi + cpu: 130m + limits: + memory: 440Mi + cpu: 1000m +- name: ibm-idp-config-ui-operator-v4.4 + spec: + commonWebUI: + replicas: 1 + resources: + requests: + ephemeral-storage: 256Mi + memory: 256Mi + cpu: 130m + limits: + memory: 440Mi + cpu: 1000m +- name: ibm-idp-config-ui-operator-v4.5 + spec: + commonWebUI: + replicas: 1 + resources: + requests: + ephemeral-storage: 256Mi + memory: 256Mi + cpu: 130m + limits: + memory: 440Mi + cpu: 1000m - name: ibm-platform-api-operator spec: platformApi: @@ -674,4 +890,49 @@ const Small = ` spec: apicatalogmanager: profile: small +- name: edb-keycloak + resources: + - apiVersion: postgresql.k8s.enterprisedb.io/v1 + kind: Cluster + name: keycloak-edb-cluster + data: + spec: + instances: 2 + resources: + limits: + cpu: 200m + memory: 768Mi + requests: + cpu: 200m + memory: 768Mi +- name: keycloak-operator + resources: + - apiVersion: k8s.keycloak.org/v2alpha1 + kind: Keycloak + name: cs-keycloak + data: + spec: + instances: 2 + resources: + limits: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 512Mi + requests: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 256Mi + unsupported: + podTemplate: + spec: + containers: + - resources: + limits: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 512Mi + requests: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 256Mi ` diff --git a/controllers/size/small_ppc64le.go b/controllers/size/small_ppc64le.go index f5daaa5a6..26117483a 100644 --- a/controllers/size/small_ppc64le.go +++ b/controllers/size/small_ppc64le.go @@ -68,6 +68,26 @@ const Small = ` limits: cpu: 1000m memory: 350Mi +- name: common-service-postgresql + resources: + - apiVersion: postgresql.k8s.enterprisedb.io/v1 + kind: Cluster + name: common-service-db + data: + spec: + instances: 2 + resources: + limits: + cpu: 200m + memory: 512Mi + ephemeral-storage: 512Mi + requests: + ephemeral-storage: 128Mi + cpu: 75m + memory: 256Mi + postgresql: + parameters: + max_connections: "600" - name: ibm-im-mongodb-operator spec: mongoDB: @@ -449,6 +469,166 @@ const Small = ` ephemeral-storage: 256Mi cpu: 80m memory: 130Mi +- name: ibm-im-operator-v4.3 + spec: + authentication: + replicas: 1 + authService: + resources: + limits: + cpu: 2000m + memory: 950Mi + requests: + ephemeral-storage: 256Mi + cpu: 140m + memory: 525Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 300Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 350Mi + requests: + ephemeral-storage: 256Mi + cpu: 50m + memory: 120Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 250Mi + requests: + ephemeral-storage: 256Mi + cpu: 80m + memory: 130Mi +- name: ibm-im-operator-v4.4 + spec: + authentication: + replicas: 1 + authService: + resources: + limits: + cpu: 2000m + memory: 950Mi + requests: + ephemeral-storage: 256Mi + cpu: 140m + memory: 525Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 300Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 350Mi + requests: + ephemeral-storage: 256Mi + cpu: 50m + memory: 120Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 250Mi + requests: + ephemeral-storage: 256Mi + cpu: 80m + memory: 130Mi +- name: ibm-im-operator-v4.5 + spec: + authentication: + replicas: 1 + authService: + resources: + limits: + cpu: 2000m + memory: 950Mi + requests: + ephemeral-storage: 256Mi + cpu: 140m + memory: 525Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 300Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 350Mi + requests: + ephemeral-storage: 256Mi + cpu: 50m + memory: 120Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 250Mi + requests: + ephemeral-storage: 256Mi + cpu: 80m + memory: 130Mi +- name: ibm-im-operator-v4.6 + spec: + authentication: + replicas: 1 + authService: + resources: + limits: + cpu: 2000m + memory: 950Mi + requests: + ephemeral-storage: 256Mi + cpu: 140m + memory: 525Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 300Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 350Mi + requests: + ephemeral-storage: 256Mi + cpu: 50m + memory: 120Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 250Mi + requests: + ephemeral-storage: 256Mi + cpu: 80m + memory: 130Mi - name: ibm-management-ingress-operator spec: managementIngress: @@ -583,6 +763,42 @@ const Small = ` limits: memory: 800Mi cpu: 1000m +- name: ibm-idp-config-ui-operator-v4.3 + spec: + commonWebUI: + replicas: 1 + resources: + requests: + ephemeral-storage: 256Mi + memory: 256Mi + cpu: 150m + limits: + memory: 800Mi + cpu: 1000m +- name: ibm-idp-config-ui-operator-v4.4 + spec: + commonWebUI: + replicas: 1 + resources: + requests: + ephemeral-storage: 256Mi + memory: 256Mi + cpu: 150m + limits: + memory: 800Mi + cpu: 1000m +- name: ibm-idp-config-ui-operator-v4.5 + spec: + commonWebUI: + replicas: 1 + resources: + requests: + ephemeral-storage: 256Mi + memory: 256Mi + cpu: 150m + limits: + memory: 800Mi + cpu: 1000m - name: ibm-platform-api-operator spec: platformApi: @@ -674,4 +890,49 @@ const Small = ` spec: apicatalogmanager: profile: small +- name: edb-keycloak + resources: + - apiVersion: postgresql.k8s.enterprisedb.io/v1 + kind: Cluster + name: keycloak-edb-cluster + data: + spec: + instances: 2 + resources: + limits: + cpu: 200m + memory: 768Mi + requests: + cpu: 200m + memory: 768Mi +- name: keycloak-operator + resources: + - apiVersion: k8s.keycloak.org/v2alpha1 + kind: Keycloak + name: cs-keycloak + data: + spec: + instances: 2 + resources: + limits: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 512Mi + requests: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 256Mi + unsupported: + podTemplate: + spec: + containers: + - resources: + limits: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 512Mi + requests: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 256Mi ` diff --git a/controllers/size/small_s390x.go b/controllers/size/small_s390x.go index ae8478e26..f33796722 100644 --- a/controllers/size/small_s390x.go +++ b/controllers/size/small_s390x.go @@ -68,6 +68,26 @@ const Small = ` limits: cpu: 1000m memory: 350Mi +- name: common-service-postgresql + resources: + - apiVersion: postgresql.k8s.enterprisedb.io/v1 + kind: Cluster + name: common-service-db + data: + spec: + instances: 2 + resources: + limits: + cpu: 200m + memory: 512Mi + ephemeral-storage: 512Mi + requests: + ephemeral-storage: 128Mi + cpu: 75m + memory: 256Mi + postgresql: + parameters: + max_connections: "600" - name: ibm-im-mongodb-operator spec: mongoDB: @@ -449,6 +469,166 @@ const Small = ` ephemeral-storage: 256Mi cpu: 80m memory: 130Mi +- name: ibm-im-operator-v4.3 + spec: + authentication: + replicas: 1 + authService: + resources: + limits: + cpu: 1000m + memory: 650Mi + requests: + ephemeral-storage: 256Mi + cpu: 140m + memory: 525Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 50Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 220Mi + requests: + ephemeral-storage: 256Mi + cpu: 50m + memory: 120Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 230Mi + requests: + ephemeral-storage: 256Mi + cpu: 80m + memory: 130Mi +- name: ibm-im-operator-v4.4 + spec: + authentication: + replicas: 1 + authService: + resources: + limits: + cpu: 1000m + memory: 650Mi + requests: + ephemeral-storage: 256Mi + cpu: 140m + memory: 525Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 50Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 220Mi + requests: + ephemeral-storage: 256Mi + cpu: 50m + memory: 120Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 230Mi + requests: + ephemeral-storage: 256Mi + cpu: 80m + memory: 130Mi +- name: ibm-im-operator-v4.5 + spec: + authentication: + replicas: 1 + authService: + resources: + limits: + cpu: 1000m + memory: 650Mi + requests: + ephemeral-storage: 256Mi + cpu: 140m + memory: 525Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 50Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 220Mi + requests: + ephemeral-storage: 256Mi + cpu: 50m + memory: 120Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 230Mi + requests: + ephemeral-storage: 256Mi + cpu: 80m + memory: 130Mi +- name: ibm-im-operator-v4.6 + spec: + authentication: + replicas: 1 + authService: + resources: + limits: + cpu: 1000m + memory: 650Mi + requests: + ephemeral-storage: 256Mi + cpu: 140m + memory: 525Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 50Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 220Mi + requests: + ephemeral-storage: 256Mi + cpu: 50m + memory: 120Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 230Mi + requests: + ephemeral-storage: 256Mi + cpu: 80m + memory: 130Mi - name: ibm-management-ingress-operator spec: managementIngress: @@ -583,6 +763,42 @@ const Small = ` limits: memory: 440Mi cpu: 1000m +- name: ibm-idp-config-ui-operator-v4.3 + spec: + commonWebUI: + replicas: 1 + resources: + requests: + ephemeral-storage: 256Mi + memory: 256Mi + cpu: 150m + limits: + memory: 440Mi + cpu: 1000m +- name: ibm-idp-config-ui-operator-v4.4 + spec: + commonWebUI: + replicas: 1 + resources: + requests: + ephemeral-storage: 256Mi + memory: 256Mi + cpu: 150m + limits: + memory: 440Mi + cpu: 1000m +- name: ibm-idp-config-ui-operator-v4.5 + spec: + commonWebUI: + replicas: 1 + resources: + requests: + ephemeral-storage: 256Mi + memory: 256Mi + cpu: 150m + limits: + memory: 440Mi + cpu: 1000m - name: ibm-platform-api-operator spec: platformApi: @@ -674,4 +890,49 @@ const Small = ` spec: apicatalogmanager: profile: small +- name: edb-keycloak + resources: + - apiVersion: postgresql.k8s.enterprisedb.io/v1 + kind: Cluster + name: keycloak-edb-cluster + data: + spec: + instances: 2 + resources: + limits: + cpu: 200m + memory: 768Mi + requests: + cpu: 200m + memory: 768Mi +- name: keycloak-operator + resources: + - apiVersion: k8s.keycloak.org/v2alpha1 + kind: Keycloak + name: cs-keycloak + data: + spec: + instances: 2 + resources: + limits: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 512Mi + requests: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 256Mi + unsupported: + podTemplate: + spec: + containers: + - resources: + limits: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 512Mi + requests: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 256Mi ` diff --git a/controllers/size/starterset_amd64.go b/controllers/size/starterset_amd64.go index 7b8333136..1b5bda6e1 100644 --- a/controllers/size/starterset_amd64.go +++ b/controllers/size/starterset_amd64.go @@ -68,6 +68,26 @@ const StarterSet = ` limits: cpu: 1000m memory: 350Mi +- name: common-service-postgresql + resources: + - apiVersion: postgresql.k8s.enterprisedb.io/v1 + kind: Cluster + name: common-service-db + data: + spec: + instances: 1 + resources: + limits: + cpu: 200m + memory: 512Mi + ephemeral-storage: 512Mi + requests: + ephemeral-storage: 128Mi + cpu: 75m + memory: 256Mi + postgresql: + parameters: + max_connections: "400" - name: ibm-im-mongodb-operator spec: mongoDB: @@ -449,6 +469,166 @@ const StarterSet = ` ephemeral-storage: 256Mi cpu: 570m memory: 250Mi +- name: ibm-im-operator-v4.3 + spec: + authentication: + replicas: 1 + authService: + resources: + limits: + cpu: 1000m + memory: 1090Mi + requests: + ephemeral-storage: 256Mi + cpu: 600m + memory: 650Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 50Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 410Mi + requests: + ephemeral-storage: 256Mi + cpu: 260m + memory: 240Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 420Mi + requests: + ephemeral-storage: 256Mi + cpu: 570m + memory: 250Mi +- name: ibm-im-operator-v4.4 + spec: + authentication: + replicas: 1 + authService: + resources: + limits: + cpu: 1000m + memory: 1090Mi + requests: + ephemeral-storage: 256Mi + cpu: 600m + memory: 650Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 50Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 410Mi + requests: + ephemeral-storage: 256Mi + cpu: 260m + memory: 240Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 420Mi + requests: + ephemeral-storage: 256Mi + cpu: 570m + memory: 250Mi +- name: ibm-im-operator-v4.5 + spec: + authentication: + replicas: 1 + authService: + resources: + limits: + cpu: 1000m + memory: 1090Mi + requests: + ephemeral-storage: 256Mi + cpu: 600m + memory: 650Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 50Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 410Mi + requests: + ephemeral-storage: 256Mi + cpu: 260m + memory: 240Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 420Mi + requests: + ephemeral-storage: 256Mi + cpu: 570m + memory: 250Mi +- name: ibm-im-operator-v4.6 + spec: + authentication: + replicas: 1 + authService: + resources: + limits: + cpu: 1000m + memory: 1090Mi + requests: + ephemeral-storage: 256Mi + cpu: 600m + memory: 650Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 50Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 410Mi + requests: + ephemeral-storage: 256Mi + cpu: 260m + memory: 240Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 420Mi + requests: + ephemeral-storage: 256Mi + cpu: 570m + memory: 250Mi - name: ibm-management-ingress-operator spec: managementIngress: @@ -583,6 +763,42 @@ const StarterSet = ` limits: memory: 440Mi cpu: 1000m +- name: ibm-idp-config-ui-operator-v4.3 + spec: + commonWebUI: + replicas: 1 + resources: + requests: + ephemeral-storage: 256Mi + memory: 256Mi + cpu: 130m + limits: + memory: 440Mi + cpu: 1000m +- name: ibm-idp-config-ui-operator-v4.4 + spec: + commonWebUI: + replicas: 1 + resources: + requests: + ephemeral-storage: 256Mi + memory: 256Mi + cpu: 130m + limits: + memory: 440Mi + cpu: 1000m +- name: ibm-idp-config-ui-operator-v4.5 + spec: + commonWebUI: + replicas: 1 + resources: + requests: + ephemeral-storage: 256Mi + memory: 256Mi + cpu: 130m + limits: + memory: 440Mi + cpu: 1000m - name: ibm-platform-api-operator spec: platformApi: @@ -674,4 +890,49 @@ const StarterSet = ` spec: apicatalogmanager: profile: small +- name: edb-keycloak + resources: + - apiVersion: postgresql.k8s.enterprisedb.io/v1 + kind: Cluster + name: keycloak-edb-cluster + data: + spec: + instances: 2 + resources: + limits: + cpu: 200m + memory: 512Mi + requests: + cpu: 200m + memory: 512Mi +- name: keycloak-operator + resources: + - apiVersion: k8s.keycloak.org/v2alpha1 + kind: Keycloak + name: cs-keycloak + data: + spec: + instances: 1 + resources: + limits: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 512Mi + requests: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 256Mi + unsupported: + podTemplate: + spec: + containers: + - resources: + limits: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 512Mi + requests: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 256Mi ` diff --git a/controllers/size/starterset_ppc64le.go b/controllers/size/starterset_ppc64le.go index 6feb4a2f1..4434232e5 100644 --- a/controllers/size/starterset_ppc64le.go +++ b/controllers/size/starterset_ppc64le.go @@ -68,6 +68,26 @@ const StarterSet = ` limits: cpu: 1000m memory: 350Mi +- name: common-service-postgresql + resources: + - apiVersion: postgresql.k8s.enterprisedb.io/v1 + kind: Cluster + name: common-service-db + data: + spec: + instances: 1 + resources: + limits: + cpu: 200m + memory: 512Mi + ephemeral-storage: 512Mi + requests: + ephemeral-storage: 128Mi + cpu: 75m + memory: 256Mi + postgresql: + parameters: + max_connections: "400" - name: ibm-im-mongodb-operator spec: mongoDB: @@ -449,6 +469,166 @@ const StarterSet = ` ephemeral-storage: 256Mi cpu: 80m memory: 130Mi +- name: ibm-im-operator-v4.3 + spec: + authentication: + replicas: 1 + authService: + resources: + limits: + cpu: 2000m + memory: 950Mi + requests: + ephemeral-storage: 256Mi + cpu: 140m + memory: 525Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 300Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 350Mi + requests: + ephemeral-storage: 256Mi + cpu: 50m + memory: 120Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 250Mi + requests: + ephemeral-storage: 256Mi + cpu: 80m + memory: 130Mi +- name: ibm-im-operator-v4.4 + spec: + authentication: + replicas: 1 + authService: + resources: + limits: + cpu: 2000m + memory: 950Mi + requests: + ephemeral-storage: 256Mi + cpu: 140m + memory: 525Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 300Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 350Mi + requests: + ephemeral-storage: 256Mi + cpu: 50m + memory: 120Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 250Mi + requests: + ephemeral-storage: 256Mi + cpu: 80m + memory: 130Mi +- name: ibm-im-operator-v4.5 + spec: + authentication: + replicas: 1 + authService: + resources: + limits: + cpu: 2000m + memory: 950Mi + requests: + ephemeral-storage: 256Mi + cpu: 140m + memory: 525Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 300Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 350Mi + requests: + ephemeral-storage: 256Mi + cpu: 50m + memory: 120Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 250Mi + requests: + ephemeral-storage: 256Mi + cpu: 80m + memory: 130Mi +- name: ibm-im-operator-v4.6 + spec: + authentication: + replicas: 1 + authService: + resources: + limits: + cpu: 2000m + memory: 950Mi + requests: + ephemeral-storage: 256Mi + cpu: 140m + memory: 525Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 300Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 350Mi + requests: + ephemeral-storage: 256Mi + cpu: 50m + memory: 120Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 250Mi + requests: + ephemeral-storage: 256Mi + cpu: 80m + memory: 130Mi - name: ibm-management-ingress-operator spec: managementIngress: @@ -583,6 +763,42 @@ const StarterSet = ` limits: memory: 800Mi cpu: 1000m +- name: ibm-idp-config-ui-operator-v4.3 + spec: + commonWebUI: + replicas: 1 + resources: + requests: + ephemeral-storage: 256Mi + memory: 256Mi + cpu: 150m + limits: + memory: 800Mi + cpu: 1000m +- name: ibm-idp-config-ui-operator-v4.4 + spec: + commonWebUI: + replicas: 1 + resources: + requests: + ephemeral-storage: 256Mi + memory: 256Mi + cpu: 150m + limits: + memory: 800Mi + cpu: 1000m +- name: ibm-idp-config-ui-operator-v4.5 + spec: + commonWebUI: + replicas: 1 + resources: + requests: + ephemeral-storage: 256Mi + memory: 256Mi + cpu: 150m + limits: + memory: 800Mi + cpu: 1000m - name: ibm-platform-api-operator spec: platformApi: @@ -674,4 +890,49 @@ const StarterSet = ` spec: apicatalogmanager: profile: small +- name: edb-keycloak + resources: + - apiVersion: postgresql.k8s.enterprisedb.io/v1 + kind: Cluster + name: keycloak-edb-cluster + data: + spec: + instances: 2 + resources: + limits: + cpu: 200m + memory: 512Mi + requests: + cpu: 200m + memory: 512Mi +- name: keycloak-operator + resources: + - apiVersion: k8s.keycloak.org/v2alpha1 + kind: Keycloak + name: cs-keycloak + data: + spec: + instances: 1 + resources: + limits: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 512Mi + requests: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 256Mi + unsupported: + podTemplate: + spec: + containers: + - resources: + limits: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 512Mi + requests: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 256Mi ` diff --git a/controllers/size/starterset_s390x.go b/controllers/size/starterset_s390x.go index b15fb49cf..de4b5eeac 100644 --- a/controllers/size/starterset_s390x.go +++ b/controllers/size/starterset_s390x.go @@ -70,6 +70,26 @@ const StarterSet = ` limits: cpu: 1000m memory: 350Mi +- name: common-service-postgresql + resources: + - apiVersion: postgresql.k8s.enterprisedb.io/v1 + kind: Cluster + name: common-service-db + data: + spec: + instances: 1 + resources: + limits: + cpu: 200m + memory: 512Mi + ephemeral-storage: 512Mi + requests: + ephemeral-storage: 128Mi + cpu: 75m + memory: 256Mi + postgresql: + parameters: + max_connections: "400" - name: ibm-im-mongodb-operator spec: mongoDB: @@ -451,6 +471,166 @@ const StarterSet = ` ephemeral-storage: 256Mi cpu: 80m memory: 130Mi +- name: ibm-im-operator-v4.3 + spec: + authentication: + replicas: 1 + authService: + resources: + limits: + cpu: 1000m + memory: 650Mi + requests: + ephemeral-storage: 256Mi + cpu: 140m + memory: 525Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 50Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 220Mi + requests: + ephemeral-storage: 256Mi + cpu: 50m + memory: 120Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 230Mi + requests: + ephemeral-storage: 256Mi + cpu: 80m + memory: 130Mi +- name: ibm-im-operator-v4.4 + spec: + authentication: + replicas: 1 + authService: + resources: + limits: + cpu: 1000m + memory: 650Mi + requests: + ephemeral-storage: 256Mi + cpu: 140m + memory: 525Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 50Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 220Mi + requests: + ephemeral-storage: 256Mi + cpu: 50m + memory: 120Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 230Mi + requests: + ephemeral-storage: 256Mi + cpu: 80m + memory: 130Mi +- name: ibm-im-operator-v4.5 + spec: + authentication: + replicas: 1 + authService: + resources: + limits: + cpu: 1000m + memory: 650Mi + requests: + ephemeral-storage: 256Mi + cpu: 140m + memory: 525Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 50Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 220Mi + requests: + ephemeral-storage: 256Mi + cpu: 50m + memory: 120Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 230Mi + requests: + ephemeral-storage: 256Mi + cpu: 80m + memory: 130Mi +- name: ibm-im-operator-v4.6 + spec: + authentication: + replicas: 1 + authService: + resources: + limits: + cpu: 1000m + memory: 650Mi + requests: + ephemeral-storage: 256Mi + cpu: 140m + memory: 525Mi + clientRegistration: + resources: + limits: + cpu: 1000m + memory: 50Mi + requests: + ephemeral-storage: 256Mi + cpu: 20m + memory: 50Mi + identityManager: + resources: + limits: + cpu: 1000m + memory: 220Mi + requests: + ephemeral-storage: 256Mi + cpu: 50m + memory: 120Mi + identityProvider: + resources: + limits: + cpu: 1000m + memory: 230Mi + requests: + ephemeral-storage: 256Mi + cpu: 80m + memory: 130Mi - name: ibm-management-ingress-operator spec: managementIngress: @@ -585,6 +765,42 @@ const StarterSet = ` limits: memory: 440Mi cpu: 1000m +- name: ibm-idp-config-ui-operator-v4.3 + spec: + commonWebUI: + replicas: 1 + resources: + requests: + ephemeral-storage: 256Mi + memory: 256Mi + cpu: 150m + limits: + memory: 440Mi + cpu: 1000m +- name: ibm-idp-config-ui-operator-v4.4 + spec: + commonWebUI: + replicas: 1 + resources: + requests: + ephemeral-storage: 256Mi + memory: 256Mi + cpu: 150m + limits: + memory: 440Mi + cpu: 1000m +- name: ibm-idp-config-ui-operator-v4.5 + spec: + commonWebUI: + replicas: 1 + resources: + requests: + ephemeral-storage: 256Mi + memory: 256Mi + cpu: 150m + limits: + memory: 440Mi + cpu: 1000m - name: ibm-platform-api-operator spec: platformApi: @@ -676,4 +892,49 @@ const StarterSet = ` spec: apicatalogmanager: profile: small +- name: edb-keycloak + resources: + - apiVersion: postgresql.k8s.enterprisedb.io/v1 + kind: Cluster + name: keycloak-edb-cluster + data: + spec: + instances: 2 + resources: + limits: + cpu: 200m + memory: 512Mi + requests: + cpu: 200m + memory: 512Mi +- name: keycloak-operator + resources: + - apiVersion: k8s.keycloak.org/v2alpha1 + kind: Keycloak + name: cs-keycloak + data: + spec: + instances: 1 + resources: + limits: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 512Mi + requests: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 256Mi + unsupported: + podTemplate: + spec: + containers: + - resources: + limits: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 512Mi + requests: + cpu: 1000m + memory: 1Gi + ephemeral-storage: 256Mi ` diff --git a/controllers/suite_test.go b/controllers/suite_test.go index 4a862b983..e0047efaa 100644 --- a/controllers/suite_test.go +++ b/controllers/suite_test.go @@ -34,10 +34,10 @@ import ( logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/log/zap" - apiv3 "github.com/IBM/ibm-common-service-operator/api/v3" - "github.com/IBM/ibm-common-service-operator/controllers/bootstrap" - "github.com/IBM/ibm-common-service-operator/controllers/constant" - "github.com/IBM/ibm-common-service-operator/controllers/deploy" + apiv3 "github.com/IBM/ibm-common-service-operator/v4/api/v3" + "github.com/IBM/ibm-common-service-operator/v4/controllers/bootstrap" + "github.com/IBM/ibm-common-service-operator/v4/controllers/constant" + "github.com/IBM/ibm-common-service-operator/v4/controllers/deploy" // +kubebuilder:scaffold:imports ) diff --git a/controllers/webhooks/commonservice/validatingwebhook.go b/controllers/webhooks/commonservice/validatingwebhook.go index 107b0bd3f..e15148b5f 100644 --- a/controllers/webhooks/commonservice/validatingwebhook.go +++ b/controllers/webhooks/commonservice/validatingwebhook.go @@ -14,7 +14,7 @@ // limitations under the License. // -package operandrequest +package commonservice import ( "context" @@ -22,24 +22,23 @@ import ( "net/http" "strings" - // certmanagerv1alpha1 "github.com/ibm/ibm-cert-manager-operator/apis/certmanager/v1alpha1" - - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/api/resource" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/klog" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/webhook" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" - operatorv3 "github.com/IBM/ibm-common-service-operator/api/v3" - util "github.com/IBM/ibm-common-service-operator/controllers/common" - "github.com/IBM/ibm-common-service-operator/controllers/constant" + operatorv3 "github.com/IBM/ibm-common-service-operator/v4/api/v3" + controller "github.com/IBM/ibm-common-service-operator/v4/controllers" + util "github.com/IBM/ibm-common-service-operator/v4/controllers/common" + "github.com/IBM/ibm-common-service-operator/v4/controllers/constant" ) // +kubebuilder:webhook:path=/validate-operator-ibm-com-v3-commonservice,mutating=false,failurePolicy=fail,sideEffects=None,groups=operator.ibm.com,resources=commonservices,verbs=create;update,versions=v3,name=vcommonservice.kb.io,admissionReviewVersions=v1 -// CommonServiceDefaulter points to correct ServiceNamespace +// CommonServiceDefaulter points to correct ServicesNamespace type Defaulter struct { Reader client.Reader Client client.Client @@ -51,9 +50,12 @@ type Defaulter struct { func (r *Defaulter) Handle(ctx context.Context, req admission.Request) admission.Response { klog.Infof("Webhook is invoked by Commonservice %s/%s", req.AdmissionRequest.Namespace, req.AdmissionRequest.Name) + // If operator is not in the operatorNamespace, it is dormant if r.IsDormant { return admission.Allowed("") } + + // Initialize the context for the tenant topology serviceNs := util.GetServicesNamespace(r.Reader) operatorNs, operatorNsErr := util.GetOperatorNamespace() if operatorNsErr != nil { @@ -66,13 +68,21 @@ func (r *Defaulter) Handle(ctx context.Context, req admission.Request) admission return admission.Errored(http.StatusBadRequest, err) } + // handle the request from CommonService cs := &operatorv3.CommonService{} + csUnstrcuted := &unstructured.Unstructured{} err := r.decoder.Decode(req, cs) if err != nil { return admission.Errored(http.StatusBadRequest, err) } + // Convert the request to unstructured + err = r.decoder.Decode(req, csUnstrcuted) + if err != nil { + return admission.Errored(http.StatusBadRequest, err) + } + // if it is master CommonService CR, check operator and services namespaces if req.AdmissionRequest.Name == constant.MasterCR && req.AdmissionRequest.Namespace == operatorNs { klog.Infof("Start to validate master CommonService CR") @@ -113,7 +123,6 @@ func (r *Defaulter) Handle(ctx context.Context, req admission.Request) admission } // check CatalogName - catalogName := cs.Spec.CatalogName deniedCatalog := r.CheckConfig(string(catalogName), catalogSourceName) if deniedCatalog { @@ -128,6 +137,12 @@ func (r *Defaulter) Handle(ctx context.Context, req admission.Request) admission } } + // check HugePageSetting + deniedHugePage, err := r.HugePageSettingDenied(csUnstrcuted) + if err != nil || deniedHugePage { + return admission.Denied(fmt.Sprintf("HugePageSetting is invalid: %v", err)) + } + // admission.PatchResponse generates a Response containing patches. return admission.Allowed("") } @@ -138,21 +153,7 @@ func (r *Defaulter) CheckNamespace(name string) (bool, error) { if name == "" { return false, nil } - // in cluster scope - if len(watchNamespaces) == 0 { - ctx := context.Background() - ns := &corev1.Namespace{} - nsKey := types.NamespacedName{ - Name: name, - } - // check if this namespace exist - if err := r.Client.Get(ctx, nsKey, ns); err != nil { - klog.Errorf("Failed to get namespace %v: %v", name, err) - return true, err - - } - // if it is not cluster scope - } else if len(watchNamespaces) != 0 && !util.Contains(strings.Split(watchNamespaces, ","), name) { + if len(watchNamespaces) != 0 && !util.Contains(strings.Split(watchNamespaces, ","), name) { denied = true } return denied, nil @@ -165,6 +166,32 @@ func (r *Defaulter) CheckConfig(config, parameter string) bool { return config != parameter } +func (r *Defaulter) HugePageSettingDenied(cs *unstructured.Unstructured) (bool, error) { + if hugespages := cs.Object["spec"].(map[string]interface{})["hugepages"]; hugespages != nil { + if enable := hugespages.(map[string]interface{})["enable"]; enable != nil && enable.(bool) { + hugePagesStruct, err := controller.UnmarshalHugePages(hugespages) + if err != nil { + return true, fmt.Errorf("failed to unmarshal hugepages: %v", err) + } + + for size, allocation := range hugePagesStruct.HugePagesSizes { + // check if size is in the format of `hugepages-` + sizeSplit := strings.Split(size, "-") + if len(sizeSplit) != 2 || sizeSplit[0] != "hugepages" { + return true, fmt.Errorf("invalid hugepages size on prefix: %s, please specify in the format of `hugepages-`", size) + } else if _, err := resource.ParseQuantity(sizeSplit[1]); err != nil { + return true, fmt.Errorf("invalid hugepages size on Quantity: %s, please specify in the format of `hugepages-`", size) + } + if _, err := resource.ParseQuantity(allocation); err != nil && allocation != "" { + return true, fmt.Errorf("invalid hugepages allocation: %s, please specify in the format of `hugepages-: `", allocation) + } + } + } + } + + return false, nil +} + func (r *Defaulter) InjectDecoder(decoder *admission.Decoder) error { r.decoder = decoder return nil diff --git a/controllers/webhooks/commonservice/validatingwebhook_test.go b/controllers/webhooks/commonservice/validatingwebhook_test.go new file mode 100644 index 000000000..3d4d0d5dc --- /dev/null +++ b/controllers/webhooks/commonservice/validatingwebhook_test.go @@ -0,0 +1,76 @@ +// +// Copyright 2022 IBM Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package commonservice + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" +) + +func TestHugePageSettingDenied(t *testing.T) { + + r := &Defaulter{} + cs := &unstructured.Unstructured{ + Object: map[string]interface{}{ + "spec": map[string]interface{}{ + "hugepages": map[string]interface{}{ + "enable": true, + }, + }, + }, + } + + // Test case: Valid hugepages sizes and allocations + cs.Object["spec"].(map[string]interface{})["hugepages"].(map[string]interface{})["hugepages-1Gi"] = "2Gi" + cs.Object["spec"].(map[string]interface{})["hugepages"].(map[string]interface{})["hugepages-2Mi"] = "4Mi" + isDenied, err := r.HugePageSettingDenied(cs) + assert.False(t, isDenied) + assert.Nil(t, err) + + // Test case: Invalid hugepages size format + cs.Object["spec"].(map[string]interface{})["hugepages"].(map[string]interface{})["invalid-1Gi"] = "2Gi" + isDenied, err = r.HugePageSettingDenied(cs) + assert.True(t, isDenied) + assert.Contains(t, err.Error(), "invalid hugepages size on prefix") + // Delete invalid size + delete(cs.Object["spec"].(map[string]interface{})["hugepages"].(map[string]interface{}), "invalid-1Gi") + + // Test case: Invalid hugepages size quantity + cs.Object["spec"].(map[string]interface{})["hugepages"].(map[string]interface{})["hugepages-invalid"] = "invalid-quantity" + isDenied, err = r.HugePageSettingDenied(cs) + assert.True(t, isDenied) + assert.Contains(t, err.Error(), "invalid hugepages size on Quantity") + // Delete invalid quantity + delete(cs.Object["spec"].(map[string]interface{})["hugepages"].(map[string]interface{}), "hugepages-invalid") + + // Test case: Invalid hugepages allocation format + cs.Object["spec"].(map[string]interface{})["hugepages"].(map[string]interface{})["hugepages-1Gi"] = "2Gi" + cs.Object["spec"].(map[string]interface{})["hugepages"].(map[string]interface{})["hugepages-2Mi"] = "invalid-allocation" + isDenied, err = r.HugePageSettingDenied(cs) + assert.True(t, isDenied) + assert.Contains(t, err.Error(), "invalid hugepages allocation") + // Delete invalid allocation + delete(cs.Object["spec"].(map[string]interface{})["hugepages"].(map[string]interface{}), "hugepages-2Mi") + + // Test case: No hugepages enabled + cs.Object["spec"].(map[string]interface{})["hugepages"].(map[string]interface{})["enable"] = false + isDenied, err = r.HugePageSettingDenied(cs) + assert.False(t, isDenied) + assert.Nil(t, err) +} diff --git a/controllers/webhooks/operandrequest/mutatingwebhook.go b/controllers/webhooks/operandrequest/mutatingwebhook.go index 1a8240d0f..19e260e3b 100644 --- a/controllers/webhooks/operandrequest/mutatingwebhook.go +++ b/controllers/webhooks/operandrequest/mutatingwebhook.go @@ -22,8 +22,6 @@ import ( "net/http" "strings" - // certmanagerv1alpha1 "github.com/ibm/ibm-cert-manager-operator/apis/certmanager/v1alpha1" - corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/types" @@ -33,8 +31,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/webhook" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" - util "github.com/IBM/ibm-common-service-operator/controllers/common" - odlm "github.com/IBM/operand-deployment-lifecycle-manager/api/v1alpha1" + util "github.com/IBM/ibm-common-service-operator/v4/controllers/common" + odlm "github.com/IBM/operand-deployment-lifecycle-manager/v4/api/v1alpha1" ) // +kubebuilder:webhook:path=/mutate-operator-ibm-com-v1alpha1-operandrequest,mutating=true,failurePolicy=ignore,sideEffects=None,groups=operator.ibm.com,resources=operandrequests,verbs=create;update,versions=v1alpha1,name=moperandrequest.kb.io,admissionReviewVersions=v1 diff --git a/docs/cloudpak-integration.md b/docs/cloudpak-integration.md index 3e6da1ec2..73fb1935b 100644 --- a/docs/cloudpak-integration.md +++ b/docs/cloudpak-integration.md @@ -157,6 +157,18 @@ spec: - name: ibm-im-operator-v4.2 spec: authentication: {} + - name: ibm-im-operator-v4.3 + spec: + authentication: {} + - name: ibm-im-operator-v4.4 + spec: + authentication: {} + - name: ibm-im-operator-v4.5 + spec: + authentication: {} + - name: ibm-im-operator-v4.6 + spec: + authentication: {} - name: ibm-healthcheck-operator spec: healthService: {} @@ -180,6 +192,21 @@ spec: commonWebUI: {} legacyHeader: {} navconfiguration: {} + - name: ibm-idp-config-ui-operator-v4.3 + spec: + commonWebUI: {} + legacyHeader: {} + navconfiguration: {} + - name: ibm-idp-config-ui-operator-v4.4 + spec: + commonWebUI: {} + legacyHeader: {} + navconfiguration: {} + - name: ibm-idp-config-ui-operator-v4.5 + spec: + commonWebUI: {} + legacyHeader: {} + navconfiguration: {} - name: ibm-idp-config-ui-operator spec: commonWebUI: {} diff --git a/docs/install.md b/docs/install.md index 34f8ec781..5c7b76039 100644 --- a/docs/install.md +++ b/docs/install.md @@ -136,7 +136,7 @@ So far, the IBM Common Service Operator and ODLM operator installation is comple ### Accept License -Accepting the license - URL: https://ibm.biz/integration-licenses +Accepting the license - URL: https://ibm.biz/icpfs39license ```yaml apiVersion: operator.ibm.com/v3 diff --git a/go.mod b/go.mod index 4d89becdf..844ec13ba 100644 --- a/go.mod +++ b/go.mod @@ -1,87 +1,101 @@ -module github.com/IBM/ibm-common-service-operator +module github.com/IBM/ibm-common-service-operator/v4 -go 1.20 +go 1.23 + +toolchain go1.23.0 require ( - github.com/IBM/controller-filtered-cache v0.3.4 - github.com/IBM/ibm-namespace-scope-operator v1.11.0 + github.com/IBM/controller-filtered-cache v0.3.5 + github.com/IBM/ibm-namespace-scope-operator/v4 v4.2.4-0.20240501132320-6675f97bc34f github.com/IBM/ibm-secretshare-operator v1.20.3 - github.com/IBM/operand-deployment-lifecycle-manager v1.19.0 - github.com/deckarep/golang-set v1.7.1 + github.com/IBM/operand-deployment-lifecycle-manager/v4 v4.3.6-beta github.com/ghodss/yaml v1.0.0 github.com/ibm/ibm-cert-manager-operator v0.0.0-20230705134954-f3b9b344298a github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 - github.com/onsi/ginkgo v1.16.4 - github.com/onsi/gomega v1.15.0 + github.com/onsi/ginkgo v1.16.5 + github.com/onsi/gomega v1.19.0 github.com/operator-framework/api v0.6.2 github.com/operator-framework/operator-lifecycle-manager v0.17.0 - k8s.io/api v0.22.1 - k8s.io/apimachinery v0.22.1 - k8s.io/client-go v0.22.1 + github.com/stretchr/testify v1.9.0 + k8s.io/api v0.24.3 + k8s.io/apimachinery v0.24.17 + k8s.io/client-go v0.24.3 k8s.io/klog v1.0.0 - sigs.k8s.io/controller-runtime v0.10.0 + sigs.k8s.io/controller-runtime v0.12.3 ) require ( - cloud.google.com/go/compute v1.15.1 // indirect + cloud.google.com/go/compute v1.23.0 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect + github.com/PuerkitoBio/purell v1.1.1 // indirect + github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver v3.5.1+incompatible // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/evanphx/json-patch v4.11.0+incompatible // indirect - github.com/fsnotify/fsnotify v1.4.9 // indirect - github.com/go-logr/logr v0.4.0 // indirect - github.com/go-logr/zapr v0.4.0 // indirect + github.com/deckarep/golang-set v1.7.1 // indirect + github.com/emicklei/go-restful/v3 v3.10.0 // indirect + github.com/evanphx/json-patch v4.12.0+incompatible // indirect + github.com/fsnotify/fsnotify v1.5.4 // indirect + github.com/go-logr/logr v1.2.3 // indirect + github.com/go-logr/zapr v1.2.0 // indirect + github.com/go-openapi/jsonpointer v0.19.5 // indirect + github.com/go-openapi/jsonreference v0.19.5 // indirect + github.com/go-openapi/swag v0.19.14 // indirect github.com/gobuffalo/flect v0.2.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/google/gnostic v0.6.9 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/gofuzz v1.1.0 // indirect - github.com/google/uuid v1.3.0 // indirect - github.com/googleapis/gnostic v0.5.5 // indirect + github.com/google/uuid v1.3.1 // indirect github.com/imdario/mergo v0.3.12 // indirect - github.com/json-iterator/go v1.1.11 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/mailru/easyjson v0.7.6 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.1 // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/nxadm/tail v1.4.8 // indirect github.com/operator-framework/operator-registry v1.13.6 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/prometheus/client_golang v1.11.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/prometheus/client_golang v1.12.2 // indirect github.com/prometheus/client_model v0.2.0 // indirect - github.com/prometheus/common v0.26.0 // indirect - github.com/prometheus/procfs v0.6.0 // indirect + github.com/prometheus/common v0.32.1 // indirect + github.com/prometheus/procfs v0.7.3 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/spf13/pflag v1.0.5 // indirect go.uber.org/atomic v1.7.0 // indirect go.uber.org/multierr v1.6.0 // indirect - go.uber.org/zap v1.19.0 // indirect - golang.org/x/net v0.17.0 // indirect - golang.org/x/oauth2 v0.4.0 // indirect - golang.org/x/sys v0.13.0 // indirect - golang.org/x/term v0.13.0 // indirect - golang.org/x/text v0.13.0 // indirect - golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect + go.uber.org/zap v1.19.1 // indirect + golang.org/x/mod v0.17.0 + golang.org/x/net v0.33.0 // indirect + golang.org/x/oauth2 v0.11.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/term v0.27.0 // indirect + golang.org/x/text v0.21.0 // indirect + golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect - google.golang.org/grpc v1.53.0 // indirect - google.golang.org/protobuf v1.28.1 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect + google.golang.org/grpc v1.59.0 // indirect + google.golang.org/protobuf v1.33.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.0 // indirect - k8s.io/apiextensions-apiserver v0.22.1 // indirect - k8s.io/component-base v0.22.1 // indirect - k8s.io/klog/v2 v2.9.0 // indirect - k8s.io/kube-aggregator v0.18.9 // indirect - k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e // indirect - k8s.io/utils v0.0.0-20210802155522-efc7438f0176 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.1.2 // indirect - sigs.k8s.io/yaml v1.2.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/apiextensions-apiserver v0.24.2 // indirect + k8s.io/component-base v0.24.2 // indirect + k8s.io/klog/v2 v2.60.1 // indirect + k8s.io/kube-openapi v0.0.0-20220627174259-011e075b9cb8 // indirect + k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect + sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect ) // fix vulnerability: CVE-2021-3121 in github.com/gogo/protobuf < v1.3.2 diff --git a/go.sum b/go.sum index bc9bd4624..030027555 100644 --- a/go.sum +++ b/go.sum @@ -11,11 +11,23 @@ cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6T cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/compute v1.15.1 h1:7UGq3QknM33pw5xATlpzeoomNxsacIVvTqTTvbfajmE= -cloud.google.com/go/compute v1.15.1/go.mod h1:bjjoF/NtFUrkD/urWfdHaKuOPDR5nWIs63rR+SXhcpA= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/compute v1.23.0 h1:tP41Zoavr8ptEqaW6j+LQOnyBBhO7OkOMAGrgLopTwY= +cloud.google.com/go/compute v1.23.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= @@ -24,13 +36,15 @@ cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqCl cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= -github.com/Azure/go-ansiterm v0.0.0-20210608223527-2377c96fe795/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= @@ -55,14 +69,14 @@ github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbt github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/IBM/controller-filtered-cache v0.3.4 h1:msdH0oQqEab+R8bppCUcOJVDQw6yxYFAvrLqUtSDp0E= -github.com/IBM/controller-filtered-cache v0.3.4/go.mod h1:NDLuOZt+Qk5hZQlVz74ZszrvO2741sO5X7kE9PV/4VI= -github.com/IBM/ibm-namespace-scope-operator v1.11.0 h1:l8CPz+1XBvb77vWvNRU5AFFAAgD3bL3pcVXtUcvnyXk= -github.com/IBM/ibm-namespace-scope-operator v1.11.0/go.mod h1:wLkJV6mcFiZx/8ZpnGb46sbO8Q4SuYVSLSE5YrgY4v8= +github.com/IBM/controller-filtered-cache v0.3.5 h1:XoT+7B12jGeWHZBe3qOnXNCJukGtXP+MUVnu0Lq4BvM= +github.com/IBM/controller-filtered-cache v0.3.5/go.mod h1:Lu4gJQZ9TqO9FiQXq+JA5gXs8/4AoFmo4ee+PD5Lp/A= +github.com/IBM/ibm-namespace-scope-operator/v4 v4.2.4-0.20240501132320-6675f97bc34f h1:cycg5Djud79GAA804WU/Y0gHi9Lqp3DVgkFPrPYj4P8= +github.com/IBM/ibm-namespace-scope-operator/v4 v4.2.4-0.20240501132320-6675f97bc34f/go.mod h1:p9DwVRJG6GF3b+kWQru/4fSEr3OQhlHKVEuJZcKewLs= github.com/IBM/ibm-secretshare-operator v1.20.3 h1:4Mz7FJ3f9TwFJqTVu4SfBHhspqtXwaCPtLnxv7DWT14= github.com/IBM/ibm-secretshare-operator v1.20.3/go.mod h1:gAkGb8Hts8swz5Ptbvkq/S0YylHE4zOTmUvj68uTQDI= -github.com/IBM/operand-deployment-lifecycle-manager v1.19.0 h1:96mWxWhoJxoDoL2TlJHIR/jzgxHSx9AJfmmS6bsuNbE= -github.com/IBM/operand-deployment-lifecycle-manager v1.19.0/go.mod h1:N/CoO0EDow3UblekSQzY1HWz4js8R/HvrM3twmlTRT0= +github.com/IBM/operand-deployment-lifecycle-manager/v4 v4.3.6-beta h1:IgthjeLSNpRchewht8XwqMgrn7O5XaGjhcPFvpT/EO0= +github.com/IBM/operand-deployment-lifecycle-manager/v4 v4.3.6-beta/go.mod h1:xRmAdXxi7Yq1BgEv0UVIMlOVLWNdjim+1IlGxn4zl3U= github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E= github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver/v3 v3.0.3/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= @@ -80,8 +94,10 @@ github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= @@ -97,11 +113,13 @@ github.com/alessio/shellescape v0.0.0-20190409004728-b115ca0f9053/go.mod h1:xW8s github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210826220005-b48c857c3a0e/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= @@ -128,6 +146,7 @@ github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2y github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/bshuster-repo/logrus-logstash-hook v0.4.1 h1:pgAtgj+A31JBVtEHu2uHuEx0n+2ukqUJnS2vVe5pQNA= github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= +github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= github.com/bugsnag/bugsnag-go v1.5.3 h1:yeRUT3mUE13jL1tGwvoQsKdVbAsQx9AJ+fqahKveP04= github.com/bugsnag/bugsnag-go v1.5.3/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= @@ -141,6 +160,7 @@ github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6 github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.0/go.mod h1:dgIUBU3pDso/gPgZ1osOZ0iQf77oPR28Tjxl5dIMyVM= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw= @@ -149,7 +169,9 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= @@ -188,6 +210,7 @@ github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfc github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -254,33 +277,40 @@ github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkg github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/emicklei/go-restful/v3 v3.10.0 h1:X4gma4HM7hFm6WMeAsTfqA0GOfdNoCzBIkHGoRLGXuM= +github.com/emicklei/go-restful/v3 v3.10.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch v4.11.0+incompatible h1:glyUF9yIYtMHzn8xaKw5rMhdWcwsYV8dZHIq5567/xs= -github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= +github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239/go.mod h1:Gdwt2ce0yfBxPvZrHkprdPPTTS3N5rwmLE8T22KBXlw= github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= +github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/fsouza/fake-gcs-server v1.7.0/go.mod h1:5XIRs4YvwNbNoz+1JF8j6KLAyDh7RHGAyAK3EP2EsNk= github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/garyburd/redigo v1.6.0 h1:0VruCpn7yAIIu7pWVClQC8wxCJEcG3nyzpMSHKi1PQc= github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= +github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= @@ -301,12 +331,13 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v0.3.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc= -github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/zapr v0.1.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= github.com/go-logr/zapr v0.2.0/go.mod h1:qhKdvif7YF5GI9NWEpyxTSSBdGmzkNguibrdCNVPunU= -github.com/go-logr/zapr v0.4.0 h1:uc1uML3hRYL9/ZZPdgHS/n8Nzo+eaYL/Efxkkamf7OM= -github.com/go-logr/zapr v0.4.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= +github.com/go-logr/zapr v1.2.0 h1:n4JnPI1T3Qq1SFEi/F8rwLrZERp2bso19PJZDB9dayk= +github.com/go-logr/zapr v1.2.0/go.mod h1:Qa4Bsj2Vb+FAVeAKsLD8RLQ+YRJB8YDmOAKxaBQf7Ro= github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= @@ -320,12 +351,14 @@ github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwds github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= +github.com/go-openapi/jsonreference v0.19.5 h1:1WJP/wi4OjB4iV8KVbH73rQaoialJrqv8gitZLxGLtM= github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= @@ -350,6 +383,7 @@ github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/ github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng= github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= @@ -359,7 +393,6 @@ github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+ github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/gobuffalo/flect v0.1.5/go.mod h1:W3K3X9ksuZfir8f/LrfVtWmCDQFfayuylOJ7sz/Fj80= github.com/gobuffalo/flect v0.2.0/go.mod h1:W3K3X9ksuZfir8f/LrfVtWmCDQFfayuylOJ7sz/Fj80= github.com/gobuffalo/flect v0.2.1 h1:GPoRjEN0QObosV4XwuoWvSd5uSiL0N3e91/xqyY4crQ= github.com/gobuffalo/flect v0.2.1/go.mod h1:vmkQwuZYhN5Pc4ljYQZzP+1sq+NEkK+lh20jmEmX3jc= @@ -376,6 +409,7 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69 github.com/golang-migrate/migrate/v4 v4.6.2 h1:LDDOHo/q1W5UDj6PbkxdCv7lv9yunyZHXvxuwDkGo3k= github.com/golang-migrate/migrate/v4 v4.6.2/go.mod h1:JYi6reN3+Z734VZ0akNuyOJNcrg45ZL7LDBMW3WGJL0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -388,12 +422,16 @@ github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= @@ -404,8 +442,9 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -415,12 +454,20 @@ github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA// github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/cel-go v0.10.1/go.mod h1:U7ayypeSkw23szu4GaQTPJGx66c20mx8JklMSxrmI1w= +github.com/google/cel-spec v0.6.0/go.mod h1:Nwjgxy5CbjlPrtCWjeDjUyKMl8w41YBYGjsyDdqk0xA= +github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= +github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0= +github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= @@ -432,17 +479,25 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= @@ -450,8 +505,6 @@ github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTV github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU= github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= -github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw= -github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= @@ -460,8 +513,9 @@ github.com/gorilla/handlers v1.4.2 h1:0QniY0USkHQ1RGCLfKxeNHK9bkDHGRYGNDFBCS+YAR github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.2 h1:zoNxOV7WjqXptQOVngLmcSQgXmgk4NMz1HibBchjl/I= github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= @@ -503,6 +557,7 @@ github.com/hokaccha/go-prettyjson v0.0.0-20190818114111-108c894c2c0e/go.mod h1:p github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ibm/ibm-cert-manager-operator v0.0.0-20230705134954-f3b9b344298a h1:SG/2DfTG9Jpc5SZIjyJRddH/Hn7N/lyQtXgWhHmTPY0= github.com/ibm/ibm-cert-manager-operator v0.0.0-20230705134954-f3b9b344298a/go.mod h1:2SHAtk2xDjLv3gyzOTDuN+rYOOU9ESh7xV2uRYtRwOM= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= @@ -528,6 +583,7 @@ github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= @@ -535,8 +591,9 @@ github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= @@ -550,6 +607,7 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -574,6 +632,7 @@ github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= @@ -611,24 +670,27 @@ github.com/mitchellh/hashstructure v1.0.0/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1D github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= -github.com/moby/term v0.0.0-20210610120745-9d4ed1856297/go.mod h1:vgPCkQMyxTZ7IDy8SXRufE172gr8+K/JE/7hHFxHW3A= +github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -652,8 +714,10 @@ github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0 github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= @@ -663,8 +727,8 @@ github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoT github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.15.0 h1:WjP/FQ/sk43MRmnEcT+MlDw2TFvkrXlprrPST/IudjU= -github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0= +github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ= @@ -712,6 +776,7 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.9.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -726,8 +791,9 @@ github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQ github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.11.1 h1:+4eQaD7vAZ6DsfsxB15hbE0odUjGI5ARs9yskGu1v4s= -github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.12.2 h1:51L9cDoUHVrXx4zWYlcLQIZ+d+VXHgqnYKkIuq4g/34= +github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= @@ -743,8 +809,9 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -755,8 +822,9 @@ github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDa github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= +github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M= @@ -765,6 +833,7 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= @@ -789,6 +858,7 @@ github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= @@ -796,8 +866,9 @@ github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tL github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= -github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M= github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= +github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q= +github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= @@ -819,8 +890,9 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.5.0/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/tebeka/strftime v0.1.3/go.mod h1:7wJm3dZlpr4l/oVK0t1HYIc4rMzQ2XJlOMIUJUJH6XQ= @@ -841,12 +913,16 @@ github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2 github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= github.com/xeipuuv/gojsonschema v1.1.0/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xlab/handysort v0.0.0-20150421192137-fb3537ed64a1/go.mod h1:QcJo0QPSfTONNIgpN5RA8prR7fF8nkF6cTWTcNerRO8= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= github.com/yvasiyarov/go-metrics v0.0.0-20150112132944-c25f46c4b940 h1:p7OofyZ509h8DmPLh8Hn+EIIZm/xYhdZHJ9GnXHdr6U= github.com/yvasiyarov/go-metrics v0.0.0-20150112132944-c25f46c4b940/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= @@ -866,9 +942,12 @@ go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= +go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0= +go.etcd.io/etcd/client/v3 v3.5.1/go.mod h1:OnjH4M8OnAotwaB2l9bVgZzRFKru7/ZMoS46OtKyd3Q= go.etcd.io/etcd/pkg/v3 v3.5.0/go.mod h1:UzJGatBQ1lXChBkQF0AuAtkRQMYnHubxAEYIrC3MSsE= go.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD00Szc= go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4= @@ -881,7 +960,11 @@ go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4= @@ -899,8 +982,10 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= +go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= @@ -910,8 +995,9 @@ go.uber.org/zap v1.8.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= -go.uber.org/zap v1.19.0 h1:mZQZefskPPCMIBCSEH0v2/iUqqLrYtaeqwD6FUGUnFE= go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= +go.uber.org/zap v1.19.1 h1:ue41HOKd1vGURxrmeKIgELGb3jPW9DMUDGtsinblHwI= +go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -932,7 +1018,8 @@ golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -957,7 +1044,7 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= @@ -967,8 +1054,12 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1007,17 +1098,31 @@ golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1025,18 +1130,29 @@ golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.4.0 h1:NF0gk8LVPg1Ml7SSbGyySuoxdsXitj7TvgvuRxIMc/M= -golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.11.0 h1:vPL4xzxBM4niKCW6g9whtaWVXTJf1U5e4aZxxFx/gbU= +golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1089,32 +1205,50 @@ golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1124,16 +1258,17 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs= -golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 h1:vVKdlvoWBphwdxWKrFZEuM0kGgGLxUOYcY4U/2Vjg44= +golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1181,15 +1316,32 @@ golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200616195046-dc31b401abb5/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.10-0.20220218145154-897bd77cd717/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1213,7 +1365,18 @@ google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsb google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1244,16 +1407,39 @@ google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200701001935-0939c5918c31/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201102152239-715cce707fb0/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= @@ -1267,14 +1453,22 @@ google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQ google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc= -google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= +google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= google.golang.org/grpc/cmd/protoc-gen-go-grpc v0.0.0-20200709232328-d8193ee9cc3e/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -1288,8 +1482,9 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1331,8 +1526,8 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0 h1:hjy8E9ON/egN1tAYqKb61G10WtihqetD4sz2H+8nIeA= -gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= @@ -1344,32 +1539,36 @@ honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= k8s.io/api v0.17.2/go.mod h1:BS9fjjLc4CMuqfSO8vgbHPKMt5+SF0ET6u/RVDihTo4= k8s.io/api v0.18.0/go.mod h1:q2HRQkfDzHMBZL9l/y9rH63PkQl4vae0xRT+8prbrK8= k8s.io/api v0.18.2/go.mod h1:SJCWI7OLzhZSvbY7U8zwNl9UA4o1fizoug34OV/2r78= k8s.io/api v0.18.9/go.mod h1:9u/h6sUh6FxfErv7QqetX1EB3yBMIYOBXzdcf0Gf0rc= k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo= -k8s.io/api v0.22.1 h1:ISu3tD/jRhYfSW8jI/Q1e+lRxkR7w9UwQEZ7FgslrwY= -k8s.io/api v0.22.1/go.mod h1:bh13rkTp3F1XEaLGykbyRD2QaTTzPm0e/BMd8ptFONY= +k8s.io/api v0.24.2/go.mod h1:AHqbSkTm6YrQ0ObxjO3Pmp/ubFF/KuM7jU+3khoBsOg= +k8s.io/api v0.24.3 h1:tt55QEmKd6L2k5DP6G/ZzdMQKvG5ro4H4teClqm0sTY= +k8s.io/api v0.24.3/go.mod h1:elGR/XSZrS7z7cSZPzVWaycpJuGIw57j9b95/1PdJNI= k8s.io/apiextensions-apiserver v0.17.2/go.mod h1:4KdMpjkEjjDI2pPfBA15OscyNldHWdBCfsWMDWAmSTs= k8s.io/apiextensions-apiserver v0.18.2/go.mod h1:q3faSnRGmYimiocj6cHQ1I3WpLqmDgJFlKL37fC4ZvY= k8s.io/apiextensions-apiserver v0.18.9/go.mod h1:JagmAhU0TVENzgUZqHJsjCSDh7YuV5o6g01G1Fwh7zI= k8s.io/apiextensions-apiserver v0.20.1/go.mod h1:ntnrZV+6a3dB504qwC5PN/Yg9PBiDNt1EVqbW2kORVk= -k8s.io/apiextensions-apiserver v0.22.1 h1:YSJYzlFNFSfUle+yeEXX0lSQyLEoxoPJySRupepb0gE= -k8s.io/apiextensions-apiserver v0.22.1/go.mod h1:HeGmorjtRmRLE+Q8dJu6AYRoZccvCMsghwS8XTUYb2c= +k8s.io/apiextensions-apiserver v0.24.2 h1:/4NEQHKlEz1MlaK/wHT5KMKC9UKYz6NZz6JE6ov4G6k= +k8s.io/apiextensions-apiserver v0.24.2/go.mod h1:e5t2GMFVngUEHUd0wuCJzw8YDwZoqZfJiGOW6mm2hLQ= k8s.io/apimachinery v0.17.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg= k8s.io/apimachinery v0.17.2/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg= k8s.io/apimachinery v0.18.0/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA= k8s.io/apimachinery v0.18.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA= k8s.io/apimachinery v0.18.9/go.mod h1:PF5taHbXgTEJLU+xMypMmYTXTWPJ5LaW8bfsisxnEXk= k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= -k8s.io/apimachinery v0.22.1 h1:DTARnyzmdHMz7bFWFDDm22AM4pLWTQECMpRTFu2d2OM= -k8s.io/apimachinery v0.22.1/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0= +k8s.io/apimachinery v0.24.2/go.mod h1:82Bi4sCzVBdpYjyI4jY6aHX+YCUchUIrZrXKedjd2UM= +k8s.io/apimachinery v0.24.3/go.mod h1:82Bi4sCzVBdpYjyI4jY6aHX+YCUchUIrZrXKedjd2UM= +k8s.io/apimachinery v0.24.17 h1:mewWCeZ3Swr4EAfatVAhHXJHGzCHojphWA/5UJW4pPY= +k8s.io/apimachinery v0.24.17/go.mod h1:kSzhCwldu9XB172NDdLffRN0sJ3x95RR7Bmyc4SHhs0= k8s.io/apiserver v0.17.2/go.mod h1:lBmw/TtQdtxvrTk0e2cgtOxHizXI+d0mmGQURIHQZlo= k8s.io/apiserver v0.18.2/go.mod h1:Xbh066NqrZO8cbsoenCwyDJ1OSi8Ag8I2lezeHxzwzw= k8s.io/apiserver v0.18.9/go.mod h1:vXQzMtUCLsGg1Bh+7Jo2mZKHpHZFCZn8eTNSepcIA1M= k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU= -k8s.io/apiserver v0.22.1/go.mod h1:2mcM6dzSt+XndzVQJX21Gx0/Klo7Aen7i0Ai6tIa400= +k8s.io/apiserver v0.24.2/go.mod h1:pSuKzr3zV+L+MWqsEo0kHHYwCo77AT5qXbFXP2jbvFI= k8s.io/cli-runtime v0.17.2/go.mod h1:aa8t9ziyQdbkuizkNLAw3qe3srSyWh9zlSB7zTqRNPI= k8s.io/cli-runtime v0.18.0/go.mod h1:1eXfmBsIJosjn9LjEBUd2WVPoPAY9XGTqTFcPMIBsUQ= k8s.io/client-go v0.17.2/go.mod h1:QAzRgsa0C2xl4/eVpeVAZMvikCn8Nm81yqVx3Kk9XYI= @@ -1377,27 +1576,29 @@ k8s.io/client-go v0.18.0/go.mod h1:uQSYDYs4WhVZ9i6AIoEZuwUggLVEF64HOD37boKAtF8= k8s.io/client-go v0.18.2/go.mod h1:Xcm5wVGXX9HAA2JJ2sSBUn3tCJ+4SVlCbl2MNNv+CIU= k8s.io/client-go v0.18.9/go.mod h1:UjkEetDmr40P9NX0Ok3Idt08FCf2I4mIHgjFsot77uY= k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y= -k8s.io/client-go v0.22.1 h1:jW0ZSHi8wW260FvcXHkIa0NLxFBQszTlhiAVsU5mopw= -k8s.io/client-go v0.22.1/go.mod h1:BquC5A4UOo4qVDUtoc04/+Nxp1MeHcVc1HJm1KmG8kk= +k8s.io/client-go v0.24.2/go.mod h1:zg4Xaoo+umDsfCWr4fCnmLEtQXyCNXCvJuSsglNcV30= +k8s.io/client-go v0.24.3 h1:Nl1840+6p4JqkFWEW2LnMKU667BUxw03REfLAVhuKQY= +k8s.io/client-go v0.24.3/go.mod h1:AAovolf5Z9bY1wIg2FZ8LPQlEdKHjLI7ZD4rw920BJw= k8s.io/code-generator v0.17.2/go.mod h1:DVmfPQgxQENqDIzVR2ddLXMH34qeszkKSdH/N+s+38s= k8s.io/code-generator v0.18.0/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRVkTc= k8s.io/code-generator v0.18.2/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRVkTc= k8s.io/code-generator v0.18.9/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c= k8s.io/code-generator v0.20.1/go.mod h1:UsqdF+VX4PU2g46NC2JRs4gc+IfrctnwHb76RNbWHJg= -k8s.io/code-generator v0.22.1/go.mod h1:eV77Y09IopzeXOJzndrDyCI88UBok2h6WxAlBwpxa+o= +k8s.io/code-generator v0.24.2/go.mod h1:dpVhs00hTuTdTY6jvVxvTFCk6gSMrtfRydbhZwHI15w= k8s.io/component-base v0.17.2/go.mod h1:zMPW3g5aH7cHJpKYQ/ZsGMcgbsA/VyhEugF3QT1awLs= k8s.io/component-base v0.18.0/go.mod h1:u3BCg0z1uskkzrnAKFzulmYaEpZF7XC9Pf/uFyb1v2c= k8s.io/component-base v0.18.2/go.mod h1:kqLlMuhJNHQ9lz8Z7V5bxUUtjFZnrypArGl58gmDfUM= k8s.io/component-base v0.18.9/go.mod h1:tUo4qZtV8m7t/U+0DgY+fcnn4BFZ480fZdzxOkWH4zk= k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk= -k8s.io/component-base v0.22.1 h1:SFqIXsEN3v3Kkr1bS6rstrs1wd45StJqbtgbQ4nRQdo= -k8s.io/component-base v0.22.1/go.mod h1:0D+Bl8rrnsPN9v0dyYvkqFfBeAd4u7n77ze+p8CMiPo= +k8s.io/component-base v0.24.2 h1:kwpQdoSfbcH+8MPN4tALtajLDfSfYxBDYlXobNWI6OU= +k8s.io/component-base v0.24.2/go.mod h1:ucHwW76dajvQ9B7+zecZAP3BVqvrHoOxm8olHEg0nmM= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20200114144118-36b2048a9120/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= -k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/gengo v0.0.0-20211129171323-c02415ce4185/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= @@ -1405,16 +1606,16 @@ k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= -k8s.io/klog/v2 v2.9.0 h1:D7HV+n1V57XeZ0m6tdRkfknthUaM06VFbWldOFh8kzM= -k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= -k8s.io/kube-aggregator v0.18.9 h1:kqwbA15uygYfLfdMUlyBm/q3OHaYbnirFrg7tGUTVZk= +k8s.io/klog/v2 v2.60.1 h1:VW25q3bZx9uE3vvdL6M8ezOX79vA2Aq1nEWLqNQclHc= +k8s.io/klog/v2 v2.60.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-aggregator v0.18.9/go.mod h1:ik5Mf6JaP2M9XbWZR/AYgXx2Nj4EDBrHyakUx7C8cdw= k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= -k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e h1:KLHHjkdQFomZy8+06csTWZ0m1343QqxZhR2LJ1OxCYM= -k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= +k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42/go.mod h1:Z/45zLw8lUo4wdiUkI+v/ImEGAvu3WatcZl3lPMR4Rk= +k8s.io/kube-openapi v0.0.0-20220627174259-011e075b9cb8 h1:yEQKdMCjzAOvGeiTwG4hO/hNVNtDOuUFvMUZ0OlaIzs= +k8s.io/kube-openapi v0.0.0-20220627174259-011e075b9cb8/go.mod h1:mbJ+NSUoAhuR14N0S63bPkh8MGVSo3VYSGZtH/mfMe0= k8s.io/kubectl v0.17.2/go.mod h1:y4rfLV0n6aPmvbRCqZQjvOp3ezxsFgpqL+zF5jH/lxk= k8s.io/kubectl v0.18.0/go.mod h1:LOkWx9Z5DXMEg5KtOjHhRiC1fqJPLyCr3KtQgEolCkU= k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= @@ -1423,9 +1624,9 @@ k8s.io/metrics v0.18.0/go.mod h1:8aYTW18koXqjLVKL7Ds05RPMX9ipJZI3mywYvBOxXd4= k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20210707171843-4b05e18ac7d9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20210802155522-efc7438f0176 h1:Mx0aa+SUAcNRQbs5jUzV8lkDlGFU8laZsY9jrcVX5SY= k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 h1:HNSDgDCrr/6Ly3WEGKZftiE7IY19Vz2GdbOCyI4qqhc= +k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw= modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk= modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k= @@ -1438,13 +1639,15 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.30/go.mod h1:fEO7lRTdivWO2qYVCVG7dEADOMo/MLDCVr8So2g88Uw= sigs.k8s.io/controller-runtime v0.6.0/go.mod h1:CpYf5pdNY/B352A1TFLAS2JVSlnGQ5O2cftPHndTroo= sigs.k8s.io/controller-runtime v0.8.0/go.mod h1:v9Lbj5oX443uR7GXYY46E0EE2o7k2YxQ58GxVNeXSW4= -sigs.k8s.io/controller-runtime v0.10.0 h1:HgyZmMpjUOrtkaFtCnfxsR1bGRuFoAczSNbn2MoKj5U= -sigs.k8s.io/controller-runtime v0.10.0/go.mod h1:GCdh6kqV6IY4LK0JLwX0Zm6g233RtVGdb/f0+KSfprg= +sigs.k8s.io/controller-runtime v0.12.3 h1:FCM8xeY/FI8hoAfh/V4XbbYMY20gElh9yh+A98usMio= +sigs.k8s.io/controller-runtime v0.12.3/go.mod h1:qKsk4WE6zW2Hfj0G4v10EnNB2jMG1C+NTb8h+DwCoU0= sigs.k8s.io/controller-tools v0.3.0/go.mod h1:enhtKGfxZD1GFEoMgP8Fdbu+uKQ/cq1/WGJhdVChfvI= sigs.k8s.io/controller-tools v0.4.1/go.mod h1:G9rHdZMVlBDocIxGkK3jHLWqcTMNvveypYJwrvYKjWU= +sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y= +sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY= sigs.k8s.io/kind v0.7.0/go.mod h1:An/AbWHT6pA/Lm0Og8j3ukGhfJP3RiVN/IBU6Lo3zl8= sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU= sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= @@ -1452,9 +1655,11 @@ sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06/go.mod h1 sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= -sigs.k8s.io/structured-merge-diff/v4 v4.1.2 h1:Hr/htKFmJEbtMgS/UD0N+gtgctAqz81t3nu+sPzynno= -sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= +sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= +sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= +sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= vbom.ml/util v0.0.0-20160121211510-db5cfe13f5cc/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj6uzU2+8OWDFv/HxUSs7kI= diff --git a/hack/keycloak-themes/.gitignore b/hack/keycloak-themes/.gitignore new file mode 100644 index 000000000..23ccd022c --- /dev/null +++ b/hack/keycloak-themes/.gitignore @@ -0,0 +1 @@ +cloudpak-theme.jar diff --git a/hack/keycloak-themes/META-INF/MANIFEST.MF b/hack/keycloak-themes/META-INF/MANIFEST.MF new file mode 100644 index 000000000..0a6a779ec --- /dev/null +++ b/hack/keycloak-themes/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Created-By: 11.0.13 (International Business Machines Corporation) + diff --git a/hack/keycloak-themes/META-INF/keycloak-themes.json b/hack/keycloak-themes/META-INF/keycloak-themes.json new file mode 100644 index 000000000..3bd5c5c5f --- /dev/null +++ b/hack/keycloak-themes/META-INF/keycloak-themes.json @@ -0,0 +1,6 @@ +{ + "themes": [{ + "name" : "cloudpak", + "types": [ "login", "account", "admin", "email", "common" ] + }] +} diff --git a/hack/keycloak-themes/Makefile b/hack/keycloak-themes/Makefile new file mode 100644 index 000000000..9ba3912fa --- /dev/null +++ b/hack/keycloak-themes/Makefile @@ -0,0 +1,17 @@ +KEYCLOAK_THEME_DIR ?= $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) +JAR_THEME_FILE ?= cloudpak-theme.jar + +default: cloudpak-theme.jar + +.PHONY: cloudpak-theme.jar +cloudpak-theme.jar: + @echo "Building the keycloak jar theme..." + rm $(KEYCLOAK_THEME_DIR)/$(JAR_THEME_FILE) || true + (cd $(KEYCLOAK_THEME_DIR) && zip -r ./$(JAR_THEME_FILE) META-INF theme) + +cloudpak-theme-version: + $(eval THEME_VERSION := $(shell ls $(KEYCLOAK_THEME_DIR)/theme/cloudpak/login/resources/css/ | grep .css)) + @echo "Updating the keycloak jar theme version to $(THEME_VERSION)" + $(YQ) eval -i '.spec.template.metadata.annotations.cloudPakThemesVersion = "$(THEME_VERSION)"' $(KEYCLOAK_THEME_DIR)/../../testdata/deploy/deploy.yaml + $(YQ) eval -i '.metadata.annotations.cloudPakThemesVersion = "$(THEME_VERSION)"' $(KEYCLOAK_THEME_DIR)/../../config/manifests/bases/ibm-common-service-operator.clusterserviceversion.yaml + $(YQ) eval -i '.metadata.annotations.cloudPakThemesVersion = "$(THEME_VERSION)"' $(KEYCLOAK_THEME_DIR)/../../bundle/manifests/ibm-common-service-operator.clusterserviceversion.yaml \ No newline at end of file diff --git a/hack/keycloak-themes/README.md b/hack/keycloak-themes/README.md new file mode 100644 index 000000000..eb8fd71a3 --- /dev/null +++ b/hack/keycloak-themes/README.md @@ -0,0 +1,41 @@ +# keycloak-themes + +A Keycloak theme for IBM Cloud Paks. + +See https://www.keycloak.org/docs/latest/server_development/index.html#_themes + +**The style files are cached, so if you update the them, remember to update the style file name and the `styles` property in `theme.properties`.** +For example, for CS 4.6: +theme/cloudpak/login/resources/css/styles470.css +theme/cloudpak/login/theme.properies styles=css/styles470.css +NOTE: this would likely apply to any of the files - images, fonts, etc. If updated, they must be renamed. + +### Style version for release 4.11.0 +theme/cloudpak/login/resources/css/styles4100.css +theme/cloudpak/login/theme.properies styles=css/styles4100.css + +## Testing + +Easiest way to play with it is to mount it into a local keycloak dev container. + +1. Run the container: + + ``` + podman run -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=chooseapassword -p 8080:8080 -p 8443:8443 -v $(pwd)/theme/:/opt/keycloak/themes:Z --name rhbk registry.redhat.io/rhbk/keycloak-rhel9@sha256:d18adf0219a17b6619ddfb86a7d569019481f0315d94917793038ba5c6dc9567 start-dev + ``` + +1. Log into Keycloak with your chosen admin password at http://localhost:8080/ + +1. Create a realm + +1. Assign the theme to the realm + +Any changes you make will be immediately visible, although you might need to force refresh to avoid caching. + +## Developing + +The easiest way to understand what you can override in the theme is to look at the existing themes. To do this, get the theme jar (something like `org.keycloak.keycloak-themes-22.0.7.redhat-00001.jar` and `org.keycloak.keycloak-admin-ui-22.0.7.redhat-00001.jar`) from an RHBK instance and extract it. + +In the `theme.properties` file, you can specify a parent theme (where resources not included in your theme will be taken from) and one or more imports (additional files you want to be considered part of your theme). You can also add additinal styles and set properties for class names etc - see the RHBK themes for examples. + +Any file you include in your theme will override a parent theme file, so by looking at the RHBK theme files and putting equivalents into the cloud pak theme, you can override resources. diff --git a/hack/keycloak-themes/theme/cloudpak/account/theme.properties b/hack/keycloak-themes/theme/cloudpak/account/theme.properties new file mode 100644 index 000000000..8db2c6e7f --- /dev/null +++ b/hack/keycloak-themes/theme/cloudpak/account/theme.properties @@ -0,0 +1,17 @@ +parent=keycloak.v2 +import=common/cloudpak +deprecatedMode=false + +developmentMode=false + +# This is the logo in upper lefthand corner. +# It must be a relative path. +logo=/img/logo.svg + +# This is the link followed when clicking on the logo. +# It can be any valid URL, including an external site. +logoUrl=./ + +# This is the icon for the account console. +# It must be a relative path. +favIcon=/img/favicon.ico diff --git a/hack/keycloak-themes/theme/cloudpak/admin/theme.properties b/hack/keycloak-themes/theme/cloudpak/admin/theme.properties new file mode 100644 index 000000000..8db2c6e7f --- /dev/null +++ b/hack/keycloak-themes/theme/cloudpak/admin/theme.properties @@ -0,0 +1,17 @@ +parent=keycloak.v2 +import=common/cloudpak +deprecatedMode=false + +developmentMode=false + +# This is the logo in upper lefthand corner. +# It must be a relative path. +logo=/img/logo.svg + +# This is the link followed when clicking on the logo. +# It can be any valid URL, including an external site. +logoUrl=./ + +# This is the icon for the account console. +# It must be a relative path. +favIcon=/img/favicon.ico diff --git a/hack/keycloak-themes/theme/cloudpak/common/resources/img/favicon.ico b/hack/keycloak-themes/theme/cloudpak/common/resources/img/favicon.ico new file mode 100644 index 000000000..6a761d73f Binary files /dev/null and b/hack/keycloak-themes/theme/cloudpak/common/resources/img/favicon.ico differ diff --git a/hack/keycloak-themes/theme/cloudpak/common/resources/img/logo.svg b/hack/keycloak-themes/theme/cloudpak/common/resources/img/logo.svg new file mode 100644 index 000000000..dc5886cf3 --- /dev/null +++ b/hack/keycloak-themes/theme/cloudpak/common/resources/img/logo.svg @@ -0,0 +1,50 @@ + + + + + + + + + + diff --git a/hack/keycloak-themes/theme/cloudpak/email/theme.properties b/hack/keycloak-themes/theme/cloudpak/email/theme.properties new file mode 100644 index 000000000..8f83cc023 --- /dev/null +++ b/hack/keycloak-themes/theme/cloudpak/email/theme.properties @@ -0,0 +1 @@ +parent=base diff --git a/hack/keycloak-themes/theme/cloudpak/login/messages/messages_de.properties b/hack/keycloak-themes/theme/cloudpak/login/messages/messages_de.properties new file mode 100644 index 000000000..50ab8964a --- /dev/null +++ b/hack/keycloak-themes/theme/cloudpak/login/messages/messages_de.properties @@ -0,0 +1,7 @@ +usernameOrEmail=Benutzername +loginAccountTitle=Anmelden +doLogIn=Anmelden +identity-provider-login-label=Alternative Anmeldungen +loginProfileTitle=Kontoinformationen aktualisieren +loginIdpReviewProfileTitle=Kontoinformationen aktualisieren +doForgotPassword=Kennwort vergessen? diff --git a/hack/keycloak-themes/theme/cloudpak/login/messages/messages_en.properties b/hack/keycloak-themes/theme/cloudpak/login/messages/messages_en.properties new file mode 100644 index 000000000..c023792bd --- /dev/null +++ b/hack/keycloak-themes/theme/cloudpak/login/messages/messages_en.properties @@ -0,0 +1,7 @@ +usernameOrEmail=Username +loginAccountTitle=Log in +doLogIn=Log in +identity-provider-login-label=Alternative logins +loginProfileTitle=Update account information +loginIdpReviewProfileTitle=Update account information +doForgotPassword=Forgot password? diff --git a/hack/keycloak-themes/theme/cloudpak/login/messages/messages_es.properties b/hack/keycloak-themes/theme/cloudpak/login/messages/messages_es.properties new file mode 100644 index 000000000..529436d92 --- /dev/null +++ b/hack/keycloak-themes/theme/cloudpak/login/messages/messages_es.properties @@ -0,0 +1,7 @@ +usernameOrEmail=Nombre de usuario +loginAccountTitle=Iniciar sesión +doLogIn=Iniciar sesión +identity-provider-login-label=Inicios de sesión alternativos +loginProfileTitle=Actualizar información de cuenta +loginIdpReviewProfileTitle=Actualizar información de cuenta +doForgotPassword=¿Ha olvidado la contraseña? diff --git a/hack/keycloak-themes/theme/cloudpak/login/messages/messages_fr.properties b/hack/keycloak-themes/theme/cloudpak/login/messages/messages_fr.properties new file mode 100644 index 000000000..7daec27bb --- /dev/null +++ b/hack/keycloak-themes/theme/cloudpak/login/messages/messages_fr.properties @@ -0,0 +1,7 @@ +usernameOrEmail=Nom d''utilisateur +loginAccountTitle=Connexion +doLogIn=Connexion +identity-provider-login-label=Connexions alternatives +loginProfileTitle=Mettre à jour les informations de compte +loginIdpReviewProfileTitle=Mettre à jour les informations de compte +doForgotPassword=Mot de passe oublié ? diff --git a/hack/keycloak-themes/theme/cloudpak/login/messages/messages_it.properties b/hack/keycloak-themes/theme/cloudpak/login/messages/messages_it.properties new file mode 100644 index 000000000..b9280cd21 --- /dev/null +++ b/hack/keycloak-themes/theme/cloudpak/login/messages/messages_it.properties @@ -0,0 +1,7 @@ +usernameOrEmail=Nome utente +loginAccountTitle=Accedi +doLogIn=Accedi +identity-provider-login-label=Accessi alternativi +loginProfileTitle=Aggiorna informazioni sull''account +loginIdpReviewProfileTitle=Aggiorna informazioni sull''account +doForgotPassword=Hai dimenticato la password? diff --git a/hack/keycloak-themes/theme/cloudpak/login/messages/messages_ja.properties b/hack/keycloak-themes/theme/cloudpak/login/messages/messages_ja.properties new file mode 100644 index 000000000..520221d4b --- /dev/null +++ b/hack/keycloak-themes/theme/cloudpak/login/messages/messages_ja.properties @@ -0,0 +1,7 @@ +usernameOrEmail=ユーザー名 +loginAccountTitle=ログイン +doLogIn=ログイン +identity-provider-login-label=代替ログイン +loginProfileTitle=アカウント情報の更新 +loginIdpReviewProfileTitle=アカウント情報の更新 +doForgotPassword=パスワードを忘れましたか? diff --git a/hack/keycloak-themes/theme/cloudpak/login/messages/messages_ko.properties b/hack/keycloak-themes/theme/cloudpak/login/messages/messages_ko.properties new file mode 100644 index 000000000..5453f75b0 --- /dev/null +++ b/hack/keycloak-themes/theme/cloudpak/login/messages/messages_ko.properties @@ -0,0 +1,7 @@ +usernameOrEmail=사용자 이름 +loginAccountTitle=로그인 +doLogIn=로그인 +identity-provider-login-label=대체 로그인 +loginProfileTitle=계정 정보 업데이트 +loginIdpReviewProfileTitle=계정 정보 업데이트 +doForgotPassword=비밀번호를 잊으셨습니까? diff --git a/hack/keycloak-themes/theme/cloudpak/login/messages/messages_pt_BR.properties b/hack/keycloak-themes/theme/cloudpak/login/messages/messages_pt_BR.properties new file mode 100644 index 000000000..9b7942bd8 --- /dev/null +++ b/hack/keycloak-themes/theme/cloudpak/login/messages/messages_pt_BR.properties @@ -0,0 +1,7 @@ +usernameOrEmail=Nome do usuário +loginAccountTitle=Efetuar login +doLogIn=Efetuar login +identity-provider-login-label=Logins alternativos +loginProfileTitle=Atualizar informações da conta +loginIdpReviewProfileTitle=Atualizar informações da conta +doForgotPassword=Esqueceu a senha? diff --git a/hack/keycloak-themes/theme/cloudpak/login/messages/messages_zh_CN.properties b/hack/keycloak-themes/theme/cloudpak/login/messages/messages_zh_CN.properties new file mode 100644 index 000000000..7f316a89c --- /dev/null +++ b/hack/keycloak-themes/theme/cloudpak/login/messages/messages_zh_CN.properties @@ -0,0 +1,7 @@ +usernameOrEmail=用户名 +loginAccountTitle=登录 +doLogIn=登录 +identity-provider-login-label=备用登录 +loginProfileTitle=更新帐户信息 +loginIdpReviewProfileTitle=更新帐户信息 +doForgotPassword=忘记密码? diff --git a/hack/keycloak-themes/theme/cloudpak/login/messages/messages_zh_TW.properties b/hack/keycloak-themes/theme/cloudpak/login/messages/messages_zh_TW.properties new file mode 100644 index 000000000..e962a7e66 --- /dev/null +++ b/hack/keycloak-themes/theme/cloudpak/login/messages/messages_zh_TW.properties @@ -0,0 +1,7 @@ +usernameOrEmail=使用者名稱 +loginAccountTitle=登入 +doLogIn=登入 +identity-provider-login-label=替代登入 +loginProfileTitle=更新帳戶資訊 +loginIdpReviewProfileTitle=更新帳戶資訊 +doForgotPassword=忘記密碼? diff --git a/hack/keycloak-themes/theme/cloudpak/login/resources/css/styles4100.css b/hack/keycloak-themes/theme/cloudpak/login/resources/css/styles4100.css new file mode 100755 index 000000000..e1701b652 --- /dev/null +++ b/hack/keycloak-themes/theme/cloudpak/login/resources/css/styles4100.css @@ -0,0 +1,407 @@ +/* +:root { + --textColor: #f6f5f7; + } +*/ + +@font-face { + font-family: IBM Plex Sans; + src: url("../fonts/IBMPlexSans-Regular.woff2") format("woff2"), + url("../fonts/IBMPlexSans-Regular.woff") format("woff"); + font-weight: normal; +} + +body { + background: #161616 !important; + color: #f4f4f4; +} + +body .login-pf-page { + font-family: IBM Plex Sans; + padding-top: 0px; + background: #161616 !important; +} + +.login-pf-page a, #reset-login { + color: #78A9FF; +} + +/* set ibm cloudpak header */ +.kc-logo-text { + background-image: url(../img/login-header.svg); + background-repeat: no-repeat; + height: 48px; + width: 100%; + margin: 0 auto; +} +.kc-logo-text span { + display: none; +} + + +#kc-locale-wrapper { + display: none; +} + +#kc-content-wrapper { + border-top: 1px solid #393939; + padding-top: 5px; +} + +.kc-form-wrapper { + background-color: #262626; +} + +.login-pf-page .card-pf { + background: #161616; + margin: 56px auto auto auto; + width: 288px; + padding: 0px; +} + +.login-pf-page .login-pf-header { + margin-bottom: 40px; +} + +.login-pf-page .login-pf-header h1 { + line-height: 40px; + letter-spacing: 0; + color: #f4f4f4; + font-size: 32px; + text-align: left; + margin: 0px; +} + +/* input fields and labels */ +.pf-c-form__label.pf-c-form__label-text { + margin: .5rem 0; + color: #c6c6c6; + font-size: 12px; + line-height: 16px; + letter-spacing: .32px; +} + +#username,#password,#password-new,#password-confirm,#email,#firstName,#lastName { + height: 48px; + background-color: #262626; + background: #262626; + font-size: .875rem; + font-weight: 300; + line-height: 1.28572; + letter-spacing: .16px; + outline: 2px solid transparent; + outline-offset: -2px; + padding: 0 1rem; + border: none; + border-bottom: 1px solid #6f6f6f; + transition: background-color 70ms cubic-bezier(.2,0,.38,.9),outline 70ms cubic-bezier(.2,0,.38,.9); + color: #f4f4f4; +} + +#username[aria-invalid=true], #password[aria-invalid=true] { + border: none; + border: 2px solid #fa4d56; + background-image: var(--pf-c-form-control--invalid--BackgroundUrl); + background-position: var(--pf-c-form-control--invalid--BackgroundPosition); + background-size: var(--pf-c-form-control--invalid--BackgroundSize); + background-repeat: no-repeat; +} + +#input-error { + color: #ff8389; + font-size: 12px; + line-height: 16px; + letter-spacing: 0.32px; +} + +/* input fields */ +#username:focus,#password:focus,#password-new:focus,#password-confirm:focus,#email:focus,#firstName:focus,#lastName:focus { + outline: 2px solid #fff; + outline-offset: -2px; +} + +/* login button, submit button, buttons on other panels */ +#kc-login, .pf-c-button.pf-m-primary.pf-m-block.btn-lg, .pf-c-button.pf-m-primary.btn-lg, .pf-c-button.btn-default.btn-lg { + border: 1px solid transparent; + background-color: #0f62fe; + color: #fff; + min-height: 3rem; + cursor: pointer; + text-align: left; + font-size: .875rem; + font-weight: 300; + letter-spacing: .16px; + outline: none; +} + +/* for update password screen */ +#kc-form-buttons { + display: flex; + flex-direction: row-reverse; +} +.pf-c-button.pf-m-primary.btn-lg { + width: 100%; +} +/* cancel button */ +.pf-c-button.btn-default.btn-lg { + background-image: none; + background-color: #393939; + width: 100%; + margin-right: 1px; +} +.pf-c-button.btn-default.btn-lg::after { + min-height: 3rem; +} + +#kc-login:hover, .pf-c-button.pf-m-primary.pf-m-block.btn-lg:hover, .pf-c-button.pf-m-primary.btn-lg:hover { + background-color: #0353e9; +} +.pf-c-button.btn-default.btn-lg:hover { + background-color: #474747; +} + +#kc-login:focus, .pf-c-button.pf-m-primary.pf-m-block.btn-lg:focus, .pf-c-button.pf-m-primary.btn-lg:focus, +.pf-c-button.btn-default.btn-lg:focus { + border-color: #fff; + box-shadow: inset 0 0 0 1px #fff,inset 0 0 0 2px #161616; +} + +/* show password button */ +.pf-c-input-group .pf-c-button.pf-m-control { + background-color: #262626; + color: #ffffff; + /*border-bottom: 1px solid #6f6f6f; puts text field line under button + outline: 2px solid transparent;*/ + height: 48px; +} +.fa.fa-eye { + width: 16px; + height: 16px; +} +.fa-eye::before { + content: url("../img/view.svg"); +} +.fa.fa-eye-slash { + width: 16px; + height: 16px; +} +.fa-eye-slash::before { + content: url("../img/view--off.svg"); +} + +/* The following block of styling is to get the carbon checkbox */ +.checkbox label { + padding-left: 27px; +} +/* This rule is specifically for the remember me checkbox - had odd alignment,don't know why */ +.form-group.login-pf-settings .checkbox label { + padding-top: 2px; +} +label:has( > input[type=checkbox]:focus)::before { + outline: 2px solid #fff; + outline-offset: 1px; +} +label:has( > input[type=checkbox]:checked)::before { + border-width: 1px; + border-color: #f4f4f4; + background-color: #f4f4f4; +} +label:has( > input[type=checkbox]:checked)::after { + transform: scale(1) rotate(-45deg); +} +label:has( > input[type=checkbox])::before { + position: absolute; + top: .125rem; + left: 0; + width: 1rem; + height: 1rem; + border: 1px solid #f4f4f4; + margin: .125rem .125rem .125rem .1875rem; + background-color: transparent; + border-radius: 1px; + content: ""; +} +label:has( > input[type=checkbox])::after { + position: absolute; + top: .5rem; + left: .4375rem; + width: .5625rem; + height: .3125rem; + border-bottom: 2px solid #161616; + border-left: 2px solid #161616; + margin-top: -.1875rem; + background: none; + content: ""; + transform: scale(0) rotate(-45deg); + transform-origin: bottom right; +} +#rememberMe, #logout-sessions { + position: absolute; + overflow: hidden; + width: 1px; + height: 1px; + padding: 0; + border: 0; + margin: -1px; + clip: rect(0,0,0,0); + visibility: inherit; + white-space: nowrap; + top: 1.25rem; + left: .7rem; +} + +/* hack to align forgot password with remember me */ +/* .form-group.login-pf-settings div span a { */ +a[tabindex="5"] { + margin-top: 12px; + margin-bottom: 20px; + display: block; +} + +/* additional providers styling */ +.kc-social-section hr { + border-top: 1px solid #393939; +} + +.kc-social-item { + text-align: left; +} + +.kc-social-links li { + width: 100%; + margin-bottom: 10px; +} + +.pf-c-button.pf-m-block { + display: block; + width: 100%; +} + +.pf-c-button::after { + border: 1px solid transparent; + /*display: none;*/ +} + +.pf-c-button.kc-social-item { + background-color: transparent; + color: #ffffff; + border-width: 1px; + border-style: solid; + border-color: #ffffff; + text-decoration: none; + outline: none; + font-size: 14px; + line-height: 18px; + letter-spacing: 0.16px; + font-weight: 300; + padding: 13px 10px 13px 10px; +} + +.pf-c-button.kc-social-item:focus { + background-color: #ffffff; + color: #161616; + border-color: #fff; + box-shadow: inset 0 0 0 1px #fff,inset 0 0 0 2px #161616; +} + +.pf-c-button.kc-social-item:hover { + background-color: #ffffff; + color: #161616; + border-width: 1px; + border-style: solid; + border-color: transparent; +} + +.pf-c-button.kc-social-item:active { + background-color: #6f6f6f; + border-width: 1px; + border-style: solid; + border-color: transparent; +} + +#kc-social-providers h4, #kc-social-providers h2 { + font-size: 12px; + line-height: 16px; + letter-spacing: .32px; + color: #c6c6c6; + font-weight: 400; +} + +.kc-social-provider-logo { + display: none; + font-size: 23px; + width: 30px; + height: 25px; + /* float: left; didn't work */ + position: absolute; + left: 15px; +} + +a:visited,:active { + text-decoration:none; +} + +/* Warning dialog - required for set new password */ +.alert-warning.pf-c-alert.pf-m-inline.pf-m-warning { + background: #262626; + border-left: 3px solid #f1c21b; + border-top: none; + height: 66px; +} + +.alert-warning.pf-c-alert.pf-m-inline.pf-m-warning .pf-c-alert__icon { + color: #f1c21b; + font-size: .875rem; + font-weight: 600; + line-height: 1.28572; + letter-spacing: .16px; + margin: 0 .25rem 0 0; +} + +.pf-c-alert__title.kc-feedback-text { + color: #f4f4f4; + font-size: 14px; + font-weight: 200; + line-height: 18px; + letter-spacing: .16px; + margin: 0 .25rem 0 0; +} + +/* error dialog */ +.alert-error.pf-c-alert.pf-m-inline.pf-m-danger { + background: #262626; + color: #f4f4f4; + border-left: 3px solid #da1e28; + border-top: none; + font-size: 14px; + font-weight: 200; + line-height: 18px; + letter-spacing: .16px; + margin: 0 .25rem 0 0; +} + +/* infor alert */ +.alert-info.pf-c-alert.pf-m-inline.pf-m-info { + background: #262626; + color: #f4f4f4; + border-left: 3px solid #4589ff; + border-top: none; + font-size: 14px; + font-weight: 200; + line-height: 18px; + letter-spacing: .16px; + margin: 0 .25rem 0 0; +} + +#kc-form-options .checkbox { + margin-bottom: 20px; +} + +#kc-attempted-username { + line-height: 40px; + letter-spacing: 0; + color: #f4f4f4; + font-size: 32px; + text-align: left; + margin: 0px; +} diff --git a/hack/keycloak-themes/theme/cloudpak/login/resources/fonts/IBMPlexSans-Regular.woff b/hack/keycloak-themes/theme/cloudpak/login/resources/fonts/IBMPlexSans-Regular.woff new file mode 100644 index 000000000..93ea3b5c9 Binary files /dev/null and b/hack/keycloak-themes/theme/cloudpak/login/resources/fonts/IBMPlexSans-Regular.woff differ diff --git a/hack/keycloak-themes/theme/cloudpak/login/resources/fonts/IBMPlexSans-Regular.woff2 b/hack/keycloak-themes/theme/cloudpak/login/resources/fonts/IBMPlexSans-Regular.woff2 new file mode 100644 index 000000000..231a1ad71 Binary files /dev/null and b/hack/keycloak-themes/theme/cloudpak/login/resources/fonts/IBMPlexSans-Regular.woff2 differ diff --git a/hack/keycloak-themes/theme/cloudpak/login/resources/img/favicon.ico b/hack/keycloak-themes/theme/cloudpak/login/resources/img/favicon.ico new file mode 100644 index 000000000..6a761d73f Binary files /dev/null and b/hack/keycloak-themes/theme/cloudpak/login/resources/img/favicon.ico differ diff --git a/hack/keycloak-themes/theme/cloudpak/login/resources/img/login-header.svg b/hack/keycloak-themes/theme/cloudpak/login/resources/img/login-header.svg new file mode 100644 index 000000000..d46c07864 --- /dev/null +++ b/hack/keycloak-themes/theme/cloudpak/login/resources/img/login-header.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hack/keycloak-themes/theme/cloudpak/login/resources/img/view--off.svg b/hack/keycloak-themes/theme/cloudpak/login/resources/img/view--off.svg new file mode 100644 index 000000000..0d9456fa3 --- /dev/null +++ b/hack/keycloak-themes/theme/cloudpak/login/resources/img/view--off.svg @@ -0,0 +1 @@ +view--off \ No newline at end of file diff --git a/hack/keycloak-themes/theme/cloudpak/login/resources/img/view.svg b/hack/keycloak-themes/theme/cloudpak/login/resources/img/view.svg new file mode 100644 index 000000000..f039a96eb --- /dev/null +++ b/hack/keycloak-themes/theme/cloudpak/login/resources/img/view.svg @@ -0,0 +1 @@ +view \ No newline at end of file diff --git a/hack/keycloak-themes/theme/cloudpak/login/theme.properties b/hack/keycloak-themes/theme/cloudpak/login/theme.properties new file mode 100755 index 000000000..26d1244d6 --- /dev/null +++ b/hack/keycloak-themes/theme/cloudpak/login/theme.properties @@ -0,0 +1,5 @@ +parent=keycloak +import=common/keycloak + +styles=css/styles4100.css +locales=en,de,es,fr,it,ja,ko,pt_BR,zh_CN,zh_TW \ No newline at end of file diff --git a/helm-cluster-scoped/Chart.yaml b/helm-cluster-scoped/Chart.yaml new file mode 100644 index 000000000..34a3329ee --- /dev/null +++ b/helm-cluster-scoped/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: ibm-common-service-operator-cluster-scoped +description: A Helm chart for ibm-common-service-operator +type: application +version: 4.11.0 +appVersion: 4.11.0 \ No newline at end of file diff --git a/helm-cluster-scoped/templates/cluster-rbac.yaml b/helm-cluster-scoped/templates/cluster-rbac.yaml new file mode 100644 index 000000000..52c08677c --- /dev/null +++ b/helm-cluster-scoped/templates/cluster-rbac.yaml @@ -0,0 +1,93 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: ibm-common-service-operator +rules: + - apiGroups: + - "" + resourceNames: + - common-service-maps + resources: + - configmaps + verbs: + - delete + - update + - apiGroups: + - "" + resourceNames: + - cloud-native-postgresql-image-list + resources: + - configmaps + verbs: + - delete + - apiGroups: + - "" + resources: + - configmaps + verbs: + - create + - get + - list + - watch + - update + - apiGroups: + - "" + resources: + - secrets + verbs: + - get + - apiGroups: + - storage.k8s.io + resources: + - storageclasses + verbs: + - get + - list + - watch + - apiGroups: + - admissionregistration.k8s.io + resources: + - mutatingwebhookconfigurations + - validatingwebhookconfigurations + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - config.openshift.io + resources: + - infrastructures + verbs: + - get + - apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + - clusterroles + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: ibm-common-service-operator +roleRef: + kind: ClusterRole + apiGroup: rbac.authorization.k8s.io + name: ibm-common-service-operator +subjects: + - kind: ServiceAccount + name: ibm-common-service-operator + namespace: {{ .Values.global.operatorNamespace }} + +--- diff --git a/helm-cluster-scoped/templates/cluster-webhook.yaml b/helm-cluster-scoped/templates/cluster-webhook.yaml new file mode 100644 index 000000000..e69de29bb diff --git a/helm-cluster-scoped/templates/crd.yaml b/helm-cluster-scoped/templates/crd.yaml new file mode 100644 index 000000000..d5c69ecf8 --- /dev/null +++ b/helm-cluster-scoped/templates/crd.yaml @@ -0,0 +1,348 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + app.kubernetes.io/instance: ibm-common-service-operator + app.kubernetes.io/managed-by: ibm-common-service-operator + app.kubernetes.io/name: ibm-common-service-operator + foundationservices.cloudpak.ibm.com: crd + name: commonservices.operator.ibm.com +spec: + group: operator.ibm.com + names: + kind: CommonService + listKind: CommonServiceList + plural: commonservices + singular: commonservice + scope: Namespaced + versions: + - name: v3 + schema: + openAPIV3Schema: + description: |- + CommonService is the Schema for the commonservices API. This API is used to + configure general foundational services configurations, such as sizing, + catalogsource, etc. See description of fields for more details. An instance + of this CRD is automatically created by the ibm-common-service-operator upon + installation to trigger the installation of critical installer components + such as operand-deployment-lifecycle-manager (ODLM), which is required to + further install other services from foundational services, such as IM. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: CommonServiceSpec defines the desired state of CommonService + properties: + BYOCACertificate: + description: |- + BYOCACertificate enables the option to replace the cs-ca-certificate with + your own CA certificate + type: boolean + catalogName: + description: |- + CatalogName is the name of the CatalogSource that will be used for ODLM + and other services in foundational services + type: string + catalogNamespace: + description: |- + CatalogNamespace is the namespace of the CatalogSource that will be used + for ODLM and other services in foundational services + type: string + defaultAdminUser: + description: |- + DefalutAdminUser is the name of the default admin user for foundational + services IM, default is cpadmin + type: string + enableInstanaMetricCollection: + type: boolean + features: + description: Features defines the configurations of Cloud Pak Services + properties: + apiCatalog: + description: APICatalog defines the configuration of APICatalog + properties: + storageClass: + type: string + type: object + bedrockshim: + description: Bedrockshim defines the configuration of Bedrockshim + properties: + crossplaneProviderRemoval: + type: boolean + enabled: + type: boolean + type: object + type: object + fipsEnabled: + description: FipsEnabled enables FIPS mode for foundational services + type: boolean + hugepages: + description: HugePages describes the hugepages settings for foundational + services + properties: + enable: + description: HugePagesEnabled enables hugepages settings for foundational + services + type: boolean + type: object + x-kubernetes-preserve-unknown-fields: true + installPlanApproval: + description: |- + InstallPlanApproval sets the approval mode for ODLM and other + foundational services: Manual or Automatic + type: string + labels: + additionalProperties: + type: string + description: |- + Labels describes foundational services will use this + labels to labels their corresponding resources + type: object + license: + description: LicenseList defines the license specification in CSV + properties: + accept: + description: 'Accepting the license - URL: https://ibm.biz/icpfs39license' + type: boolean + key: + description: The license key for this deployment. + type: string + license: + description: The license being accepted where the component has + multiple. + type: string + use: + description: The type of license being accepted. + type: string + type: object + manualManagement: + type: boolean + operatorConfigs: + description: OperatorConfigs is a list of configurations to be applied + to operators via CSV updates + items: + description: OperatorConfig is configuration composed of key-value + pairs to be injected into specified CSVs + properties: + name: + description: Name is the name of the operator as requested in + an OperandRequest + type: string + replicas: + description: |- + Number of desired pods. This is a pointer to distinguish between explicit + 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 + operatorNamespace: + description: |- + OperatorNamespace describes the namespace where operators will be + installed in such as ODLM. This will also apply to all services in + foundational services, e.g. ODLM will install IM operator in this + namespace + type: string + profileController: + description: |- + ProfileController enables turbonomic to automatically handle sizing of + foundational services. Default value is 'default' + type: string + routeHost: + description: |- + RouteHost describes the hostname for the foundational services route, + and can only be configured pre-installation of IM + type: string + services: + description: |- + Services describes the CPU, memory, and replica configuration for + individual services in foundational services + items: + properties: + managementStrategy: + type: string + name: + type: string + resources: + items: + type: object + x-kubernetes-preserve-unknown-fields: true + type: array + spec: + additionalProperties: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + required: + - name + type: object + x-kubernetes-preserve-unknown-fields: true + type: array + servicesNamespace: + description: |- + ServicesNamespace describes the namespace where operands will be created + in such as OperandRegistry and OperandConfig. This will also apply to all + services in foundational services, e.g. IM will create operands in this + namespace + type: string + size: + description: |- + Size describes the T-shirt size of foundational services: starterset, + small, medium, or large + type: string + storageClass: + description: |- + StorageClass describes the storage class to use for the foundational + services PVCs + type: string + type: object + x-kubernetes-preserve-unknown-fields: true + status: + description: CommonServiceStatus defines the observed state of CommonService + properties: + bedrockOperators: + items: + description: BedrockOperator describes a list of foundational services' + operators currently installed for this tenant. + properties: + installPlanName: + type: string + name: + type: string + operatorStatus: + type: string + subscriptionStatus: + type: string + troubleshooting: + type: string + version: + type: string + type: object + type: array + conditions: + description: Conditions represents the current state of CommonService + items: + description: CommonServiceCondition defines the observed condition + of CommonService + properties: + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + type: string + lastUpdateTime: + description: The last time this condition was updated. + type: string + message: + description: A human readable message indicating details about + the transition. + type: string + reason: + description: The reason for the condition's last transition. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type of condition. + type: string + type: object + type: array + configStatus: + description: ConfigStatus describes various configuration currently + applied onto the foundational services installer. + properties: + catalogName: + description: CatalogName is the name of the CatalogSource foundational + services is using + type: string + catalogNamespace: + description: CatalogNamespace is the namesapce of the CatalogSource + type: string + configurable: + description: |- + Configurable indicates whether this CommonService CR is the one + that can be used to configure the foundational services' installer. Other + CommonService CRs configurations will not take effect, except for sizing + type: boolean + operatorDeployed: + description: |- + OperatorDeployed indicates whether the OperandRegistry has been created + or not. + type: boolean + operatorNamespace: + description: |- + OperatorNamespace is the namespace of where the foundational services' + operators will be installed in. + type: string + servicesDeployed: + description: |- + ServicesDeployed indicates whether the OperandConfig has been created or + not. + type: boolean + servicesNamespace: + description: |- + ServicesNamespace is the namespace where the foundational services' + operands will be created in. + type: string + topologyConfigurableCRs: + description: TopologyConfigurableCRs describes the configurable + CommonService CR + items: + properties: + apiVersion: + description: ApiVersion is the api version of the configurable + CommonService CR + type: string + kind: + description: Kind is the kind of the configurable CommonService + CR + type: string + namespace: + description: Namespace is the namespace of the configurable + CommonService CR + type: string + objectName: + description: ObjectName is the name of the configurable + CommonService CR + type: string + type: object + type: array + type: object + overallStatus: + description: OverallStatus describes whether the Installation for + the foundational services has succeeded or not + type: string + phase: + description: Phase describes the phase of the overall installation + type: string + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: true + subresources: + status: {} diff --git a/helm-cluster-scoped/values.yaml b/helm-cluster-scoped/values.yaml new file mode 100644 index 000000000..ab9af7843 --- /dev/null +++ b/helm-cluster-scoped/values.yaml @@ -0,0 +1,11 @@ +# Note there are no leading or trailing /'s +imageRegistryNamespaceOperator: cpopen +imageRegistryNamespaceOperand: cpopen/cpfs + +#Commented out values are covered by a global values file +# imagePullPrefix: icr.io +# imagePullSecret: ibm-entitlement-key +# other configuration you think you might need for your operator +# following are examples, not required: +# operatorNamespace: "" +# servicesNamespace: "" diff --git a/helm/Chart.yaml b/helm/Chart.yaml new file mode 100644 index 000000000..ca328a208 --- /dev/null +++ b/helm/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: ibm-common-service-operator +description: A Helm chart for ibm-common-service-operator +type: application +version: 4.11.0 +appVersion: 4.11.0 \ No newline at end of file diff --git a/helm/templates/cr.yaml b/helm/templates/cr.yaml new file mode 100644 index 000000000..2ee4ea696 --- /dev/null +++ b/helm/templates/cr.yaml @@ -0,0 +1,16 @@ +apiVersion: operator.ibm.com/v3 +kind: CommonService +metadata: + annotations: + version: '-1' + name: common-service + namespace: {{ .Values.global.operatorNamespace }} + labels: + foundationservices.cloudpak.ibm.com: commonservice +spec: + license: + accept: {{ .Values.global.licenseAccept }} + operatorNamespace: {{ .Values.global.operatorNamespace }} + servicesNamespace: {{ .Values.global.instanceNamespace }} + size: {{ .Values.commonServiceSpec.size }} + storageClass: {{ .Values.global.blockStorageClass }} \ No newline at end of file diff --git a/helm/templates/operator-deployment.yaml b/helm/templates/operator-deployment.yaml new file mode 100644 index 000000000..eb852875b --- /dev/null +++ b/helm/templates/operator-deployment.yaml @@ -0,0 +1,98 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ibm-common-service-operator + namespace: {{ .Values.global.operatorNamespace }} +spec: + replicas: 1 + selector: + matchLabels: + name: ibm-common-service-operator + strategy: + type: Recreate + template: + metadata: + annotations: + productID: 068a62892a1e4db39641342e592daa25 + productMetric: FREE + productName: IBM Cloud Platform Common Services + labels: + app.kubernetes.io/instance: ibm-common-service-operator + app.kubernetes.io/managed-by: ibm-common-service-operator + app.kubernetes.io/name: ibm-common-service-operator + name: ibm-common-service-operator + intent: projected + productName: IBM_Cloud_Platform_Common_Services + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/arch + operator: In + values: + - amd64 + - ppc64le + - s390x + containers: + - name: ibm-common-service-operator + image: {{ .Values.global.imagePullPrefix}}/{{ .Values.imageRegistryNamespaceOperator}}/common-service-operator:4.11.0 + command: + - /manager + env: + - name: OPERATOR_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: WATCH_NAMESPACE + valueFrom: + configMapKeyRef: + key: namespaces + name: namespace-scope + - name: NO_OLM + value: "true" + - name: ENABLE_WEBHOOKS + value: "false" + - name: OPERATOR_NAME + value: ibm-common-service-operator + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 10 + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 120 + periodSeconds: 60 + timeoutSeconds: 10 + readinessProbe: + failureThreshold: 10 + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 20 + timeoutSeconds: 20 + resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 100m + ephemeral-storage: 256Mi + memory: 200Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + imagePullSecrets: + - name: {{ .Values.global.imagePullSecret }} + serviceAccountName: ibm-common-service-operator + terminationGracePeriodSeconds: 10 diff --git a/helm/templates/rbac.yaml b/helm/templates/rbac.yaml new file mode 100644 index 000000000..06363575e --- /dev/null +++ b/helm/templates/rbac.yaml @@ -0,0 +1,211 @@ +# Generated by [Kustohelmize](https://github.com/yeahdongcn/kustohelmize) +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: ibm-common-service-operator + namespace: {{ .Values.global.operatorNamespace }} +roleRef: + kind: Role + apiGroup: rbac.authorization.k8s.io + name: ibm-common-service-operator +subjects: + - kind: ServiceAccount + name: ibm-common-service-operator + namespace: {{ .Values.global.operatorNamespace }} +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: ibm-common-service-operator + namespace: {{ .Values.global.operatorNamespace }} +rules: + - apiGroups: + - "" + resources: + - configmaps + verbs: + - delete + - patch + - apiGroups: + - operator.ibm.com + resources: + - namespacescopes + verbs: + - create + - delete + - get + - list + - watch + - patch + - apiGroups: + - cert-manager.io + resources: + - certificates + - issuers + verbs: + - create + - delete + - get + - list + - watch + - apiGroups: + - apps + resources: + - deployments + - statefulsets + - daemonsets + verbs: + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - operator.ibm.com + resources: + - commonservices + - commonservices/finalizers + - commonservices/status + - operandconfigs + - operandregistries + - operatorconfigs + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - operators.coreos.com + resources: + - subscriptions + - clusterserviceversions + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - "" + resources: + - namespaces + verbs: + - get + - apiGroups: + - "" + resources: + - pods + verbs: + - get + - list + - delete + - apiGroups: + - "" + resources: + - secrets + - services + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - "" + resources: + - events + verbs: + - create + - get + - patch + - update + - apiGroups: + - certmanager.k8s.io + resources: + - certificates + - issuers + verbs: + - delete + - apiGroups: + - monitoring.operator.ibm.com + resources: + - exporters + - prometheusexts + verbs: + - delete + - apiGroups: + - operator.ibm.com + resources: + - operandrequests + - operandbindinfos + - cataloguis + - helmapis + - helmrepos + verbs: + - delete + - apiGroups: + - elasticstack.ibm.com + resources: + - elasticstacks + verbs: + - delete + - apiGroups: + - "" + resources: + - serviceaccounts + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - rbac.authorization.k8s.io + resources: + - rolebindings + - roles + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - operator.ibm.com + resources: + - podpresets + verbs: + - get + - delete + - list + - apiGroups: + - ibmcpcs.ibm.com + resources: + - secretshares + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: ibm-common-service-operator + namespace: {{ .Values.global.operatorNamespace }} diff --git a/helm/values.yaml b/helm/values.yaml new file mode 100644 index 000000000..239f1d639 --- /dev/null +++ b/helm/values.yaml @@ -0,0 +1,19 @@ +# Note there are no leading or trailing /'s +imageRegistryNamespaceOperator: cpopen +imageRegistryNamespaceOperand: cpopen/cpfs + +# Commented out values are handled by a global values file +# imagePullPrefix: icr.io +# imagePullSecret: ibm-entitlement-key + +# other configuration you think you might need for your operator +# following are examples, not required: +# operatorNamespace: "" +# servicesNamespace: "" + +# CR configurations + +commonServiceSpec: + # license: + # accept: false + size: starterset diff --git a/main.go b/main.go index 9e4a8126e..0c5124c4b 100644 --- a/main.go +++ b/main.go @@ -24,6 +24,7 @@ import ( olmv1 "github.com/operator-framework/api/pkg/operators/v1" olmv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1" operatorsv1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1" + admv1 "k8s.io/api/admissionregistration/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" @@ -37,22 +38,21 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log/zap" "github.com/IBM/controller-filtered-cache/filteredcache" - nssv1 "github.com/IBM/ibm-namespace-scope-operator/api/v1" + nssv1 "github.com/IBM/ibm-namespace-scope-operator/v4/api/v1" ssv1 "github.com/IBM/ibm-secretshare-operator/api/v1" - odlm "github.com/IBM/operand-deployment-lifecycle-manager/api/v1alpha1" + odlm "github.com/IBM/operand-deployment-lifecycle-manager/v4/api/v1alpha1" certmanagerv1 "github.com/ibm/ibm-cert-manager-operator/apis/cert-manager/v1" - cmconstants "github.com/ibm/ibm-cert-manager-operator/controllers/resources" - - operatorv3 "github.com/IBM/ibm-common-service-operator/api/v3" - "github.com/IBM/ibm-common-service-operator/controllers" - "github.com/IBM/ibm-common-service-operator/controllers/bootstrap" - certmanagerv1controllers "github.com/IBM/ibm-common-service-operator/controllers/cert-manager" - util "github.com/IBM/ibm-common-service-operator/controllers/common" - "github.com/IBM/ibm-common-service-operator/controllers/constant" - "github.com/IBM/ibm-common-service-operator/controllers/goroutines" - commonservicewebhook "github.com/IBM/ibm-common-service-operator/controllers/webhooks/commonservice" - operandrequestwebhook "github.com/IBM/ibm-common-service-operator/controllers/webhooks/operandrequest" + + operatorv3 "github.com/IBM/ibm-common-service-operator/v4/api/v3" + "github.com/IBM/ibm-common-service-operator/v4/controllers" + "github.com/IBM/ibm-common-service-operator/v4/controllers/bootstrap" + certmanagerv1controllers "github.com/IBM/ibm-common-service-operator/v4/controllers/cert-manager" + util "github.com/IBM/ibm-common-service-operator/v4/controllers/common" + "github.com/IBM/ibm-common-service-operator/v4/controllers/constant" + "github.com/IBM/ibm-common-service-operator/v4/controllers/goroutines" + commonservicewebhook "github.com/IBM/ibm-common-service-operator/v4/controllers/webhooks/commonservice" + operandrequestwebhook "github.com/IBM/ibm-common-service-operator/v4/controllers/webhooks/operandrequest" // +kubebuilder:scaffold:imports ) @@ -67,6 +67,7 @@ func init() { utilruntime.Must(nssv1.AddToScheme(scheme)) utilruntime.Must(ssv1.AddToScheme(scheme)) utilruntime.Must(operatorv3.AddToScheme(scheme)) + utilruntime.Must(admv1.AddToScheme(scheme)) // +kubebuilder:scaffold:scheme utilruntime.Must(olmv1alpha1.AddToScheme(scheme)) @@ -100,7 +101,7 @@ func main() { LabelSelector: constant.CsManagedLabel, }, corev1.SchemeGroupVersion.WithKind("Secret"): { - LabelSelector: cmconstants.SecretWatchLabel, + LabelSelector: constant.SecretWatchLabel, }, } clusterGVKList := []schema.GroupVersionKind{ @@ -141,7 +142,6 @@ func main() { // If Common Service Operator Namespace is not in the same as .spec.operatorNamespace(cpfsNs) in default CS CR, // this Common Service Operator is not in the operatorNamespace(cpfsNs) under this tenant, and goes dormant. if operatorNs == cpfsNs { - // New bootstrap Object bs, err := bootstrap.NewBootstrap(mgr) if err != nil { @@ -153,13 +153,8 @@ func main() { klog.Errorf("Cleanup Webhook Resources failed: %v", err) os.Exit(1) } - // Create or Update CPP configuration - go goroutines.CreateUpdateConfig(bs) - // Update CS CR Status - go goroutines.UpdateCsCrStatus(bs) - // Create CS CR - go goroutines.WaitToCreateCsCR(bs) + klog.Infof("Setup commonservice manager") if err = (&controllers.CommonServiceReconciler{ Bootstrap: bs, Scheme: mgr.GetScheme(), @@ -168,26 +163,52 @@ func main() { klog.Errorf("Unable to create controller CommonService: %v", err) os.Exit(1) } - if err = (&certmanagerv1controllers.CertificateRefreshReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - }).SetupWithManager(mgr); err != nil { - klog.Error(err, "unable to create controller", "controller", "CertificateRefresh") - os.Exit(1) + + klog.Infof("Start go routines") + if os.Getenv("NO_OLM") != "true" { + // Update CS CR Status + go goroutines.UpdateCsCrStatus(bs) + } else { + // Update CS CR Status + go goroutines.UpdateNoOLMCsCrStatus(bs) } - if err = (&certmanagerv1controllers.PodRefreshReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - }).SetupWithManager(mgr); err != nil { - klog.Error(err, "unable to create controller", "controller", "PodRefresh") + + // Create CS CR + go goroutines.WaitToCreateCsCR(bs) + // Delete Keycloak Cert + go goroutines.CleanupResources(bs) + + // check if cert-manager CRD does not exist, then skip cert-manager related controllers initialization + exist, err := bs.CheckCRD(constant.CertManagerAPIGroupVersionV1, "Certificate") + if err != nil { + klog.Errorf("Failed to check if cert-manager CRD exists: %v", err) os.Exit(1) } - if err = (&certmanagerv1controllers.V1AddLabelReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - }).SetupWithManager(mgr); err != nil { - klog.Error(err, "unable to create controller", "controller", "V1AddLabel") - os.Exit(1) + if !exist && err == nil { + klog.Infof("cert-manager CRD does not exist, skip cert-manager related controllers initialization") + } else if exist && err == nil { + + if err = (&certmanagerv1controllers.CertificateRefreshReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + klog.Error(err, "unable to create controller", "controller", "CertificateRefresh") + os.Exit(1) + } + if err = (&certmanagerv1controllers.PodRefreshReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + klog.Error(err, "unable to create controller", "controller", "PodRefresh") + os.Exit(1) + } + if err = (&certmanagerv1controllers.V1AddLabelReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + klog.Error(err, "unable to create controller", "controller", "V1AddLabel") + os.Exit(1) + } } } else { klog.Infof("Common Service Operator goes dormant in the namespace %s", operatorNs) diff --git a/testdata/actual.yaml b/testdata/actual.yaml index e8a282f4e..6d4c92dc4 100644 --- a/testdata/actual.yaml +++ b/testdata/actual.yaml @@ -189,6 +189,102 @@ } } }, + { + "name": "ibm-idp-config-ui-operator-v4.3", + "spec": { + "commonWebUI": { + "commonWebUIConfig": { + "dashboardData": { + "resources": { + "limits": { + "cpu": "3000m", + "memory": "600Mi" + }, + "requests": { + "cpu": "390m", + "memory": "380Mi" + } + } + } + }, + "replicas": 3, + "resources": { + "limits": { + "cpu": "1000m", + "memory": "660Mi" + }, + "requests": { + "cpu": "450m", + "memory": "490Mi" + } + } + } + } + }, + { + "name": "ibm-idp-config-ui-operator-v4.4", + "spec": { + "commonWebUI": { + "commonWebUIConfig": { + "dashboardData": { + "resources": { + "limits": { + "cpu": "3000m", + "memory": "600Mi" + }, + "requests": { + "cpu": "390m", + "memory": "380Mi" + } + } + } + }, + "replicas": 3, + "resources": { + "limits": { + "cpu": "1000m", + "memory": "660Mi" + }, + "requests": { + "cpu": "450m", + "memory": "490Mi" + } + } + } + } + }, + { + "name": "ibm-idp-config-ui-operator-v4.5", + "spec": { + "commonWebUI": { + "commonWebUIConfig": { + "dashboardData": { + "resources": { + "limits": { + "cpu": "3000m", + "memory": "600Mi" + }, + "requests": { + "cpu": "390m", + "memory": "380Mi" + } + } + } + }, + "replicas": 3, + "resources": { + "limits": { + "cpu": "1000m", + "memory": "660Mi" + }, + "requests": { + "cpu": "450m", + "memory": "490Mi" + } + } + } + } + }, { "name": "ibm-idp-config-ui-operator", "spec": { @@ -710,6 +806,278 @@ } } }, + { + "name": "ibm-im-operator-v4.3", + "spec": { + "authentication": { + "authService": { + "resources": { + "limits": { + "cpu": "2000m", + "memory": "1090Mi" + }, + "requests": { + "cpu": "400m", + "memory": "540Mi" + } + } + }, + "clientRegistration": { + "resources": { + "limits": { + "cpu": "1000m", + "memory": "50Mi" + }, + "requests": { + "cpu": "20m", + "memory": "50Mi" + } + } + }, + "identityManager": { + "resources": { + "limits": { + "cpu": "1000m", + "memory": "1270Mi" + }, + "requests": { + "cpu": "260m", + "memory": "210Mi" + } + } + }, + "identityProvider": { + "resources": { + "limits": { + "cpu": "1000m", + "memory": "920Mi" + }, + "requests": { + "cpu": "570m", + "memory": "210Mi" + } + } + }, + "initMongodb": { + "resources": { + "limits": { + "cpu": "100m", + "memory": "128Mi" + }, + "requests": { + "cpu": "100m", + "memory": "128Mi" + } + } + }, + "replicas": 3 + } + } + }, + { + "name": "ibm-im-operator-v4.4", + "spec": { + "authentication": { + "authService": { + "resources": { + "limits": { + "cpu": "2000m", + "memory": "1090Mi" + }, + "requests": { + "cpu": "400m", + "memory": "540Mi" + } + } + }, + "clientRegistration": { + "resources": { + "limits": { + "cpu": "1000m", + "memory": "50Mi" + }, + "requests": { + "cpu": "20m", + "memory": "50Mi" + } + } + }, + "identityManager": { + "resources": { + "limits": { + "cpu": "1000m", + "memory": "1270Mi" + }, + "requests": { + "cpu": "260m", + "memory": "210Mi" + } + } + }, + "identityProvider": { + "resources": { + "limits": { + "cpu": "1000m", + "memory": "920Mi" + }, + "requests": { + "cpu": "570m", + "memory": "210Mi" + } + } + }, + "initMongodb": { + "resources": { + "limits": { + "cpu": "100m", + "memory": "128Mi" + }, + "requests": { + "cpu": "100m", + "memory": "128Mi" + } + } + }, + "replicas": 3 + } + } + }, + { + "name": "ibm-im-operator-v4.5", + "spec": { + "authentication": { + "authService": { + "resources": { + "limits": { + "cpu": "2000m", + "memory": "1090Mi" + }, + "requests": { + "cpu": "400m", + "memory": "540Mi" + } + } + }, + "clientRegistration": { + "resources": { + "limits": { + "cpu": "1000m", + "memory": "50Mi" + }, + "requests": { + "cpu": "20m", + "memory": "50Mi" + } + } + }, + "identityManager": { + "resources": { + "limits": { + "cpu": "1000m", + "memory": "1270Mi" + }, + "requests": { + "cpu": "260m", + "memory": "210Mi" + } + } + }, + "identityProvider": { + "resources": { + "limits": { + "cpu": "1000m", + "memory": "920Mi" + }, + "requests": { + "cpu": "570m", + "memory": "210Mi" + } + } + }, + "initMongodb": { + "resources": { + "limits": { + "cpu": "100m", + "memory": "128Mi" + }, + "requests": { + "cpu": "100m", + "memory": "128Mi" + } + } + }, + "replicas": 3 + } + } + }, + { + "name": "ibm-im-operator-v4.6", + "spec": { + "authentication": { + "authService": { + "resources": { + "limits": { + "cpu": "2000m", + "memory": "1090Mi" + }, + "requests": { + "cpu": "400m", + "memory": "540Mi" + } + } + }, + "clientRegistration": { + "resources": { + "limits": { + "cpu": "1000m", + "memory": "50Mi" + }, + "requests": { + "cpu": "20m", + "memory": "50Mi" + } + } + }, + "identityManager": { + "resources": { + "limits": { + "cpu": "1000m", + "memory": "1270Mi" + }, + "requests": { + "cpu": "260m", + "memory": "210Mi" + } + } + }, + "identityProvider": { + "resources": { + "limits": { + "cpu": "1000m", + "memory": "920Mi" + }, + "requests": { + "cpu": "570m", + "memory": "210Mi" + } + } + }, + "initMongodb": { + "resources": { + "limits": { + "cpu": "100m", + "memory": "128Mi" + }, + "requests": { + "cpu": "100m", + "memory": "128Mi" + } + } + }, + "replicas": 3 + } + } + }, { "name": "ibm-ingress-nginx-operator", "spec": { diff --git a/testdata/deploy/deploy.yaml b/testdata/deploy/deploy.yaml index eafb945ac..1aa890db2 100644 --- a/testdata/deploy/deploy.yaml +++ b/testdata/deploy/deploy.yaml @@ -15,52 +15,47 @@ spec: name: ibm-common-service-operator annotations: description: The IBM Common Service Operator is used to deploy IBM Common Services - operatorChannel: v4.3 - operatorVersion: 4.3.1 + operatorChannel: v4.11 + operatorVersion: 4.11.0 + cloudPakThemesVersion: styles4100.css spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - - matchExpressions: - - key: kubernetes.io/arch - operator: In - values: - - amd64 - - ppc64le - - s390x + - matchExpressions: + - key: kubernetes.io/arch + operator: In + values: + - amd64 + - ppc64le + - s390x containers: - - command: - - /manager - env: - - name: OPERATOR_NAME - value: ibm-common-service-operator - - name: IBM_CS_WEBHOOK_IMAGE - value: icr.io/cpopen/cpfs/ibm-cs-webhook:1.18.0 - - name: IBM_SECRETSHARE_OPERATOR_IMAGE - value: icr.io/cpopen/cpfs/ibm-secretshare-operator:1.19.0 - - name: IBM_ZEN_OPERATOR_IMAGE - value: icr.io/cpopen/ibm-zen-operator:1.7.0 - image: siji/operator:cs - imagePullPolicy: IfNotPresent - name: ibm-common-service-operator - resources: - limits: - cpu: 500m - memory: 512Mi - requests: - cpu: 100m - memory: 200Mi - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - privileged: false - readOnlyRootFilesystem: true - runAsNonRoot: true - terminationMessagePath: /dev/termination-log - terminationMessagePolicy: File + - command: + - /manager + env: + - name: OPERATOR_NAME + value: ibm-common-service-operator + image: siji/operator:cs + imagePullPolicy: IfNotPresent + name: ibm-common-service-operator + resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 100m + memory: 200Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + readOnlyRootFilesystem: true + runAsNonRoot: true + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File dnsPolicy: ClusterFirst restartPolicy: Always schedulerName: default-scheduler diff --git a/testdata/expected.yaml b/testdata/expected.yaml index 98ae728e4..a7d07a265 100644 --- a/testdata/expected.yaml +++ b/testdata/expected.yaml @@ -189,6 +189,102 @@ } } }, + { + "name": "ibm-idp-config-ui-operator-v4.3", + "spec": { + "commonWebUI": { + "commonWebUIConfig": { + "dashboardData": { + "resources": { + "limits": { + "cpu": "3000m", + "memory": "600Mi" + }, + "requests": { + "cpu": "390m", + "memory": "380Mi" + } + } + } + }, + "replicas": 3, + "resources": { + "limits": { + "cpu": "1000m", + "memory": "660Mi" + }, + "requests": { + "cpu": "450m", + "memory": "490Mi" + } + } + } + } + }, + { + "name": "ibm-idp-config-ui-operator-v4.4", + "spec": { + "commonWebUI": { + "commonWebUIConfig": { + "dashboardData": { + "resources": { + "limits": { + "cpu": "3000m", + "memory": "600Mi" + }, + "requests": { + "cpu": "390m", + "memory": "380Mi" + } + } + } + }, + "replicas": 3, + "resources": { + "limits": { + "cpu": "1000m", + "memory": "660Mi" + }, + "requests": { + "cpu": "450m", + "memory": "490Mi" + } + } + } + } + }, + { + "name": "ibm-idp-config-ui-operator-v4.5", + "spec": { + "commonWebUI": { + "commonWebUIConfig": { + "dashboardData": { + "resources": { + "limits": { + "cpu": "3000m", + "memory": "600Mi" + }, + "requests": { + "cpu": "390m", + "memory": "380Mi" + } + } + } + }, + "replicas": 3, + "resources": { + "limits": { + "cpu": "1000m", + "memory": "660Mi" + }, + "requests": { + "cpu": "450m", + "memory": "490Mi" + } + } + } + } + }, { "name": " ibm-idp-config-ui-operator", "spec": { @@ -710,6 +806,278 @@ } } }, + { + "name": "ibm-im-operator-v4.3", + "spec": { + "authentication": { + "authService": { + "resources": { + "limits": { + "cpu": "2000m", + "memory": "1090Mi" + }, + "requests": { + "cpu": "400m", + "memory": "540Mi" + } + } + }, + "clientRegistration": { + "resources": { + "limits": { + "cpu": "1000m", + "memory": "50Mi" + }, + "requests": { + "cpu": "20m", + "memory": "50Mi" + } + } + }, + "identityManager": { + "resources": { + "limits": { + "cpu": "1000m", + "memory": "1270Mi" + }, + "requests": { + "cpu": "260m", + "memory": "210Mi" + } + } + }, + "identityProvider": { + "resources": { + "limits": { + "cpu": "1000m", + "memory": "920Mi" + }, + "requests": { + "cpu": "570m", + "memory": "210Mi" + } + } + }, + "initMongodb": { + "resources": { + "limits": { + "cpu": "100m", + "memory": "128Mi" + }, + "requests": { + "cpu": "100m", + "memory": "128Mi" + } + } + }, + "replicas": 3 + } + } + }, + { + "name": "ibm-im-operator-v4.4", + "spec": { + "authentication": { + "authService": { + "resources": { + "limits": { + "cpu": "2000m", + "memory": "1090Mi" + }, + "requests": { + "cpu": "400m", + "memory": "540Mi" + } + } + }, + "clientRegistration": { + "resources": { + "limits": { + "cpu": "1000m", + "memory": "50Mi" + }, + "requests": { + "cpu": "20m", + "memory": "50Mi" + } + } + }, + "identityManager": { + "resources": { + "limits": { + "cpu": "1000m", + "memory": "1270Mi" + }, + "requests": { + "cpu": "260m", + "memory": "210Mi" + } + } + }, + "identityProvider": { + "resources": { + "limits": { + "cpu": "1000m", + "memory": "920Mi" + }, + "requests": { + "cpu": "570m", + "memory": "210Mi" + } + } + }, + "initMongodb": { + "resources": { + "limits": { + "cpu": "100m", + "memory": "128Mi" + }, + "requests": { + "cpu": "100m", + "memory": "128Mi" + } + } + }, + "replicas": 3 + } + } + }, + { + "name": "ibm-im-operator-v4.5", + "spec": { + "authentication": { + "authService": { + "resources": { + "limits": { + "cpu": "2000m", + "memory": "1090Mi" + }, + "requests": { + "cpu": "400m", + "memory": "540Mi" + } + } + }, + "clientRegistration": { + "resources": { + "limits": { + "cpu": "1000m", + "memory": "50Mi" + }, + "requests": { + "cpu": "20m", + "memory": "50Mi" + } + } + }, + "identityManager": { + "resources": { + "limits": { + "cpu": "1000m", + "memory": "1270Mi" + }, + "requests": { + "cpu": "260m", + "memory": "210Mi" + } + } + }, + "identityProvider": { + "resources": { + "limits": { + "cpu": "1000m", + "memory": "920Mi" + }, + "requests": { + "cpu": "570m", + "memory": "210Mi" + } + } + }, + "initMongodb": { + "resources": { + "limits": { + "cpu": "100m", + "memory": "128Mi" + }, + "requests": { + "cpu": "100m", + "memory": "128Mi" + } + } + }, + "replicas": 3 + } + } + }, + { + "name": "ibm-im-operator-v4.6", + "spec": { + "authentication": { + "authService": { + "resources": { + "limits": { + "cpu": "2000m", + "memory": "1090Mi" + }, + "requests": { + "cpu": "400m", + "memory": "540Mi" + } + } + }, + "clientRegistration": { + "resources": { + "limits": { + "cpu": "1000m", + "memory": "50Mi" + }, + "requests": { + "cpu": "20m", + "memory": "50Mi" + } + } + }, + "identityManager": { + "resources": { + "limits": { + "cpu": "1000m", + "memory": "1270Mi" + }, + "requests": { + "cpu": "260m", + "memory": "210Mi" + } + } + }, + "identityProvider": { + "resources": { + "limits": { + "cpu": "1000m", + "memory": "920Mi" + }, + "requests": { + "cpu": "570m", + "memory": "210Mi" + } + } + }, + "initMongodb": { + "resources": { + "limits": { + "cpu": "100m", + "memory": "128Mi" + }, + "requests": { + "cpu": "100m", + "memory": "128Mi" + } + } + }, + "replicas": 3 + } + } + }, { "name": "ibm-ingress-nginx-operator", "spec": { diff --git a/version/version.go b/version/version.go index 58d53ca21..216404190 100644 --- a/version/version.go +++ b/version/version.go @@ -17,5 +17,5 @@ package version var ( - Version = "4.3.1" + Version = "4.11.0" )