├── .github ├── PULL_REQUEST_TEMPLATE.md ├── dependabot.yml └── workflows │ ├── cherry-pick.yaml │ └── ocp.yaml ├── .gitignore ├── Dockerfile ├── LICENSE ├── Makefile ├── OWNERS ├── PROJECT ├── README.md ├── api └── v3 │ ├── commonservice_types.go │ ├── finalizer.go │ ├── groupversion_info.go │ └── zz_generated.deepcopy.go ├── base_images.json ├── bedrock-migration ├── .helmignore ├── Chart.yaml ├── templates │ ├── bedrock-migration-job.yaml │ └── rbac.yaml └── values.yaml ├── bundle.Dockerfile ├── bundle ├── manifests │ ├── ibm-common-service-operator.clusterserviceversion.yaml │ ├── operator.ibm.com_commonservices.yaml │ └── webhook-service_v1_service.yaml ├── metadata │ └── annotations.yaml └── tests │ └── scorecard │ └── config.yaml ├── cmd └── main.go ├── common ├── Makefile.common.mk ├── config │ └── .golangci.yml └── scripts │ ├── .githooks │ ├── make_lint-all.sh │ └── pre-commit │ ├── artifactory_config_docker.sh │ ├── force-uninstall.sh │ ├── gobuild.sh │ ├── health-check.sh │ ├── install-operator-sdk.sh │ ├── lint-csv.sh │ ├── lint_copyright_banner.sh │ ├── lint_go.sh │ ├── multiarch_image.sh │ ├── next-csv.sh │ ├── patch_image.sh │ ├── quay_config_docker.sh │ ├── rollback_to_eus.sh │ ├── tests │ └── clear_ocp.sh │ ├── update_catalogsource.sh │ ├── upgrade_to_continuous_delivery.sh │ └── upgrade_to_continuous_delivery_airgap.sh ├── config ├── certmanager │ ├── certificate.yaml │ ├── kustomization.yaml │ └── kustomizeconfig.yaml ├── crd │ ├── bases │ │ └── operator.ibm.com_commonservices.yaml │ ├── kustomization.yaml │ ├── kustomizeconfig.yaml │ └── patches │ │ ├── cainjection_in_commonservices.yaml │ │ ├── label_in_commonservices.yaml │ │ └── webhook_in_commonservices.yaml ├── default │ ├── kustomization.yaml │ ├── manager_auth_proxy_patch.yaml │ ├── manager_webhook_patch.yaml │ └── webhookcainjection_patch.yaml ├── ibm-common-service-operator.yaml ├── manager │ ├── kustomization.yaml │ ├── manager.yaml │ └── non-olm-env-patch.yaml ├── manifests │ ├── bases │ │ └── ibm-common-service-operator.clusterserviceversion.yaml │ └── kustomization.yaml ├── prometheus │ ├── kustomization.yaml │ └── monitor.yaml ├── rbac │ ├── auth_proxy_client_clusterrole.yaml │ ├── auth_proxy_role.yaml │ ├── auth_proxy_role_binding.yaml │ ├── auth_proxy_service.yaml │ ├── commonservice_editor_role.yaml │ ├── commonservice_viewer_role.yaml │ ├── kustomization.yaml │ ├── leader_election_role.yaml │ ├── leader_election_role_binding.yaml │ ├── role.yaml │ ├── role_binding.yaml │ └── service_account.yaml ├── samples │ ├── kustomization.yaml │ └── operator_v3_commonservice.yaml ├── scorecard │ ├── bases │ │ └── config.yaml │ ├── kustomization.yaml │ └── patches │ │ ├── basic.config.yaml │ │ └── olm.config.yaml ├── service_account │ ├── kustomization.yaml │ └── service_account.yaml └── webhook │ ├── kustomization.yaml │ ├── kustomizeconfig.yaml │ ├── manifests.yaml │ └── service.yaml ├── docs ├── cloudpak-integration.md ├── design.md ├── images │ ├── create-catalog-source.png │ ├── create-project.png │ ├── install-operator.png │ ├── installed-operators.png │ ├── manage-operators.png │ └── search-operator.png ├── install-cli.md ├── install.md └── uninstall.md ├── go.mod ├── go.sum ├── hack ├── boilerplate.go.txt └── keycloak-themes │ ├── .gitignore │ ├── META-INF │ ├── MANIFEST.MF │ └── keycloak-themes.json │ ├── Makefile │ ├── README.md │ └── theme │ └── cloudpak │ ├── account │ └── theme.properties │ ├── admin │ └── theme.properties │ ├── common │ └── resources │ │ └── img │ │ ├── favicon.ico │ │ └── logo.svg │ ├── email │ └── theme.properties │ └── login │ ├── messages │ ├── messages_de.properties │ ├── messages_en.properties │ ├── messages_es.properties │ ├── messages_fr.properties │ ├── messages_it.properties │ ├── messages_ja.properties │ ├── messages_ko.properties │ ├── messages_pt_BR.properties │ ├── messages_zh_CN.properties │ └── messages_zh_TW.properties │ ├── resources │ ├── css │ │ └── styles4100.css │ ├── fonts │ │ ├── IBMPlexSans-Regular.woff │ │ └── IBMPlexSans-Regular.woff2 │ └── img │ │ ├── favicon.ico │ │ ├── login-header.svg │ │ ├── view--off.svg │ │ └── view.svg │ └── theme.properties ├── helm-cluster-scoped ├── Chart.yaml ├── templates │ ├── cluster-rbac.yaml │ ├── cluster-webhook.yaml │ └── crd.yaml └── values.yaml ├── helm ├── Chart.yaml ├── templates │ ├── operator-deployment.yaml │ └── rbac.yaml └── values.yaml ├── internal └── controller │ ├── bootstrap │ ├── init.go │ └── init_test.go │ ├── cert-manager │ ├── certificaterefresh_controller.go │ ├── podrefresh_controller.go │ ├── suite_test.go │ └── v1_add_label_controller.go │ ├── common │ ├── cache.go │ ├── util.go │ └── util_test.go │ ├── commonservice_controller.go │ ├── commonservice_controller_test.go │ ├── configurationcollector │ └── collector.go │ ├── constant │ ├── apicatalog.go │ ├── autoScaleConfig.go │ ├── certmanager.go │ ├── cloudNativePostgresql.go │ ├── constant.go │ ├── defaultAdminUser.go │ ├── docLink.go │ ├── fipsEnable.go │ ├── hugepages.go │ ├── instanaEnable.go │ ├── keycloakThemes.go │ ├── namespace.go │ ├── odlm.go │ ├── odlm_operatorconfig.go │ ├── routeHost.go │ ├── serviceLabel.go │ └── storageclass.go │ ├── deploy │ └── manager.go │ ├── goroutines │ ├── cleanup_resources.go │ ├── waitToCreateCsCR.go │ └── waitToCreateCsCrNoOLM.go │ ├── no_olm_commonservice_controller.go │ ├── operandconfig.go │ ├── operatorconfig.go │ ├── recocile_pause.go │ ├── render_template.go │ ├── render_template_test.go │ ├── rules │ ├── resource_comparison.go │ ├── resource_comparison_test.go │ ├── rules.go │ └── rules_suite_test.go │ ├── size │ ├── large_amd64.go │ ├── large_ppc64le.go │ ├── large_s390x.go │ ├── medium_amd64.go │ ├── medium_ppc64le.go │ ├── medium_s390x.go │ ├── small_amd64.go │ ├── small_ppc64le.go │ ├── small_s390x.go │ ├── starterset_amd64.go │ ├── starterset_ppc64le.go │ └── starterset_s390x.go │ ├── suite_test.go │ └── webhooks │ ├── commonservice │ ├── validatingwebhook.go │ └── validatingwebhook_test.go │ └── operandrequest │ └── mutatingwebhook.go ├── testdata ├── README.md ├── actual.yaml ├── deploy │ ├── cluster_rbac.yaml │ ├── deploy.yaml │ ├── role.yaml │ ├── role.yaml.bak │ ├── role_binding.yaml │ └── sa.yaml ├── expected.yaml ├── sizing │ ├── large_mongodb.yaml │ ├── large_size.yaml │ ├── medium_size.yaml │ ├── operandrequest.yaml │ └── storage_class.yaml └── test_profile.sh ├── testing.md └── version └── version.go /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | **What this PR does / why we need it**: 2 | 3 | **Which issue(s) this PR fixes**: 4 | Fixes # 5 | 6 | **Special notes for your reviewer**: 7 | 8 | 1. How the test is done? 9 | 10 | **How to backport this PR to other branch**: 11 | 1. Add label to this PR with the target branch name `backport ` 12 | 2. The PR will be automatically created in the target branch after merging this PR 13 | 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 -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: docker 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | target-branch: "master" 8 | - package-ecosystem: docker 9 | directory: "/" 10 | schedule: 11 | interval: daily 12 | target-branch: "release-sc2" 13 | -------------------------------------------------------------------------------- /.github/workflows/cherry-pick.yaml: -------------------------------------------------------------------------------- 1 | name: cherry pick merged pull request 2 | on: 3 | pull_request_target: 4 | types: [closed] 5 | issue_comment: 6 | types: [created] 7 | permissions: 8 | contents: write # so it can comment 9 | pull-requests: write # so it can create pull requests 10 | jobs: 11 | backport: 12 | name: Backport pull request 13 | runs-on: ubuntu-latest 14 | 15 | # Only run when pull request is merged 16 | # or when a comment starting with `/backport` is created by someone other than the 17 | # https://github.com/backport-action bot user (user id: 97796249). Note that if you use your 18 | # own PAT as `github_token`, that you should replace this id with yours. 19 | if: > 20 | ( 21 | github.event_name == 'pull_request_target' && 22 | github.event.pull_request.merged 23 | ) || ( 24 | github.event_name == 'issue_comment' && 25 | github.event.issue.pull_request && 26 | github.event.comment.user.id != 97796249 && 27 | startsWith(github.event.comment.body, '/backport') 28 | ) 29 | steps: 30 | - uses: actions/checkout@v4 31 | - name: Create backport pull requests 32 | uses: korthout/backport-action@v2 -------------------------------------------------------------------------------- /.github/workflows/ocp.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2022 IBM Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http:#www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | 17 | name: ocp.yaml 18 | 19 | on: 20 | pull_request_target: 21 | types: [labeled] 22 | 23 | env: 24 | AWS_OCP_KUBECONFIG: ${{ secrets.AWS_OCP_KUBECONFIG }} 25 | QUAY_USERNAME: ${{ secrets.QUAY_USERNAME }} 26 | QUAY_PASSWORD: ${{ secrets.QUAY_PASSWORD }} 27 | QUAY_REGISTRY: quay.io/opencloudio 28 | REGISTRY: docker-na-public.artifactory.swg-devops.com/hyc-cloud-private-scratch-docker-local/ibmcom 29 | SCRATCH_USERNAME: ${{ secrets.SCRATCH_USERNAME }} 30 | SCRATCH_TOKEN: ${{ secrets.SCRATCH_TOKEN}} 31 | 32 | jobs: 33 | test-fresh-install: 34 | runs-on: ubuntu-18.04 35 | steps: 36 | - name: Set up Golang 37 | uses: actions/setup-go@v2 38 | with: 39 | go-version: ^1.15 40 | id: go 41 | 42 | - name: Checkout 43 | if: contains(github.event.pull_request.labels.*.name, 'ok-to-test') 44 | with: 45 | ref: ${{ github.event.pull_request.head.ref }} 46 | repository: ${{ github.event.pull_request.head.repo.full_name }} 47 | persist-credentials: false 48 | uses: actions/checkout@v2 49 | 50 | - name: Access cluster 51 | run: | 52 | echo "$AWS_OCP_KUBECONFIG" > ./kubeconfig 53 | mkdir -p /home/runner/.kube 54 | cp ./kubeconfig $HOME/.kube/config 55 | oc get nodes 56 | 57 | - name: Login to registry 58 | run: | 59 | docker login "$QUAY_REGISTRY" -u "$QUAY_USERNAME" -p "$QUAY_PASSWORD" 60 | docker login "$REGISTRY" -u "$SCRATCH_USERNAME" -p "$SCRATCH_TOKEN" 61 | 62 | - name: Build operator 63 | run: | 64 | make build-dev-image 65 | 66 | - name: Generate bundle 67 | run: | 68 | mkdir ./bin 69 | export PATH=$PATH:$(pwd)/bin 70 | echo "$(pwd)/bin" >> $GITHUB_PATH 71 | make clis 72 | 73 | arch=$(uname -m | sed 's/x86_64/amd64/') 74 | yq -i eval ".spec.template.spec.containers[0].image = \"$REGISTRY/common-service-operator-${arch}:dev\"" config/manager/manager.yaml 75 | cat ./config/manager/manager.yaml 76 | 77 | make bundle-manifests RELEASE_VERSION=99.99.99 78 | cat ./bundle/manifests/ibm-common-service-operator.clusterserviceversion.yaml 79 | 80 | make build-bundle-image RELEASE_VERSION=dev 81 | 82 | - name: Deploy operator 83 | run: | 84 | oc project ibm-common-services 85 | ./common/scripts/tests/clear_ocp.sh 86 | make run-bundle RELEASE_VERSION=dev 87 | sleep 20 88 | 89 | - name: Test operator 90 | run: | 91 | oc wait --for condition=Available -n ibm-common-services --timeout=60s deployment/ibm-common-service-operator 92 | oc wait --for condition=Available -n ibm-common-services --timeout=60s deployment/ibm-namespace-scope-operator 93 | oc wait --for condition=Available -n ibm-common-services --timeout=60s deployment/operand-deployment-lifecycle-manager 94 | 95 | - name: Uninstall operator 96 | run: | 97 | oc project ibm-common-services 98 | make cleanup-bundle 99 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Binaries for programs and plugins 3 | *.exe 4 | *.exe~ 5 | *.dll 6 | *.so 7 | *.dylib 8 | bin 9 | 10 | # Test binary, build with `go test -c` 11 | *.test 12 | 13 | # Output of the go coverage tool, specifically when used with LiteIDE 14 | *.out 15 | 16 | # Kubernetes Generated files - skip generated files, except for vendored files 17 | 18 | !vendor/**/zz_generated.* 19 | 20 | # editor and IDE paraphernalia 21 | .idea 22 | *.swp 23 | *.swo 24 | *~ 25 | .vscode 26 | 27 | cache 28 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Build the manager binary 2 | FROM docker-na-public.artifactory.swg-devops.com/hyc-cloud-private-dockerhub-docker-remote/golang:1.23.2 as builder 3 | ARG GOARCH 4 | 5 | WORKDIR /workspace 6 | # Copy the Go Modules manifests 7 | COPY go.mod go.mod 8 | COPY go.sum go.sum 9 | # cache deps before building and copying source so that we don't need to re-download as much 10 | # and so that source changes don't invalidate our downloaded layer 11 | RUN go mod download 12 | 13 | # Copy the go source 14 | COPY cmd/main.go cmd/main.go 15 | COPY api/ api/ 16 | COPY internal/controller/ internal/controller/ 17 | 18 | # Build 19 | RUN CGO_ENABLED=0 GOOS=linux GO111MODULE=on go build -a -o manager cmd/main.go 20 | 21 | # Use distroless as minimal base image to package the manager binary 22 | # Refer to https://github.com/GoogleContainerTools/distroless for more details 23 | # FROM gcr.io/distroless/static:nonroot 24 | FROM docker-na-public.artifactory.swg-devops.com/hyc-cloud-private-edge-docker-local/build-images/ubi9-minimal:latest 25 | 26 | ARG VCS_REF 27 | ARG VCS_URL 28 | ARG RELEASE_VERSION 29 | 30 | LABEL org.label-schema.vendor="IBM" \ 31 | org.label-schema.name="ibm common service operator" \ 32 | org.label-schema.description="Deploy ODLM and IBM Common Services" \ 33 | org.label-schema.vcs-ref=$VCS_REF \ 34 | org.label-schema.vcs-url=$VCS_URL \ 35 | org.label-schema.license="Licensed Materials - Property of IBM" \ 36 | org.label-schema.schema-version="1.0" \ 37 | name="common-service-operator" \ 38 | maintainer="IBM" \ 39 | vendor="IBM" \ 40 | version=$RELEASE_VERSION \ 41 | release=$RELEASE_VERSION \ 42 | description="Deploy ODLM and IBM Common Services" \ 43 | summary="Deploy ODLM and IBM Common Services" 44 | 45 | WORKDIR / 46 | COPY --from=builder /workspace/manager . 47 | COPY hack/keycloak-themes/cloudpak-theme.jar /hack/keycloak-themes/cloudpak-theme.jar 48 | 49 | # copy licenses 50 | RUN mkdir /licenses 51 | COPY LICENSE /licenses 52 | 53 | # USER nonroot:nonroot 54 | USER 1001 55 | 56 | ENTRYPOINT ["/manager"] 57 | -------------------------------------------------------------------------------- /OWNERS: -------------------------------------------------------------------------------- 1 | approvers: 2 | - bitscuit 3 | - Daniel-Fan 4 | - qpdpQ 5 | - bluzarraga 6 | - YCShen1010 7 | - pgodowski 8 | - Jeremy-Cheng-stack 9 | reviewers: 10 | - bitscuit 11 | - Daniel-Fan 12 | - qpdpQ 13 | - bluzarraga 14 | - YCShen1010 15 | - pgodowski 16 | - Jeremy-Cheng-stack 17 | -------------------------------------------------------------------------------- /PROJECT: -------------------------------------------------------------------------------- 1 | domain: ibm.com 2 | layout: go.kubebuilder.io/v4 3 | projectName: ibm-common-service-operator 4 | repo: github.com/IBM/ibm-common-service-operator 5 | resources: 6 | - group: operator 7 | kind: CommonService 8 | version: v3 9 | version: "3" 10 | plugins: 11 | manifests.sdk.operatorframework.io/v2: {} 12 | scorecard.sdk.operatorframework.io/v2: {} 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ibm-common-service-operator 2 | 3 | The `ibm-common-service-operator` is a bridge to connect IBM Cloud Paks and Operand Deployment Lifecycle Manager (ODLM) with IBM Cloud Platform Common Services. You can also install the `ibm-common-service-operator` in stand-alone mode. 4 | 5 | When you install this operator, the operator completes the following tasks: 6 | 7 | - Installs ODLM operator namespace 8 | - Creates the Common Services `OperandRegistry` and `OperandConfig` in the service namespace 9 | 10 | 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). 11 | 12 | For more information about the available IBM Cloud Platform Common Services, see the [IBM Knowledge Center](http://ibm.biz/cpcsdocs). 13 | 14 | ## Supported platforms 15 | 16 | Red Hat OpenShift Container Platform 4.3 or newer installed on one of the following platforms: 17 | 18 | - Linux x86_64 19 | - Linux on Power (ppc64le) 20 | 21 | ## Operator versions 22 | 23 | - 4.13.0 24 | 25 | ## Prerequisites 26 | 27 | Before you install this operator, you need to first install the operator prerequisites: 28 | 29 | - For the list of prerequisites for installing the operator, see the IBM Knowledge Center [Preparing to install services documentation](http://ibm.biz/cpcs_opinstprereq). 30 | 31 | ## Documentation 32 | 33 | - If you are using the operator as part of an IBM Cloud Pak, see the documentation for that IBM Cloud Pak. For a list of IBM Cloud Paks, see [IBM Cloud Paks that use Common Services](http://ibm.biz/cpcs_cloudpaks). 34 | - If you are using the operator in stand-alone mode or with an IBM Containerized Software, see the IBM Cloud Platform Common Services Knowledge Center [Installer documentation](http://ibm.biz/cpcs_opinstall). 35 | 36 | ## SecurityContextConstraints Requirements 37 | 38 | The IBM Common Service Operator supports running with the OpenShift Container Platform 4.3 default restricted Security Context Constraints (SCCs). 39 | 40 | For more information about the OpenShift Container Platform Security Context Constraints, see [Managing Security Context Constraints](https://docs.openshift.com/container-platform/4.3/authentication/managing-security-context-constraints.html). 41 | 42 | ## Developer guide 43 | 44 | If, as a developer, you are looking to build and test this operator to try out and learn more about the operator and its capabilities, you can use the following developer guide. This guide provides commands for a quick install and initial validation for running the operator. 45 | 46 | - [IBM Common Service Operator Design](docs/design.md) 47 | - [Install Common Services in stand-alone mode](docs/install.md) 48 | - [Install Common Services with CloudPaks](docs/cloudpak-integration.md) 49 | 50 | ### End-to-End testing 51 | 52 | For more instructions on how to run end-to-end testing with the Operand Deployment Lifecycle Manager, see [ODLM guide](https://github.com/IBM/operand-deployment-lifecycle-manager/blob/master/docs/install/common-service-integration.md#end-to-end-test). 53 | -------------------------------------------------------------------------------- /api/v3/finalizer.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2022 IBM Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package v3 18 | 19 | import ( 20 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 21 | ) 22 | 23 | // RemoveFinalizer removes the finalizer from the object's ObjectMeta. 24 | func RemoveFinalizer(objectMeta *metav1.ObjectMeta, deletingFinalizer string) bool { 25 | outFinalizers := make([]string, 0) 26 | var changed bool 27 | for _, finalizer := range objectMeta.Finalizers { 28 | if finalizer == deletingFinalizer { 29 | changed = true 30 | continue 31 | } 32 | outFinalizers = append(outFinalizers, finalizer) 33 | } 34 | 35 | objectMeta.Finalizers = outFinalizers 36 | return changed 37 | } 38 | -------------------------------------------------------------------------------- /api/v3/groupversion_info.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2022 IBM Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | // Package v3 contains API Schema definitions for the operator v3 API group 18 | // +kubebuilder:object:generate=true 19 | // +groupName=operator.ibm.com 20 | package v3 21 | 22 | import ( 23 | "k8s.io/apimachinery/pkg/runtime/schema" 24 | "sigs.k8s.io/controller-runtime/pkg/scheme" 25 | ) 26 | 27 | var ( 28 | // GroupVersion is group version used to register these objects 29 | GroupVersion = schema.GroupVersion{Group: "operator.ibm.com", Version: "v3"} 30 | 31 | // SchemeBuilder is used to add go types to the GroupVersionKind scheme 32 | SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} 33 | 34 | // AddToScheme adds the types in this group-version to the given scheme. 35 | AddToScheme = SchemeBuilder.AddToScheme 36 | ) 37 | -------------------------------------------------------------------------------- /base_images.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "imageType": "external", 4 | "sourceRepo": "registry.access.redhat.com", 5 | "sourceNamespace": "ubi9", 6 | "sourceImage": "ubi-minimal", 7 | "destStage": "edge", 8 | "destNamespace": "build-images", 9 | "destImage": "ubi9-minimal", 10 | "tag": "9.6-1747218906", 11 | "updatePackages": [] 12 | }, 13 | { 14 | "imageType": "external", 15 | "sourceRepo": "registry.access.redhat.com", 16 | "sourceNamespace": "ubi9", 17 | "sourceImage": "ubi", 18 | "destStage": "edge", 19 | "destNamespace": "build-images", 20 | "destImage": "ubi9", 21 | "tag": "9.6-1747219013", 22 | "updatePackages": [] 23 | }, 24 | { 25 | "imageType": "external", 26 | "sourceRepo": "registry.access.redhat.com", 27 | "sourceNamespace": "ubi9", 28 | "sourceImage": "ubi-micro", 29 | "destStage": "edge", 30 | "destNamespace": "build-images", 31 | "destImage": "ubi9-micro", 32 | "tag": "9.6-1745521186", 33 | "updatePackages": [] 34 | }, 35 | { 36 | "imageType": "node", 37 | "sourceImage": "ubi9-minimal", 38 | "sourceTag": "9.6-1747218906", 39 | "destImage": "node-v20-ubi9-minimal", 40 | "nodeVersion": "20.19.2" 41 | }, 42 | { 43 | "imageType": "node", 44 | "sourceImage": "ubi9-minimal", 45 | "sourceTag": "9.6-1747218906", 46 | "destImage": "node-v22-ubi9-minimal", 47 | "nodeVersion": "22.15.1" 48 | } 49 | ] 50 | -------------------------------------------------------------------------------- /bedrock-migration/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /bedrock-migration/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: cpfs-migration 3 | description: A Helm chart for migrating Bedrock from OLM to No OLM 4 | type: application 5 | version: 0.0.0 6 | appVersion: "0.0.0" 7 | -------------------------------------------------------------------------------- /bedrock-migration/templates/rbac.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: bedrock-migration-job-sa 5 | namespace: {{ .Values.global.operatorNamespace }} 6 | annotations: 7 | "helm.sh/hook": pre-install 8 | "helm.sh/hook-weight": "-1" 9 | --- 10 | kind: Role 11 | apiVersion: rbac.authorization.k8s.io/v1 12 | metadata: 13 | name: bedrock-migration-job-role-{{ .Values.global.operatorNamespace }} 14 | namespace: {{ .Values.global.operatorNamespace }} 15 | annotations: 16 | "helm.sh/hook": pre-install 17 | "helm.sh/hook-weight": "0" 18 | "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed 19 | rules: 20 | - apiGroups: 21 | - operators.coreos.com 22 | resources: 23 | - subscriptions 24 | - clusterserviceversions 25 | verbs: 26 | - list 27 | - get 28 | - delete 29 | - watch 30 | - apiGroups: 31 | - "rbac.authorization.k8s.io" 32 | resources: 33 | - roles 34 | - rolebindings 35 | verbs: 36 | - list 37 | - get 38 | - delete 39 | - watch 40 | - apiGroups: 41 | - "" 42 | resources: 43 | - configmaps 44 | - serviceaccounts 45 | - secrets 46 | verbs: 47 | - list 48 | - get 49 | - delete 50 | - watch 51 | - apiGroups: 52 | - "batch" 53 | resources: 54 | - jobs 55 | verbs: 56 | - list 57 | - get 58 | - delete 59 | - watch 60 | - apiGroups: 61 | - "operator.ibm.com" 62 | resources: 63 | - namespacescopes 64 | verbs: 65 | - list 66 | - get 67 | - delete 68 | - patch 69 | - watch 70 | --- 71 | kind: RoleBinding 72 | apiVersion: rbac.authorization.k8s.io/v1 73 | metadata: 74 | name: bedrock-migration-job-rb-{{ .Values.global.operatorNamespace }} 75 | namespace: {{ .Values.global.operatorNamespace }} 76 | annotations: 77 | "helm.sh/hook": pre-install 78 | "helm.sh/hook-weight": "1" 79 | "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed 80 | subjects: 81 | - kind: ServiceAccount 82 | name: bedrock-migration-job-sa 83 | namespace: {{ .Values.global.operatorNamespace }} 84 | roleRef: 85 | apiGroup: rbac.authorization.k8s.io 86 | kind: Role 87 | name: bedrock-migration-job-role-{{ .Values.global.operatorNamespace }} 88 | {{- $watchNamespaces := .Values.global.tetheredNamespaces | default list -}} 89 | {{- if .Values.global.instanceNamespace -}} 90 | {{- $watchNamespaces = append $watchNamespaces .Values.global.instanceNamespace -}} 91 | {{- end -}} 92 | {{- range $namespace := $watchNamespaces | uniq }} 93 | --- 94 | kind: Role 95 | apiVersion: rbac.authorization.k8s.io/v1 96 | metadata: 97 | name: bedrock-migration-job-role 98 | namespace: {{ $namespace }} 99 | annotations: 100 | "helm.sh/hook": pre-install 101 | "helm.sh/hook-weight": "0" 102 | "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed 103 | rules: 104 | - apiGroups: 105 | - "rbac.authorization.k8s.io" 106 | resources: 107 | - roles 108 | - rolebindings 109 | verbs: 110 | - list 111 | - get 112 | - delete 113 | - watch 114 | - apiGroups: 115 | - "" 116 | resources: 117 | - configmaps 118 | - serviceaccounts 119 | verbs: 120 | - list 121 | - get 122 | - delete 123 | - watch 124 | --- 125 | kind: RoleBinding 126 | apiVersion: rbac.authorization.k8s.io/v1 127 | metadata: 128 | name: bedrock-migration-job-rb 129 | namespace: {{ $namespace }} 130 | annotations: 131 | "helm.sh/hook": pre-install 132 | "helm.sh/hook-weight": "1" 133 | "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed 134 | subjects: 135 | - kind: ServiceAccount 136 | name: bedrock-migration-job-sa 137 | namespace: {{ $.Values.global.operatorNamespace }} 138 | roleRef: 139 | apiGroup: rbac.authorization.k8s.io 140 | kind: Role 141 | name: bedrock-migration-job-role 142 | {{- end }} 143 | -------------------------------------------------------------------------------- /bedrock-migration/values.yaml: -------------------------------------------------------------------------------- 1 | imEnabled: "true" #should this be a global value? Is there a better way to determine this? 2 | 3 | #stand-in global values for testing 4 | global: 5 | operatorNamespace: "cs-op" 6 | instanceNamespace: "cs-serv" 7 | tetheredNamespaces: [""] 8 | imagePullPrefix: icr.io 9 | imagePullSecret: ibm-entitlement-key 10 | 11 | cpfs: 12 | imageRegistryNamespaceOperand: cpopen/cpfs -------------------------------------------------------------------------------- /bundle.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM scratch 2 | 3 | # Core bundle labels. 4 | LABEL operators.operatorframework.io.bundle.mediatype.v1=registry+v1 5 | LABEL operators.operatorframework.io.bundle.manifests.v1=manifests/ 6 | LABEL operators.operatorframework.io.bundle.metadata.v1=metadata/ 7 | LABEL operators.operatorframework.io.bundle.package.v1=ibm-common-service-operator 8 | LABEL operators.operatorframework.io.bundle.channels.v1=v4.13 9 | LABEL operators.operatorframework.io.bundle.channel.default.v1=v4.13 10 | LABEL operators.operatorframework.io.metrics.builder=operator-sdk-v1.38.0 11 | LABEL operators.operatorframework.io.metrics.mediatype.v1=metrics+v1 12 | LABEL operators.operatorframework.io.metrics.project_layout=go.kubebuilder.io/v4 13 | 14 | # Labels for testing. 15 | LABEL operators.operatorframework.io.test.mediatype.v1=scorecard+v1 16 | LABEL operators.operatorframework.io.test.config.v1=tests/scorecard/ 17 | 18 | # Copy files to locations specified by labels. 19 | COPY bundle/manifests /manifests/ 20 | COPY bundle/metadata /metadata/ 21 | COPY bundle/tests/scorecard /tests/scorecard/ 22 | -------------------------------------------------------------------------------- /bundle/manifests/webhook-service_v1_service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | creationTimestamp: null 5 | name: webhook-service 6 | spec: 7 | ports: 8 | - port: 443 9 | targetPort: 9443 10 | selector: 11 | control-plane: controller-manager 12 | status: 13 | loadBalancer: {} 14 | -------------------------------------------------------------------------------- /bundle/metadata/annotations.yaml: -------------------------------------------------------------------------------- 1 | annotations: 2 | # Core bundle annotations. 3 | operators.operatorframework.io.bundle.mediatype.v1: registry+v1 4 | operators.operatorframework.io.bundle.manifests.v1: manifests/ 5 | operators.operatorframework.io.bundle.metadata.v1: metadata/ 6 | operators.operatorframework.io.bundle.package.v1: ibm-common-service-operator 7 | operators.operatorframework.io.bundle.channels.v1: v4.13 8 | operators.operatorframework.io.bundle.channel.default.v1: v4.13 9 | operators.operatorframework.io.metrics.builder: operator-sdk-v1.38.0 10 | operators.operatorframework.io.metrics.mediatype.v1: metrics+v1 11 | operators.operatorframework.io.metrics.project_layout: go.kubebuilder.io/v4 12 | 13 | # Annotations for testing. 14 | operators.operatorframework.io.test.mediatype.v1: scorecard+v1 15 | operators.operatorframework.io.test.config.v1: tests/scorecard/ 16 | 17 | # OpenShift annotations. 18 | com.redhat.openshift.versions: v4.12-v4.17 19 | -------------------------------------------------------------------------------- /bundle/tests/scorecard/config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: scorecard.operatorframework.io/v1alpha3 2 | kind: Configuration 3 | metadata: 4 | name: config 5 | stages: 6 | - parallel: true 7 | tests: 8 | - entrypoint: 9 | - scorecard-test 10 | - basic-check-spec 11 | image: quay.io/operator-framework/scorecard-test:master 12 | labels: 13 | suite: basic 14 | test: basic-check-spec-test 15 | storage: 16 | spec: 17 | mountPath: {} 18 | - entrypoint: 19 | - scorecard-test 20 | - olm-bundle-validation 21 | image: quay.io/operator-framework/scorecard-test:master 22 | labels: 23 | suite: olm 24 | test: olm-bundle-validation-test 25 | storage: 26 | spec: 27 | mountPath: {} 28 | - entrypoint: 29 | - scorecard-test 30 | - olm-crds-have-validation 31 | image: quay.io/operator-framework/scorecard-test:master 32 | labels: 33 | suite: olm 34 | test: olm-crds-have-validation-test 35 | storage: 36 | spec: 37 | mountPath: {} 38 | - entrypoint: 39 | - scorecard-test 40 | - olm-spec-descriptors 41 | image: quay.io/operator-framework/scorecard-test:master 42 | labels: 43 | suite: olm 44 | test: olm-spec-descriptors-test 45 | storage: 46 | spec: 47 | mountPath: {} 48 | storage: 49 | spec: 50 | mountPath: {} 51 | -------------------------------------------------------------------------------- /common/Makefile.common.mk: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2022 IBM Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | ############################################################ 19 | # GKE section 20 | ############################################################ 21 | PROJECT ?= oceanic-guard-191815 22 | ZONE ?= us-east5-c 23 | CLUSTER ?= bedrock-prow 24 | 25 | activate-serviceaccount: 26 | ifdef GOOGLE_APPLICATION_CREDENTIALS 27 | gcloud auth activate-service-account --key-file="$(GOOGLE_APPLICATION_CREDENTIALS)" || true 28 | endif 29 | 30 | get-cluster-credentials: activate-serviceaccount 31 | mkdir -p ~/.kube; cp -v /etc/kubeconfig/config ~/.kube; kubectl config use-context default; kubectl get nodes; echo going forward retiring google cloud 32 | 33 | ifdef GOOGLE_APPLICATION_CREDENTIALS 34 | gcloud container clusters get-credentials "$(CLUSTER)" --project="$(PROJECT)" --zone="$(ZONE)" || true 35 | endif 36 | 37 | config-docker: get-cluster-credentials 38 | @common/scripts/artifactory_config_docker.sh 39 | 40 | config-docker-quay: get-cluster-credentials 41 | @common/scripts/quay_config_docker.sh 42 | 43 | FINDFILES=find . \( -path ./.git -o -path ./.github \) -prune -o -type f 44 | XARGS = xargs -0 ${XARGS_FLAGS} 45 | CLEANXARGS = xargs ${XARGS_FLAGS} 46 | 47 | lint-copyright-banner: 48 | @${FINDFILES} \( -name '*.go' -o -name '*.cc' -o -name '*.h' -o -name '*.proto' -o -name '*.py' -o -name '*.sh' \) \( ! \( -name '*.gen.go' -o -name '*.pb.go' -o -name '*_pb2.py' \) \) -print0 |\ 49 | ${XARGS} common/scripts/lint_copyright_banner.sh 50 | 51 | lint-go: 52 | golangci-lint version 53 | @${FINDFILES} -name '*.go' \( ! \( -name '*.gen.go' -o -name '*.pb.go' \) \) -print0 | ${XARGS} common/scripts/lint_go.sh 54 | 55 | lint-all: lint-copyright-banner lint-go 56 | 57 | # find or download controller-gen 58 | # download controller-gen if necessary 59 | controller-gen: 60 | ifeq (, $(shell which controller-gen 2>/dev/null)) 61 | @{ \ 62 | GOBIN=$(shell pwd)/bin go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_TOOLS_VERSION) ;\ 63 | } 64 | CONTROLLER_GEN=$(realpath ./bin/controller-gen) 65 | else 66 | CONTROLLER_GEN=$(shell which controller-gen) 67 | endif 68 | 69 | # Run go vet for this project. More info: https://golang.org/cmd/vet/ 70 | code-vet: 71 | @echo go vet 72 | go vet $$(go list ./... ) 73 | 74 | # Run go fmt for this project 75 | code-fmt: 76 | @echo go fmt 77 | go fmt $$(go list ./... ) 78 | 79 | # Run go mod tidy to update dependencies 80 | code-tidy: 81 | @echo go mod tidy 82 | go mod tidy -v 83 | 84 | .PHONY: code-vet code-fmt code-tidy code-gen lint-copyright-banner lint-go lint-all config-docker 85 | -------------------------------------------------------------------------------- /common/scripts/.githooks/make_lint-all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2022 IBM Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | # Launches fmt and lint checks 19 | make lint-all 20 | -------------------------------------------------------------------------------- /common/scripts/.githooks/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2021 The Kubernetes Authors. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | # This hook is called with the following parameters: 18 | # 19 | # $1 -- Name of the remote to which the push is being done 20 | # $2 -- URL to which the push is being done 21 | # 22 | # If pushing without using a named remote those arguments will be equal. 23 | # 24 | # Information about the commits which are being pushed is supplied as lines to 25 | # the standard input in the form: 26 | # 27 | # 28 | # 29 | 30 | remote="$1" 31 | url="$2" 32 | 33 | .git/hooks/make_lint-all.sh 34 | 35 | exit $? 36 | -------------------------------------------------------------------------------- /common/scripts/artifactory_config_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2022 IBM Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | KUBECTL=$(which kubectl) 19 | DOCKER_REGISTRY="docker-na-public.artifactory.swg-devops.com/hyc-cloud-private-integration-docker-local" 20 | DOCKER_EDGE_REGISTRY="docker-na-public.artifactory.swg-devops.com/hyc-cloud-private-edge-docker-local" 21 | DOCKER_USERNAME=$(${KUBECTL} -n default get secret artifactory-cred -o jsonpath='{.data.username}' | base64 --decode) 22 | DOCKER_PASSWORD=$(${KUBECTL} -n default get secret artifactory-cred -o jsonpath='{.data.password}' | base64 --decode) 23 | 24 | # support other container tools, e.g. podman 25 | CONTAINER_CLI=${CONTAINER_CLI:-docker} 26 | 27 | # login the docker registry 28 | ${CONTAINER_CLI} login "${DOCKER_REGISTRY}" -u "${DOCKER_USERNAME}" -p "${DOCKER_PASSWORD}" 29 | ${CONTAINER_CLI} login "${DOCKER_EDGE_REGISTRY}" -u "${DOCKER_USERNAME}" -p "${DOCKER_PASSWORD}" 30 | -------------------------------------------------------------------------------- /common/scripts/gobuild.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2022 IBM Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | # This script builds and version stamps the output 19 | 20 | VERBOSE=${VERBOSE:-"0"} 21 | V="" 22 | if [[ "${VERBOSE}" == "1" ]];then 23 | V="-x" 24 | set -x 25 | fi 26 | 27 | OUT=${1:?"output path"} 28 | shift 29 | 30 | set -e 31 | 32 | BUILD_GOOS=${GOOS:-linux} 33 | BUILD_GOARCH=${GOARCH:-amd64} 34 | GOBINARY=${GOBINARY:-go} 35 | BUILDINFO=${BUILDINFO:-""} 36 | STATIC=${STATIC:-1} 37 | GOBUILDFLAGS=${GOBUILDFLAGS:-} 38 | GCFLAGS=${GCFLAGS:-} 39 | LDFLAGS=${LDFLAGS:-"-extldflags -static"} 40 | # Split GOBUILDFLAGS by spaces into an array called GOBUILDFLAGS_ARRAY. 41 | IFS=' ' read -r -a GOBUILDFLAGS_ARRAY <<< "$GOBUILDFLAGS" 42 | 43 | export CGO_ENABLED=0 44 | 45 | if [[ "${STATIC}" != "1" ]];then 46 | LDFLAGS="" 47 | fi 48 | 49 | time GOOS=${BUILD_GOOS} GOARCH=${BUILD_GOARCH} ${GOBINARY} build \ 50 | ${V} "${GOBUILDFLAGS_ARRAY[@]}" ${GCFLAGS:+-gcflags "${GCFLAGS}"} \ 51 | -o "${OUT}" \ 52 | -ldflags "${LDFLAGS}" "${@}" 53 | -------------------------------------------------------------------------------- /common/scripts/install-operator-sdk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2022 IBM Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | echo ">>> Installing Operator SDK" 19 | 20 | # Use version 0.10.0 21 | RELEASE_VERSION=v0.19.0 22 | # Download binary 23 | curl -LO https://github.com/operator-framework/operator-sdk/releases/download/${RELEASE_VERSION}/operator-sdk-${RELEASE_VERSION}-x86_64-linux-gnu 24 | # Install binary 25 | chmod +x operator-sdk-${RELEASE_VERSION}-x86_64-linux-gnu && mkdir -p /usr/local/bin/ && cp operator-sdk-${RELEASE_VERSION}-x86_64-linux-gnu /usr/local/bin/operator-sdk && rm operator-sdk-${RELEASE_VERSION}-x86_64-linux-gnu 26 | -------------------------------------------------------------------------------- /common/scripts/lint-csv.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2022 IBM Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | STATUS=0 19 | ARCH=$(uname -m) 20 | [[ "${ARCH}" != "x86_64" ]] && exit 0 21 | 22 | JQ=$(command -v jq) 23 | YQ=$(command -v yq) 24 | 25 | if [[ "X${JQ}" == "X" ]]; then 26 | curl -L -o /tmp/jq https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64 27 | chmod +x /tmp/jq 28 | JQ=/tmp/jq 29 | fi 30 | if [[ "X${YQ}" == "X" ]]; then 31 | curl -L -o /tmp/yq https://github.com/mikefarah/yq/releases/download/v4.3.1/yq_linux_amd64 32 | chmod +x /tmp/yq 33 | YQ=/tmp/yq 34 | fi 35 | 36 | CSV_PATH=bundle/manifests/ibm-common-service-operator.clusterserviceversion.yaml 37 | 38 | # Lint alm-examples 39 | echo "Lint alm-examples" 40 | $YQ eval '.metadata.annotations.alm-examples' $CSV_PATH | $JQ . >/dev/null || STATUS=1 41 | 42 | # Lint yamls, only CS Operator needs this part 43 | for section in csV4OperandConfig csV4SaasOperandConfig csV4OperandRegistry csV4SaasOperandRegistry csOperatorSubscription csSecretshareOperator csWebhookOperator csWebhookOperatorEnableOpreqWebhook nsRestrictedSubscription nsSubscription odlmClusterSubscription odlmNamespacedSubscription; do 44 | echo "Lint $section" 45 | $YQ eval '.metadata.annotations.$section' $CSV_PATH | $YQ - >/dev/null || STATUS=1 46 | done 47 | 48 | exit $STATUS 49 | -------------------------------------------------------------------------------- /common/scripts/lint_copyright_banner.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2022 IBM Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | set -e 19 | 20 | ec=0 21 | for fn in "$@"; do 22 | if ! grep -L -q -e "Apache License, Version 2" "${fn}"; then 23 | echo "Missing license: ${fn}" 24 | ec=1 25 | fi 26 | 27 | if ! grep -L -q -e "Copyright" "${fn}"; then 28 | echo "Missing copyright: ${fn}" 29 | ec=1 30 | fi 31 | done 32 | 33 | exit $ec 34 | -------------------------------------------------------------------------------- /common/scripts/lint_go.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2022 IBM Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | GOGC=25 golangci-lint run -c ./common/config/.golangci.yml --timeout=480s -------------------------------------------------------------------------------- /common/scripts/multiarch_image.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2022 IBM Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | # This script build and push multiarch(amd64, ppc64le and s390x) image for the one specified by 19 | # IMAGE_REPO, IMAGE_NAME and VERSION. 20 | # It assumes the specified image for each platform is already pushed into corresponding docker registry. 21 | 22 | ALL_PLATFORMS="amd64 ppc64le s390x" 23 | 24 | IMAGE_REPO=${1} 25 | IMAGE_NAME=${2} 26 | VERSION=${3-"$(git describe --exact-match 2> /dev/null || git describe --match=$(git rev-parse --short=8 HEAD) --always --dirty --abbrev=8)"} 27 | RELEASE_VERSION=${4:-4.13.0} 28 | MAX_PULLING_RETRY=${MAX_PULLING_RETRY-10} 29 | RETRY_INTERVAL=${RETRY_INTERVAL-10} 30 | # support other container tools, e.g. podman 31 | CONTAINER_CLI=${CONTAINER_CLI:-docker} 32 | 33 | # Loop until the image for each single platform is ready in the docker registry. 34 | # TODO: remove this if prow job support dependency. 35 | for arch in ${ALL_PLATFORMS} 36 | do 37 | for i in $(seq 1 "${MAX_PULLING_RETRY}") 38 | do 39 | echo "Checking image '${IMAGE_REPO}'/'${IMAGE_NAME}'-'${arch}':'${VERSION}'..." 40 | ${CONTAINER_CLI} manifest inspect "${IMAGE_REPO}"/"${IMAGE_NAME}"-"${arch}":"${VERSION}" && break 41 | sleep "${RETRY_INTERVAL}" 42 | if [ "${i}" -eq "${MAX_PULLING_RETRY}" ]; then 43 | echo "Failed to found image '${IMAGE_REPO}'/'${IMAGE_NAME}'-'${arch}':'${VERSION}'!!!" 44 | exit 1 45 | fi 46 | done 47 | done 48 | 49 | # create multi-arch manifest 50 | echo "Creating the multi-arch image manifest for ${IMAGE_REPO}/${IMAGE_NAME}:${RELEASE_VERSION}..." 51 | ${CONTAINER_CLI} manifest create "${IMAGE_REPO}"/"${IMAGE_NAME}":"${RELEASE_VERSION}" \ 52 | "${IMAGE_REPO}"/"${IMAGE_NAME}"-amd64:"${VERSION}" \ 53 | "${IMAGE_REPO}"/"${IMAGE_NAME}"-ppc64le:"${VERSION}" \ 54 | "${IMAGE_REPO}"/"${IMAGE_NAME}"-s390x:"${VERSION}" 55 | echo "Creating the multi-arch image manifest for ${IMAGE_REPO}/${IMAGE_NAME}:latest..." 56 | ${CONTAINER_CLI} manifest create "${IMAGE_REPO}"/"${IMAGE_NAME}":latest \ 57 | "${IMAGE_REPO}"/"${IMAGE_NAME}"-amd64:"${VERSION}" \ 58 | "${IMAGE_REPO}"/"${IMAGE_NAME}"-ppc64le:"${VERSION}" \ 59 | "${IMAGE_REPO}"/"${IMAGE_NAME}"-s390x:"${VERSION}" 60 | 61 | # push multi-arch manifest 62 | echo "Pushing the multi-arch image manifest for ${IMAGE_REPO}/${IMAGE_NAME}:${RELEASE_VERSION}..." 63 | ${CONTAINER_CLI} manifest push "${IMAGE_REPO}"/"${IMAGE_NAME}":"${RELEASE_VERSION}" 64 | echo "Pushing the multi-arch image manifest for ${IMAGE_REPO}/${IMAGE_NAME}:latest..." 65 | ${CONTAINER_CLI} manifest push "${IMAGE_REPO}"/"${IMAGE_NAME}":latest 66 | -------------------------------------------------------------------------------- /common/scripts/patch_image.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2022 IBM Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | # counter to keep track of installation steps 19 | STEP=0 20 | 21 | # script base directory 22 | BASE_DIR=$(dirname "$0") 23 | 24 | # ---------- Command functions ---------- 25 | 26 | function main() { 27 | title "Patch Common Service Operator and ODLM images" 28 | msg "-----------------------------------------------------------------------" 29 | 30 | CS_IMAGE="" 31 | ODLM_IMAGE="" 32 | while [ "$#" -gt "0" ] 33 | do 34 | case "$1" in 35 | "-h"|"--help") 36 | usage 37 | exit 0 38 | ;; 39 | "-cs") 40 | CS_IMAGE=$2 41 | shift 42 | ;; 43 | "-odlm") 44 | ODLM_IMAGE=$2 45 | shift 46 | ;; 47 | *) 48 | warning "invalid option -- \`$1\`" 49 | usage 50 | exit 1 51 | ;; 52 | esac 53 | shift 54 | done 55 | check_preqreqs 56 | patch_new_images 57 | } 58 | 59 | function usage() { 60 | local script="${0##*/}" 61 | 62 | while read -r ; do echo "${REPLY}" ; done <<-EOF 63 | Usage: ${script} [OPTION]... 64 | Patch common services operator and ODLM 65 | 66 | Options: 67 | Mandatory arguments to long options are mandatory for short options too. 68 | -h, --help display this help and exit 69 | -cs specify the patched image of ibm-common-service-operator 70 | -oodlm specify the patched image of operand-deployment-lifecycle-manager 71 | EOF 72 | } 73 | 74 | function check_preqreqs() { 75 | title "[${STEP}] Checking prerequesites ..." 76 | msg "-----------------------------------------------------------------------" 77 | 78 | # checking oc command 79 | if [[ -z "$(command -v oc 2> /dev/null)" ]]; then 80 | error "OpenShift Command Line tool oc is not available" 81 | else 82 | success "OpenShift Command Line tool oc is available." 83 | fi 84 | 85 | # checking oc command logged in 86 | user=$(oc whoami 2> /dev/null) 87 | if [ $? -ne 0 ]; then 88 | error "You must be logged into the OpenShift Cluster from the oc command line." 89 | else 90 | success "oc command logged in as ${user}" 91 | fi 92 | } 93 | 94 | function patch_new_images { 95 | STEP=$((STEP + 1 )) 96 | 97 | title "[${STEP}] Patching CSV of ibm-common-service-operator ..." 98 | msg "-----------------------------------------------------------------------" 99 | 100 | if [ "${CS_IMAGE}" != "" ]; then 101 | while read -r ns cscsv; do 102 | 103 | msg "Updating csv ${cscsv} in namespace ${ns}..." 104 | msg "-----------------------------------------------------------------------" 105 | 106 | in_step=1 107 | msg "[${in_step}] Updating the image ..." 108 | 109 | template='[{"op": "replace", "path":"/spec/install/spec/deployments/0/spec/template/spec/containers/0/image", "value":"%s"}]' 110 | json_string=$(printf "$template" "${CS_IMAGE}") 111 | oc patch csv ${cscsv} -n ${ns} --type="json" -p "${json_string}" 2> /dev/null 112 | msg "" 113 | done < <(oc get csv --all-namespaces | grep ibm-common-service-operator | awk '{print $1" "$2}') 114 | 115 | success "Updated csv of ibm-common-service-operator successfully." 116 | msg "" 117 | fi 118 | 119 | if [ "${ODLM_IMAGE}" != "" ]; then 120 | while read -r ns odlmcsv; do 121 | 122 | msg "Updating csv ${odlmcsv} in namespace ${ns}..." 123 | msg "-----------------------------------------------------------------------" 124 | 125 | in_step=1 126 | msg "[${in_step}] Updating the image ..." 127 | 128 | template='[{"op": "replace", "path":"/spec/install/spec/deployments/0/spec/template/spec/containers/0/image", "value":"%s"}]' 129 | json_string=$(printf "$template" "${ODLM_IMAGE}") 130 | oc patch csv ${odlmcsv} -n ${ns} --type="json" -p "${json_string}" 2> /dev/null 131 | 132 | msg "" 133 | done < <(oc get csv --all-namespaces | grep operand-deployment-lifecycle-manager | awk '{print $1" "$2}') 134 | 135 | success "Updated csv of operand-deployment-lifecycle-manager successfully." 136 | msg "" 137 | fi 138 | } 139 | 140 | function msg() { 141 | printf '%b\n' "$1" 142 | } 143 | 144 | function success() { 145 | msg "\33[32m[✔] ${1}\33[0m" 146 | } 147 | 148 | function error() { 149 | msg "\33[31m[✘] ${1}\33[0m" 150 | exit 1 151 | } 152 | 153 | function title() { 154 | msg "\33[34m# ${1}\33[0m" 155 | } 156 | 157 | function info() { 158 | msg "[INFO] ${1}" 159 | } 160 | 161 | # --- Run --- 162 | 163 | main $* 164 | -------------------------------------------------------------------------------- /common/scripts/quay_config_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2022 IBM Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | KUBECTL=$(command -v kubectl) 19 | DOCKER_REGISTRY="quay.io" 20 | DOCKER_USERNAME="multicloudlab" 21 | DOCKER_PASSWORD=$(${KUBECTL} -n default get secret quay-cred -o jsonpath='{.data.password}' | base64 --decode) 22 | 23 | # support other container tools, e.g. podman 24 | CONTAINER_CLI=${CONTAINER_CLI:-docker} 25 | 26 | # login the docker registry 27 | ${CONTAINER_CLI} login "${DOCKER_REGISTRY}" -u "${DOCKER_USERNAME}" -p "${DOCKER_PASSWORD}" 28 | 29 | -------------------------------------------------------------------------------- /common/scripts/tests/clear_ocp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2022 IBM Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http:#www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | echo "Checking if cluster is clear for deploy" 19 | 20 | oc get deployment ibm-common-service-operator 21 | export ret=$? 22 | while [ $ret -eq 0 ]; do 23 | echo "Cluster already has common service operator installed. Waiting until clear" 24 | sleep 60 25 | oc get deployment ibm-common-service-operator 26 | ret=$? 27 | done 28 | -------------------------------------------------------------------------------- /common/scripts/update_catalogsource.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2022 IBM Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | CATALOG_SOURCE_NAME=$1 19 | CATALOG_SOURCE_IMAGE=$2 20 | 21 | # checking arguments 22 | if [[ ( -z "${CATALOG_SOURCE_NAME}" || -z "${CATALOG_SOURCE_IMAGE}" ) ]]; then 23 | echo "[ERROR] Usage: $0 CATALOG_SOURCE_NAME CATALOG_SOURCE_IMAGE" 24 | exit 1 25 | fi 26 | 27 | cat <(oc apply -f -) | cat 28 | apiVersion: operators.coreos.com/v1alpha1 29 | kind: CatalogSource 30 | metadata: 31 | name: ${CATALOG_SOURCE_NAME} 32 | namespace: openshift-marketplace 33 | spec: 34 | displayName: ${CATALOG_SOURCE_NAME} 35 | publisher: IBM 36 | sourceType: grpc 37 | image: ${CATALOG_SOURCE_IMAGE} 38 | updateStrategy: 39 | registryPoll: 40 | interval: 45m 41 | EOF -------------------------------------------------------------------------------- /config/certmanager/certificate.yaml: -------------------------------------------------------------------------------- 1 | # The following manifests contain a self-signed issuer CR and a certificate CR. 2 | # More document can be found at https://docs.cert-manager.io 3 | # WARNING: Targets CertManager v1.0. Check https://cert-manager.io/docs/installation/upgrading/ for breaking changes. 4 | apiVersion: cert-manager.io/v1 5 | kind: Issuer 6 | metadata: 7 | name: selfsigned-issuer 8 | # namespace: ibm-common-services 9 | spec: 10 | selfSigned: {} 11 | --- 12 | apiVersion: cert-manager.io/v1 13 | kind: Certificate 14 | metadata: 15 | name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml 16 | # namespace: ibm-common-services 17 | spec: 18 | # $(SERVICE_NAME) and $(SERVICE_NAMESPACE) will be substituted by kustomize 19 | dnsNames: 20 | - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc 21 | - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc.cluster.local 22 | issuerRef: 23 | kind: Issuer 24 | name: selfsigned-issuer 25 | secretName: webhook-server-cert # this secret will not be prefixed, since it's not managed by kustomize -------------------------------------------------------------------------------- /config/certmanager/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - certificate.yaml 3 | 4 | configurations: 5 | - kustomizeconfig.yaml 6 | -------------------------------------------------------------------------------- /config/certmanager/kustomizeconfig.yaml: -------------------------------------------------------------------------------- 1 | # This configuration is for teaching kustomize how to update name ref and var substitution 2 | nameReference: 3 | - kind: Issuer 4 | group: cert-manager.io 5 | fieldSpecs: 6 | - kind: Certificate 7 | group: cert-manager.io 8 | path: spec/issuerRef/name 9 | 10 | varReference: 11 | - kind: Certificate 12 | group: cert-manager.io 13 | path: spec/commonName 14 | - kind: Certificate 15 | group: cert-manager.io 16 | path: spec/dnsNames 17 | -------------------------------------------------------------------------------- /config/crd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # This kustomization.yaml is not intended to be run by itself, 2 | # since it depends on service name and namespace that are out of this kustomize package. 3 | # It should be run by config/default 4 | resources: 5 | - bases/operator.ibm.com_commonservices.yaml 6 | # +kubebuilder:scaffold:crdkustomizeresource 7 | 8 | patchesStrategicMerge: 9 | # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. 10 | # patches here are for enabling the conversion webhook for each CRD 11 | - patches/webhook_in_commonservices.yaml 12 | # +kubebuilder:scaffold:crdkustomizewebhookpatch 13 | 14 | # [CERTMANAGER] To enable webhook, uncomment all the sections with [CERTMANAGER] prefix. 15 | # patches here are for enabling the CA injection for each CRD 16 | #- patches/cainjection_in_commonservices.yaml 17 | # +kubebuilder:scaffold:crdkustomizecainjectionpatch 18 | 19 | # patches here are for adding labels for each CRD 20 | - patches/label_in_commonservices.yaml 21 | # +kubebuilder:scaffold:crdkustomizecainjectionpatch 22 | 23 | # the following config is for teaching kustomize how to do kustomization for CRDs. 24 | configurations: 25 | - kustomizeconfig.yaml 26 | -------------------------------------------------------------------------------- /config/crd/kustomizeconfig.yaml: -------------------------------------------------------------------------------- 1 | # This file is for teaching kustomize how to substitute name and namespace reference in CRD 2 | nameReference: 3 | - kind: Service 4 | version: v1 5 | fieldSpecs: 6 | - kind: CustomResourceDefinition 7 | group: apiextensions.k8s.io 8 | path: spec/conversion/webhookClientConfig/service/name 9 | 10 | namespace: 11 | - kind: CustomResourceDefinition 12 | group: apiextensions.k8s.io 13 | path: spec/conversion/webhookClientConfig/service/namespace 14 | create: false 15 | 16 | varReference: 17 | - path: metadata/annotations 18 | -------------------------------------------------------------------------------- /config/crd/patches/cainjection_in_commonservices.yaml: -------------------------------------------------------------------------------- 1 | # The following patch adds a directive for certmanager to inject CA into the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 7 | name: commonservices.operator.ibm.com -------------------------------------------------------------------------------- /config/crd/patches/label_in_commonservices.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apiextensions.k8s.io/v1 2 | kind: CustomResourceDefinition 3 | metadata: 4 | labels: 5 | app.kubernetes.io/instance: "ibm-common-service-operator" 6 | app.kubernetes.io/managed-by: "ibm-common-service-operator" 7 | app.kubernetes.io/name: "ibm-common-service-operator" 8 | name: commonservices.operator.ibm.com 9 | -------------------------------------------------------------------------------- /config/crd/patches/webhook_in_commonservices.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM/ibm-common-service-operator/34b3d3fb70108852ef6aac2cc1e972f164853d4c/config/crd/patches/webhook_in_commonservices.yaml -------------------------------------------------------------------------------- /config/default/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # Adds namespace to all resources. 2 | transformers: 3 | - |- 4 | apiVersion: builtin 5 | kind: NamespaceTransformer 6 | metadata: 7 | name: notImportantHere 8 | namespace: custom-namespace 9 | setRoleBindingSubjects: allServiceAccounts 10 | fieldSpecs: 11 | - path: metadata/namespace 12 | create: true 13 | 14 | namespace: custom-namespace 15 | 16 | # Value of this field is prepended to the 17 | # names of all resources, e.g. a deployment named 18 | # "wordpress" becomes "alices-wordpress". 19 | # Note that it should also match with the prefix (text before '-') of the namespace 20 | # field above. 21 | # namePrefix: ibm- 22 | 23 | # Labels to add to all resources and selectors. 24 | #commonLabels: 25 | # someName: someValue 26 | 27 | bases: 28 | - ../crd 29 | - ../rbac 30 | - ../manager 31 | # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in 32 | # crd/kustomization.yaml 33 | - ../webhook 34 | # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required. 35 | - ../certmanager 36 | # [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. 37 | #- ../prometheus 38 | - ../service_account 39 | 40 | patchesStrategicMerge: 41 | # Protect the /metrics endpoint by putting it behind auth. 42 | # If you want your controller-manager to expose the /metrics 43 | # endpoint w/o any authn/z, please comment the following line. 44 | # - manager_auth_proxy_patch.yaml 45 | 46 | # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in 47 | # crd/kustomization.yaml 48 | # - manager_webhook_patch.yaml 49 | 50 | # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 51 | # Uncomment 'CERTMANAGER' sections in crd/kustomization.yaml to enable the CA injection in the admission webhooks. 52 | # 'CERTMANAGER' needs to be enabled to use ca injection 53 | - webhookcainjection_patch.yaml 54 | 55 | # the following config is for teaching kustomize how to do var substitution 56 | vars: 57 | # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix. 58 | - name: CERTIFICATE_NAMESPACE # namespace of the certificate CR 59 | objref: 60 | kind: Certificate 61 | group: cert-manager.io 62 | version: v1 63 | name: serving-cert # this name should match the one in certificate.yaml 64 | fieldref: 65 | fieldpath: metadata.namespace 66 | - name: CERTIFICATE_NAME 67 | objref: 68 | kind: Certificate 69 | group: cert-manager.io 70 | version: v1 71 | name: serving-cert # this name should match the one in certificate.yaml 72 | - name: SERVICE_NAMESPACE # namespace of the service 73 | objref: 74 | kind: Service 75 | version: v1 76 | name: webhook-service 77 | fieldref: 78 | fieldpath: metadata.namespace 79 | - name: SERVICE_NAME 80 | objref: 81 | kind: Service 82 | version: v1 83 | name: webhook-service 84 | -------------------------------------------------------------------------------- /config/default/manager_auth_proxy_patch.yaml: -------------------------------------------------------------------------------- 1 | # This patch inject a sidecar container which is a HTTP proxy for the 2 | # controller manager, it performs RBAC authorization against the Kubernetes API using SubjectAccessReviews. 3 | apiVersion: apps/v1 4 | kind: Deployment 5 | metadata: 6 | name: ibm-common-service-operator 7 | # namespace: ibm-common-services 8 | spec: 9 | template: 10 | spec: 11 | containers: 12 | - name: kube-rbac-proxy 13 | image: gcr.io/kubebuilder/kube-rbac-proxy:v0.5.0 14 | args: 15 | - "--secure-listen-address=0.0.0.0:8443" 16 | - "--upstream=http://127.0.0.1:8080/" 17 | - "--logtostderr=true" 18 | - "--v=10" 19 | ports: 20 | - containerPort: 8443 21 | name: https 22 | - name: manager 23 | args: 24 | - "--metrics-addr=127.0.0.1:8080" 25 | -------------------------------------------------------------------------------- /config/default/manager_webhook_patch.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: ibm-common-service-operator 5 | # namespace: ibm-common-services 6 | spec: 7 | template: 8 | spec: 9 | containers: 10 | - name: ibm-common-service-operator 11 | ports: 12 | - containerPort: 9443 13 | name: webhook-server 14 | protocol: TCP 15 | volumeMounts: 16 | - mountPath: /tmp/k8s-webhook-server/serving-certs 17 | name: cert 18 | readOnly: true 19 | volumes: 20 | - name: cert 21 | secret: 22 | defaultMode: 420 23 | secretName: webhook-server-cert 24 | -------------------------------------------------------------------------------- /config/default/webhookcainjection_patch.yaml: -------------------------------------------------------------------------------- 1 | # This patch add annotation to admission webhook config and 2 | # the variables $(CERTIFICATE_NAMESPACE) and $(CERTIFICATE_NAME) will be substituted by kustomize. 3 | apiVersion: admissionregistration.k8s.io/v1 4 | kind: MutatingWebhookConfiguration 5 | metadata: 6 | name: mutating-webhook-configuration 7 | annotations: 8 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 9 | 10 | --- 11 | apiVersion: admissionregistration.k8s.io/v1 12 | kind: ValidatingWebhookConfiguration 13 | metadata: 14 | name: validating-webhook-configuration 15 | annotations: 16 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) -------------------------------------------------------------------------------- /config/manager/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - manager.yaml 3 | apiVersion: kustomize.config.k8s.io/v1beta1 4 | kind: Kustomization 5 | images: 6 | - name: icr.io/cpopen/common-service-operator 7 | newName: icr.io/cpopen/common-service-operator 8 | newTag: 4.13.0 9 | -------------------------------------------------------------------------------- /config/manager/manager.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: ibm-common-service-operator 5 | # namespace: ibm-common-services 6 | labels: 7 | app.kubernetes.io/instance: "ibm-common-service-operator" 8 | app.kubernetes.io/managed-by: "ibm-common-service-operator" 9 | app.kubernetes.io/name: "ibm-common-service-operator" 10 | productName: IBM_Cloud_Platform_Common_Services 11 | spec: 12 | strategy: 13 | type: Recreate 14 | selector: 15 | matchLabels: 16 | name: ibm-common-service-operator 17 | replicas: 1 18 | template: 19 | metadata: 20 | labels: 21 | name: ibm-common-service-operator 22 | app.kubernetes.io/instance: ibm-common-service-operator 23 | app.kubernetes.io/managed-by: "ibm-common-service-operator" 24 | app.kubernetes.io/name: "ibm-common-service-operator" 25 | productName: IBM_Cloud_Platform_Common_Services 26 | annotations: 27 | productName: "IBM Cloud Platform Common Services" 28 | productID: "068a62892a1e4db39641342e592daa25" 29 | productMetric: "FREE" 30 | spec: 31 | serviceAccountName: ibm-common-service-operator 32 | affinity: 33 | nodeAffinity: 34 | requiredDuringSchedulingIgnoredDuringExecution: 35 | nodeSelectorTerms: 36 | - matchExpressions: 37 | - key: kubernetes.io/arch 38 | operator: In 39 | values: 40 | - amd64 41 | - ppc64le 42 | - s390x 43 | containers: 44 | - command: 45 | - /manager 46 | readinessProbe: 47 | httpGet: 48 | path: /readyz 49 | port: 8081 50 | initialDelaySeconds: 5 51 | timeoutSeconds: 20 52 | periodSeconds: 20 53 | failureThreshold: 10 54 | livenessProbe: 55 | httpGet: 56 | path: /healthz 57 | port: 8081 58 | initialDelaySeconds: 120 59 | timeoutSeconds: 10 60 | periodSeconds: 60 61 | failureThreshold: 10 62 | image: icr.io/cpopen/common-service-operator:latest 63 | imagePullPolicy: IfNotPresent 64 | name: ibm-common-service-operator 65 | env: 66 | - name: OPERATOR_NAMESPACE 67 | valueFrom: 68 | fieldRef: 69 | apiVersion: v1 70 | fieldPath: metadata.namespace 71 | - name: WATCH_NAMESPACE 72 | valueFrom: 73 | fieldRef: 74 | fieldPath: metadata.annotations['olm.targetNamespaces'] 75 | - name: OPERATOR_NAME 76 | value: "ibm-common-service-operator" 77 | - name: CPFS_UTILS_IMAGE 78 | value: icr.io/cpopen/cpfs/cpfs-utils:latest 79 | resources: 80 | limits: 81 | cpu: 500m 82 | memory: 512Mi 83 | requests: 84 | cpu: 100m 85 | memory: 200Mi 86 | ephemeral-storage: 256Mi 87 | securityContext: 88 | seccompProfile: 89 | type: RuntimeDefault 90 | allowPrivilegeEscalation: false 91 | capabilities: 92 | drop: 93 | - ALL 94 | privileged: false 95 | readOnlyRootFilesystem: true 96 | runAsNonRoot: true 97 | terminationGracePeriodSeconds: 10 98 | -------------------------------------------------------------------------------- /config/manager/non-olm-env-patch.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: ibm-common-service-operator 5 | spec: 6 | template: 7 | spec: 8 | containers: 9 | - name: ibm-common-service-operator 10 | env: 11 | - name: NO_OLM 12 | value: "true" 13 | - name: ENABLE_WEBHOOKS 14 | value: "false" -------------------------------------------------------------------------------- /config/manifests/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - ../default 3 | - ../samples 4 | - ../scorecard 5 | -------------------------------------------------------------------------------- /config/prometheus/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - monitor.yaml 3 | -------------------------------------------------------------------------------- /config/prometheus/monitor.yaml: -------------------------------------------------------------------------------- 1 | 2 | # Prometheus Monitor Service (Metrics) 3 | apiVersion: monitoring.coreos.com/v1 4 | kind: ServiceMonitor 5 | metadata: 6 | labels: 7 | control-plane: controller-manager 8 | name: controller-manager-metrics-monitor 9 | # namespace: ibm-common-services 10 | spec: 11 | endpoints: 12 | - path: /metrics 13 | port: https 14 | selector: 15 | matchLabels: 16 | control-plane: controller-manager 17 | -------------------------------------------------------------------------------- /config/rbac/auth_proxy_client_clusterrole.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1beta1 2 | kind: ClusterRole 3 | metadata: 4 | name: metrics-reader 5 | rules: 6 | - nonResourceURLs: ["/metrics"] 7 | verbs: ["get"] 8 | -------------------------------------------------------------------------------- /config/rbac/auth_proxy_role.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: proxy-role 5 | rules: 6 | - apiGroups: ["authentication.k8s.io"] 7 | resources: 8 | - tokenreviews 9 | verbs: ["create"] 10 | - apiGroups: ["authorization.k8s.io"] 11 | resources: 12 | - subjectaccessreviews 13 | verbs: ["create"] 14 | -------------------------------------------------------------------------------- /config/rbac/auth_proxy_role_binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: proxy-rolebinding 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: ClusterRole 8 | name: proxy-role 9 | subjects: 10 | - kind: ServiceAccount 11 | name: default 12 | namespace: ibm-common-services 13 | -------------------------------------------------------------------------------- /config/rbac/auth_proxy_service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | control-plane: controller-manager 6 | name: controller-manager-metrics-service 7 | # namespace: ibm-common-services 8 | spec: 9 | ports: 10 | - name: https 11 | port: 8443 12 | targetPort: https 13 | selector: 14 | control-plane: controller-manager 15 | -------------------------------------------------------------------------------- /config/rbac/commonservice_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit commonservices. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: commonservice-editor-role 6 | rules: 7 | - apiGroups: 8 | - operator.ibm.com 9 | resources: 10 | - commonservices 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - operator.ibm.com 21 | resources: 22 | - commonservices/status 23 | verbs: 24 | - get 25 | -------------------------------------------------------------------------------- /config/rbac/commonservice_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view commonservices. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: commonservice-viewer-role 6 | rules: 7 | - apiGroups: 8 | - operator.ibm.com 9 | resources: 10 | - commonservices 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - apiGroups: 16 | - operator.ibm.com 17 | resources: 18 | - commonservices/status 19 | verbs: 20 | - get 21 | -------------------------------------------------------------------------------- /config/rbac/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - role.yaml 3 | - role_binding.yaml 4 | # - leader_election_role.yaml 5 | # - leader_election_role_binding.yaml 6 | # Comment the following 4 lines if you want to disable 7 | # the auth proxy (https://github.com/brancz/kube-rbac-proxy) 8 | # which protects your /metrics endpoint. 9 | # - auth_proxy_service.yaml 10 | # - auth_proxy_role.yaml 11 | # - auth_proxy_role_binding.yaml 12 | # - auth_proxy_client_clusterrole.yaml 13 | -------------------------------------------------------------------------------- /config/rbac/leader_election_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions to do leader election. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: Role 4 | metadata: 5 | name: ibm-common-service-operator-leader-election-role 6 | rules: 7 | - apiGroups: 8 | - "" 9 | resources: 10 | - configmaps 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - create 16 | - update 17 | - patch 18 | - delete 19 | - apiGroups: 20 | - "" 21 | resources: 22 | - configmaps/status 23 | verbs: 24 | - get 25 | - update 26 | - patch 27 | - apiGroups: 28 | - "" 29 | resources: 30 | - events 31 | verbs: 32 | - create 33 | - patch 34 | -------------------------------------------------------------------------------- /config/rbac/leader_election_role_binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | name: ibm-common-service-operator-leader-election-rolebinding 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: Role 8 | name: ibm-common-service-operator-leader-election-role 9 | subjects: 10 | - kind: ServiceAccount 11 | name: ibm-common-service-operator 12 | namespace: ibm-common-services 13 | -------------------------------------------------------------------------------- /config/rbac/role.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: ibm-common-service-operator 5 | rules: 6 | # Manipulate ConfigMap in kube-public namespace 7 | - verbs: 8 | - delete 9 | - update 10 | apiGroups: 11 | - '' 12 | resources: 13 | - configmaps 14 | resourceNames: 15 | - common-service-maps 16 | - verbs: 17 | - delete 18 | apiGroups: 19 | - "" 20 | resources: 21 | - configmaps 22 | resourceNames: 23 | - cloud-native-postgresql-image-list 24 | - verbs: 25 | - create 26 | - get 27 | - list 28 | - watch 29 | - update 30 | apiGroups: 31 | - '' 32 | resources: 33 | - configmaps 34 | - verbs: 35 | - get 36 | apiGroups: 37 | - '' 38 | resources: 39 | - secrets 40 | # Get StorageClass from cluster 41 | - apiGroups: 42 | - storage.k8s.io 43 | resources: 44 | - storageclasses 45 | verbs: 46 | - get 47 | - list 48 | - watch 49 | # manage mutation webhook configuration 50 | - apiGroups: 51 | - admissionregistration.k8s.io 52 | resources: 53 | - mutatingwebhookconfigurations 54 | - validatingwebhookconfigurations 55 | verbs: 56 | - create 57 | - delete 58 | - get 59 | - list 60 | - patch 61 | - update 62 | - watch 63 | - verbs: 64 | - get 65 | apiGroups: 66 | - config.openshift.io 67 | resources: 68 | - infrastructures 69 | - apiGroups: 70 | - rbac.authorization.k8s.io 71 | resources: 72 | - clusterrolebindings 73 | - clusterroles 74 | verbs: 75 | - create 76 | - delete 77 | - get 78 | - list 79 | - patch 80 | - update 81 | - watch 82 | --- 83 | apiVersion: rbac.authorization.k8s.io/v1 84 | kind: Role 85 | metadata: 86 | name: ibm-common-service-operator 87 | rules: 88 | - apiGroups: 89 | - "" 90 | verbs: 91 | - delete 92 | - patch 93 | resources: 94 | - configmaps 95 | - apiGroups: 96 | - operator.ibm.com 97 | verbs: 98 | - create 99 | - delete 100 | - get 101 | - list 102 | - watch 103 | - patch 104 | resources: 105 | - namespacescopes 106 | - apiGroups: 107 | - cert-manager.io 108 | resources: 109 | - certificates 110 | - issuers 111 | verbs: 112 | - create 113 | - delete 114 | - get 115 | - list 116 | - watch 117 | - update 118 | - apiGroups: 119 | - apps 120 | resources: 121 | - deployments 122 | - statefulsets 123 | - daemonsets 124 | verbs: 125 | - delete 126 | - get 127 | - list 128 | - patch 129 | - update 130 | - watch 131 | - apiGroups: 132 | - operator.ibm.com 133 | resources: 134 | - commonservices 135 | - commonservices/finalizers 136 | - commonservices/status 137 | - operandconfigs 138 | - operandregistries 139 | - operatorconfigs 140 | verbs: 141 | - create 142 | - delete 143 | - get 144 | - list 145 | - patch 146 | - update 147 | - watch 148 | - apiGroups: 149 | - operators.coreos.com 150 | resources: 151 | - subscriptions 152 | - clusterserviceversions 153 | verbs: 154 | - create 155 | - delete 156 | - get 157 | - list 158 | - patch 159 | - update 160 | - watch 161 | - apiGroups: 162 | - '' 163 | resources: 164 | - namespaces 165 | verbs: 166 | - get 167 | - apiGroups: 168 | - '' 169 | resources: 170 | - pods 171 | verbs: 172 | - get 173 | - list 174 | - delete 175 | - apiGroups: 176 | - '' 177 | resources: 178 | - secrets 179 | - services 180 | verbs: 181 | - create 182 | - delete 183 | - get 184 | - list 185 | - patch 186 | - update 187 | - watch 188 | - apiGroups: 189 | - '' 190 | resources: 191 | - events 192 | verbs: 193 | - create 194 | - get 195 | - patch 196 | - update 197 | 198 | 199 | # handle clean up of deprecated objects 200 | - apiGroups: 201 | - certmanager.k8s.io 202 | resources: 203 | - certificates 204 | - issuers 205 | verbs: 206 | - delete 207 | - apiGroups: 208 | - monitoring.operator.ibm.com 209 | resources: 210 | - exporters 211 | - prometheusexts 212 | verbs: 213 | - delete 214 | - apiGroups: 215 | - operator.ibm.com 216 | resources: 217 | - operandrequests 218 | - operandbindinfos 219 | - cataloguis 220 | - helmapis 221 | - helmrepos 222 | verbs: 223 | - delete 224 | - apiGroups: 225 | - elasticstack.ibm.com 226 | resources: 227 | - elasticstacks 228 | verbs: 229 | - delete 230 | # Delete ServiceAccount, RoleBinding, Role, secretshares 231 | - apiGroups: 232 | - "" 233 | resources: 234 | - serviceaccounts 235 | verbs: 236 | - create 237 | - delete 238 | - get 239 | - list 240 | - patch 241 | - update 242 | - watch 243 | - apiGroups: 244 | - rbac.authorization.k8s.io 245 | resources: 246 | - rolebindings 247 | - roles 248 | verbs: 249 | - create 250 | - delete 251 | - get 252 | - list 253 | - patch 254 | - update 255 | - watch 256 | - apiGroups: 257 | - operator.ibm.com 258 | verbs: 259 | - get 260 | - delete 261 | - list 262 | resources: 263 | - podpresets 264 | - apiGroups: 265 | - ibmcpcs.ibm.com 266 | resources: 267 | - secretshares 268 | verbs: 269 | - create 270 | - delete 271 | - get 272 | - list 273 | - patch 274 | - update 275 | - watch 276 | - apiGroups: 277 | - postgresql.k8s.enterprisedb.io 278 | resources: 279 | - clusters 280 | verbs: 281 | - get 282 | - list -------------------------------------------------------------------------------- /config/rbac/role_binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | labels: 5 | app.kubernetes.io/instance: "ibm-common-service-operator" 6 | app.kubernetes.io/managed-by: "ibm-common-service-operator" 7 | app.kubernetes.io/name: "ibm-common-service-operator" 8 | name: ibm-common-service-operator 9 | roleRef: 10 | apiGroup: rbac.authorization.k8s.io 11 | kind: ClusterRole 12 | name: ibm-common-service-operator 13 | subjects: 14 | - kind: ServiceAccount 15 | name: ibm-common-service-operator 16 | namespace: ibm-common-services 17 | 18 | --- 19 | apiVersion: rbac.authorization.k8s.io/v1 20 | kind: RoleBinding 21 | metadata: 22 | labels: 23 | app.kubernetes.io/instance: "ibm-common-service-operator" 24 | app.kubernetes.io/managed-by: "ibm-common-service-operator" 25 | app.kubernetes.io/name: "ibm-common-service-operator" 26 | name: ibm-common-service-operator 27 | roleRef: 28 | apiGroup: rbac.authorization.k8s.io 29 | kind: Role 30 | name: ibm-common-service-operator 31 | subjects: 32 | - kind: ServiceAccount 33 | name: ibm-common-service-operator 34 | namespace: ibm-common-services -------------------------------------------------------------------------------- /config/rbac/service_account.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | labels: 5 | app.kubernetes.io/instance: "ibm-common-service-operator" 6 | app.kubernetes.io/managed-by: "ibm-common-service-operator" 7 | app.kubernetes.io/name: "ibm-common-service-operator" 8 | name: ibm-common-service-operator 9 | -------------------------------------------------------------------------------- /config/samples/kustomization.yaml: -------------------------------------------------------------------------------- 1 | ## This file is auto-generated, do not modify ## 2 | resources: 3 | - operator_v3_commonservice.yaml 4 | # +kubebuilder:scaffold:manifestskustomizesamples 5 | -------------------------------------------------------------------------------- /config/samples/operator_v3_commonservice.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: operator.ibm.com/v3 2 | kind: CommonService 3 | metadata: 4 | labels: 5 | app.kubernetes.io/instance: "ibm-common-service-operator" 6 | app.kubernetes.io/managed-by: "ibm-common-service-operator" 7 | app.kubernetes.io/name: "ibm-common-service-operator" 8 | name: example-commonservice 9 | spec: 10 | size: starterset 11 | -------------------------------------------------------------------------------- /config/scorecard/bases/config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: scorecard.operatorframework.io/v1alpha3 2 | kind: Configuration 3 | metadata: 4 | name: config 5 | stages: 6 | - parallel: true 7 | tests: [] 8 | -------------------------------------------------------------------------------- /config/scorecard/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - bases/config.yaml 3 | patchesJson6902: 4 | - path: patches/basic.config.yaml 5 | target: 6 | group: scorecard.operatorframework.io 7 | version: v1alpha3 8 | kind: Configuration 9 | name: config 10 | - path: patches/olm.config.yaml 11 | target: 12 | group: scorecard.operatorframework.io 13 | version: v1alpha3 14 | kind: Configuration 15 | name: config 16 | # +kubebuilder:scaffold:patchesJson6902 17 | -------------------------------------------------------------------------------- /config/scorecard/patches/basic.config.yaml: -------------------------------------------------------------------------------- 1 | - op: add 2 | path: /stages/0/tests/- 3 | value: 4 | entrypoint: 5 | - scorecard-test 6 | - basic-check-spec 7 | image: quay.io/operator-framework/scorecard-test:master 8 | labels: 9 | suite: basic 10 | test: basic-check-spec-test 11 | -------------------------------------------------------------------------------- /config/scorecard/patches/olm.config.yaml: -------------------------------------------------------------------------------- 1 | - op: add 2 | path: /stages/0/tests/- 3 | value: 4 | entrypoint: 5 | - scorecard-test 6 | - olm-bundle-validation 7 | image: quay.io/operator-framework/scorecard-test:master 8 | labels: 9 | suite: olm 10 | test: olm-bundle-validation-test 11 | - op: add 12 | path: /stages/0/tests/- 13 | value: 14 | entrypoint: 15 | - scorecard-test 16 | - olm-crds-have-validation 17 | image: quay.io/operator-framework/scorecard-test:master 18 | labels: 19 | suite: olm 20 | test: olm-crds-have-validation-test 21 | # - op: add 22 | # path: /stages/0/tests/- 23 | # value: 24 | # entrypoint: 25 | # - scorecard-test 26 | # - olm-crds-have-resources 27 | # image: quay.io/operator-framework/scorecard-test:master 28 | # labels: 29 | # suite: olm 30 | # test: olm-crds-have-resources-test 31 | - op: add 32 | path: /stages/0/tests/- 33 | value: 34 | entrypoint: 35 | - scorecard-test 36 | - olm-spec-descriptors 37 | image: quay.io/operator-framework/scorecard-test:master 38 | labels: 39 | suite: olm 40 | test: olm-spec-descriptors-test 41 | # - op: add 42 | # path: /stages/0/tests/- 43 | # value: 44 | # entrypoint: 45 | # - scorecard-test 46 | # - olm-status-descriptors 47 | # image: quay.io/operator-framework/scorecard-test:master 48 | # labels: 49 | # suite: olm 50 | # test: olm-status-descriptors-test 51 | -------------------------------------------------------------------------------- /config/service_account/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - service_account.yaml -------------------------------------------------------------------------------- /config/service_account/service_account.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: ibm-common-service-operator -------------------------------------------------------------------------------- /config/webhook/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - manifests.yaml 3 | - service.yaml 4 | 5 | configurations: 6 | - kustomizeconfig.yaml 7 | -------------------------------------------------------------------------------- /config/webhook/kustomizeconfig.yaml: -------------------------------------------------------------------------------- 1 | # the following config is for teaching kustomize where to look at when substituting vars. 2 | # It requires kustomize v2.1.0 or newer to work properly. 3 | nameReference: 4 | - kind: Service 5 | version: v1 6 | fieldSpecs: 7 | - kind: MutatingWebhookConfiguration 8 | group: admissionregistration.k8s.io 9 | path: webhooks/clientConfig/service/name 10 | - kind: ValidatingWebhookConfiguration 11 | group: admissionregistration.k8s.io 12 | path: webhooks/clientConfig/service/name 13 | 14 | namespace: 15 | - kind: MutatingWebhookConfiguration 16 | group: admissionregistration.k8s.io 17 | path: webhooks/clientConfig/service/namespace 18 | create: true 19 | - kind: ValidatingWebhookConfiguration 20 | group: admissionregistration.k8s.io 21 | path: webhooks/clientConfig/service/namespace 22 | create: true 23 | 24 | varReference: 25 | - path: metadata/annotations 26 | -------------------------------------------------------------------------------- /config/webhook/manifests.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: admissionregistration.k8s.io/v1 3 | kind: MutatingWebhookConfiguration 4 | metadata: 5 | name: mutating-webhook-configuration 6 | webhooks: 7 | - admissionReviewVersions: 8 | - v1 9 | clientConfig: 10 | service: 11 | name: webhook-service 12 | namespace: system 13 | path: /mutate-operator-ibm-com-v1alpha1-operandrequest 14 | failurePolicy: Ignore 15 | name: moperandrequest.kb.io 16 | rules: 17 | - apiGroups: 18 | - operator.ibm.com 19 | apiVersions: 20 | - v1alpha1 21 | operations: 22 | - CREATE 23 | - UPDATE 24 | resources: 25 | - operandrequests 26 | sideEffects: None 27 | --- 28 | apiVersion: admissionregistration.k8s.io/v1 29 | kind: ValidatingWebhookConfiguration 30 | metadata: 31 | name: validating-webhook-configuration 32 | webhooks: 33 | - admissionReviewVersions: 34 | - v1 35 | clientConfig: 36 | service: 37 | name: webhook-service 38 | namespace: system 39 | path: /validate-operator-ibm-com-v3-commonservice 40 | failurePolicy: Fail 41 | name: vcommonservice.kb.io 42 | rules: 43 | - apiGroups: 44 | - operator.ibm.com 45 | apiVersions: 46 | - v3 47 | operations: 48 | - CREATE 49 | - UPDATE 50 | resources: 51 | - commonservices 52 | sideEffects: None 53 | -------------------------------------------------------------------------------- /config/webhook/service.yaml: -------------------------------------------------------------------------------- 1 | 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: webhook-service 6 | # namespace: ibm-common-services 7 | spec: 8 | ports: 9 | - port: 443 10 | targetPort: 9443 11 | selector: 12 | control-plane: controller-manager 13 | -------------------------------------------------------------------------------- /docs/design.md: -------------------------------------------------------------------------------- 1 | # Design 2 | 3 | IBM Common Service Operator is designed as the entrance of the IBM Common Services. 4 | 5 | There are multiple individual services in IBM Common Services, we need a method to unify the installation of these individual services. 6 | 7 | A single cluster can have multiple IBM Common Service Operator installed, and all these operators have same function. 8 | 9 | This Operator is a minimal operator that only have a single API and no controller, it will create/update the IBM Common Services related Kubernetes resources during the start of Operator process. 10 | 11 | It will: 12 | 13 | * create the `ibm-common-services` namespace, all the individual services will be installed into this namespace 14 | * create the `operand-deployment-lifecycle-manager` subscription which will trigger the ODLM to be installed in all namespaces mode 15 | * create the `OperandConfig` and `OperandRegistry` of IBM Common Services under `ibm-common-services` namespace which tells the individual service configuration and location, later users can manually create `OperandRequest` to trigger the installation 16 | * create extra Kubernetes resources, there is a `build/resources/extra` directory, putting Kuberentes resource YAML files to this directory, the operator will automatically create them(note: one YAML file should only contain one Kubernetes resource) 17 | 18 | The main logic is inside [pkg/bootstrap/init.go](/pkg/bootstrap/init.go) file. 19 | -------------------------------------------------------------------------------- /docs/images/create-catalog-source.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM/ibm-common-service-operator/34b3d3fb70108852ef6aac2cc1e972f164853d4c/docs/images/create-catalog-source.png -------------------------------------------------------------------------------- /docs/images/create-project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM/ibm-common-service-operator/34b3d3fb70108852ef6aac2cc1e972f164853d4c/docs/images/create-project.png -------------------------------------------------------------------------------- /docs/images/install-operator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM/ibm-common-service-operator/34b3d3fb70108852ef6aac2cc1e972f164853d4c/docs/images/install-operator.png -------------------------------------------------------------------------------- /docs/images/installed-operators.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM/ibm-common-service-operator/34b3d3fb70108852ef6aac2cc1e972f164853d4c/docs/images/installed-operators.png -------------------------------------------------------------------------------- /docs/images/manage-operators.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM/ibm-common-service-operator/34b3d3fb70108852ef6aac2cc1e972f164853d4c/docs/images/manage-operators.png -------------------------------------------------------------------------------- /docs/images/search-operator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM/ibm-common-service-operator/34b3d3fb70108852ef6aac2cc1e972f164853d4c/docs/images/search-operator.png -------------------------------------------------------------------------------- /docs/uninstall.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | **Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* 4 | 5 | - [Uninstall IBM Common Services](#uninstall-ibm-common-services) 6 | - [Delete OperandRequest Created by CloudPaks](#delete-operandrequest-created-by-cloudpaks) 7 | - [Clean up environment (Optional)](#clean-up-environment-optional) 8 | - [Clean up OperandConfig and OperandRegistry](#clean-up-operandconfig-and-operandregistry) 9 | - [Clean up `IBM Common Service Operator` and `Operand Deployment Lifecycle Manager`](#clean-up-ibm-common-service-operator-and-operand-deployment-lifecycle-manager) 10 | 11 | 12 | 13 | # Uninstall IBM Common Services 14 | 15 | ## Delete OperandRequest Created by CloudPaks 16 | 17 | Users can use the following steps to remove the services deployed by `IBM Common Service Operator`. 18 | 19 | 1. Log in to your OpenShift cluster console. 20 | 21 | 2. Access the `OperandRequest` API. Click Operators > Installed Operators and switch to the namespace you create `OperandRequest`. 22 | 23 | 3. Click `Operand Deployment Lifecycle Manager` > `OperandRequest` and delete the OperandRequest instances you create. When an OperandRequest instance is deleted, the services that are requested by this OperandRequest instance are deleted unless the service is requested by other OperandRequest instances. 24 | 25 | ## Clean up environment (Optional) 26 | 27 | **Note:** The following steps is for cleaning up `IBM Common Service Operator` and `Operand Deployment Lifecycle Manager`. You can only clean up them when you make sure, no other CloudPaks are using them. 28 | 29 | ### Clean up OperandConfig and OperandRegistry 30 | 31 | Delete the OperandConfig API. 32 | 33 | Click `Operators` > `Installed Operators` and switch to namespace `ibm-common-services` 34 | 35 | Click `Operand Deployment Lifecycle Manager` > `OperandConfig` and delete all the OperandConfig instances. 36 | 37 | Then Click `OperandRegistry` and delete all the `OperandRegistry` instances. 38 | 39 | ### Clean up `IBM Common Service Operator` and `Operand Deployment Lifecycle Manager` 40 | 41 | - Uninstall the `Operand Deployment Lifecycle Manager`. 42 | 43 | Click Operators > Installed Operators and switch to namespace `openshift-operators`. 44 | 45 | Click the overflow menu icon and click Uninstall Operator. 46 | 47 | - Uninstall the `IBM Common Service Operator` operator. 48 | 49 | Click Operators > Installed Operators and switch to namespace that CloudPaks deployed `IBM Common Service Operator`. 50 | 51 | Click the overflow menu icon and click Uninstall Operator. 52 | 53 | - Remove `ibm-common-services` namespace. 54 | 55 | Click Projects and delete project `ibm-common-services`. 56 | 57 | - Remove the RBAC for `ibmcloud-cluster-info` 58 | 59 | Click `User Management` > `Role Bindings` and switch to `kube-public` namespace. 60 | Search and delete all the `Role Bindings` with the name `ibmcloud-cluster-info`. 61 | 62 | Click `User Management` > `Roles` and switch to `kube-public` namespace. 63 | Search and delete the `Roles` with the name `ibmcloud-cluster-info`. 64 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/IBM/ibm-common-service-operator/v4 2 | 3 | go 1.23.0 4 | 5 | toolchain go1.23.4 6 | 7 | require ( 8 | github.com/IBM/controller-filtered-cache v0.3.5 9 | github.com/IBM/ibm-namespace-scope-operator/v4 v4.2.4-0.20240501132320-6675f97bc34f 10 | github.com/IBM/ibm-secretshare-operator v1.20.3 11 | github.com/IBM/operand-deployment-lifecycle-manager/v4 v4.3.11-alpha 12 | github.com/ghodss/yaml v1.0.0 13 | github.com/ibm/ibm-cert-manager-operator v0.0.0-20230705134954-f3b9b344298a 14 | github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 15 | github.com/onsi/ginkgo v1.16.5 16 | github.com/onsi/gomega v1.19.0 17 | github.com/operator-framework/api v0.6.2 18 | github.com/operator-framework/operator-lifecycle-manager v0.17.0 19 | github.com/stretchr/testify v1.9.0 20 | k8s.io/api v0.24.3 21 | k8s.io/apimachinery v0.24.17 22 | k8s.io/client-go v0.24.3 23 | k8s.io/klog v1.0.0 24 | sigs.k8s.io/controller-runtime v0.12.3 25 | ) 26 | 27 | require ( 28 | cloud.google.com/go/compute v1.23.0 // indirect 29 | cloud.google.com/go/compute/metadata v0.2.3 // indirect 30 | github.com/PuerkitoBio/purell v1.1.1 // indirect 31 | github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect 32 | github.com/beorn7/perks v1.0.1 // indirect 33 | github.com/blang/semver v3.5.1+incompatible // indirect 34 | github.com/blang/semver/v4 v4.0.0 // indirect 35 | github.com/cespare/xxhash/v2 v2.2.0 // indirect 36 | github.com/davecgh/go-spew v1.1.1 // indirect 37 | github.com/deckarep/golang-set v1.7.1 // indirect 38 | github.com/emicklei/go-restful/v3 v3.10.0 // indirect 39 | github.com/evanphx/json-patch v4.12.0+incompatible // indirect 40 | github.com/fsnotify/fsnotify v1.5.4 // indirect 41 | github.com/go-logr/logr v1.2.3 // indirect 42 | github.com/go-logr/zapr v1.2.0 // indirect 43 | github.com/go-openapi/jsonpointer v0.19.5 // indirect 44 | github.com/go-openapi/jsonreference v0.19.5 // indirect 45 | github.com/go-openapi/swag v0.19.14 // indirect 46 | github.com/gobuffalo/flect v0.2.1 // indirect 47 | github.com/gogo/protobuf v1.3.2 // indirect 48 | github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect 49 | github.com/golang/protobuf v1.5.3 // indirect 50 | github.com/google/gnostic v0.6.9 // indirect 51 | github.com/google/go-cmp v0.5.9 // indirect 52 | github.com/google/gofuzz v1.1.0 // indirect 53 | github.com/google/uuid v1.3.1 // indirect 54 | github.com/imdario/mergo v0.3.12 // indirect 55 | github.com/josharian/intern v1.0.0 // indirect 56 | github.com/json-iterator/go v1.1.12 // indirect 57 | github.com/mailru/easyjson v0.7.6 // indirect 58 | github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect 59 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 60 | github.com/modern-go/reflect2 v1.0.2 // indirect 61 | github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect 62 | github.com/nxadm/tail v1.4.8 // indirect 63 | github.com/operator-framework/operator-registry v1.13.6 // indirect 64 | github.com/pkg/errors v0.9.1 // indirect 65 | github.com/pmezard/go-difflib v1.0.0 // indirect 66 | github.com/prometheus/client_golang v1.12.2 // indirect 67 | github.com/prometheus/client_model v0.2.0 // indirect 68 | github.com/prometheus/common v0.32.1 // indirect 69 | github.com/prometheus/procfs v0.7.3 // indirect 70 | github.com/sirupsen/logrus v1.9.3 // indirect 71 | github.com/spf13/pflag v1.0.5 // indirect 72 | go.uber.org/atomic v1.7.0 // indirect 73 | go.uber.org/multierr v1.6.0 // indirect 74 | go.uber.org/zap v1.19.1 // indirect 75 | golang.org/x/mod v0.17.0 76 | golang.org/x/net v0.38.0 // indirect 77 | golang.org/x/oauth2 v0.11.0 // indirect 78 | golang.org/x/sys v0.31.0 // indirect 79 | golang.org/x/term v0.30.0 // indirect 80 | golang.org/x/text v0.23.0 // indirect 81 | golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect 82 | gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect 83 | google.golang.org/appengine v1.6.7 // indirect 84 | google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect 85 | google.golang.org/grpc v1.59.0 // indirect 86 | google.golang.org/protobuf v1.33.0 // indirect 87 | gopkg.in/inf.v0 v0.9.1 // indirect 88 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect 89 | gopkg.in/yaml.v2 v2.4.0 // indirect 90 | gopkg.in/yaml.v3 v3.0.1 // indirect 91 | k8s.io/apiextensions-apiserver v0.24.2 // indirect 92 | k8s.io/component-base v0.24.2 // indirect 93 | k8s.io/klog/v2 v2.60.1 // indirect 94 | k8s.io/kube-openapi v0.0.0-20220627174259-011e075b9cb8 // indirect 95 | k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect 96 | sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect 97 | sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect 98 | sigs.k8s.io/yaml v1.3.0 // indirect 99 | ) 100 | 101 | // fix vulnerability: CVE-2021-3121 in github.com/gogo/protobuf < v1.3.2 102 | replace github.com/gogo/protobuf => github.com/gogo/protobuf v1.3.2 103 | -------------------------------------------------------------------------------- /hack/boilerplate.go.txt: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2022 IBM Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | -------------------------------------------------------------------------------- /hack/keycloak-themes/.gitignore: -------------------------------------------------------------------------------- 1 | cloudpak-theme.jar 2 | -------------------------------------------------------------------------------- /hack/keycloak-themes/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Created-By: 11.0.13 (International Business Machines Corporation) 3 | 4 | -------------------------------------------------------------------------------- /hack/keycloak-themes/META-INF/keycloak-themes.json: -------------------------------------------------------------------------------- 1 | { 2 | "themes": [{ 3 | "name" : "cloudpak", 4 | "types": [ "login", "account", "admin", "email", "common" ] 5 | }] 6 | } 7 | -------------------------------------------------------------------------------- /hack/keycloak-themes/Makefile: -------------------------------------------------------------------------------- 1 | KEYCLOAK_THEME_DIR ?= $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) 2 | JAR_THEME_FILE ?= cloudpak-theme.jar 3 | 4 | default: cloudpak-theme.jar 5 | 6 | .PHONY: cloudpak-theme.jar 7 | cloudpak-theme.jar: 8 | @echo "Building the keycloak jar theme..." 9 | rm $(KEYCLOAK_THEME_DIR)/$(JAR_THEME_FILE) || true 10 | (cd $(KEYCLOAK_THEME_DIR) && zip -r ./$(JAR_THEME_FILE) META-INF theme) 11 | 12 | cloudpak-theme-version: 13 | $(eval THEME_VERSION := $(shell ls $(KEYCLOAK_THEME_DIR)/theme/cloudpak/login/resources/css/ | grep .css)) 14 | @echo "Updating the keycloak jar theme version to $(THEME_VERSION)" 15 | $(YQ) eval -i '.spec.template.metadata.annotations.cloudPakThemesVersion = "$(THEME_VERSION)"' $(KEYCLOAK_THEME_DIR)/../../testdata/deploy/deploy.yaml 16 | $(YQ) eval -i '.metadata.annotations.cloudPakThemesVersion = "$(THEME_VERSION)"' $(KEYCLOAK_THEME_DIR)/../../config/manifests/bases/ibm-common-service-operator.clusterserviceversion.yaml 17 | $(YQ) eval -i '.metadata.annotations.cloudPakThemesVersion = "$(THEME_VERSION)"' $(KEYCLOAK_THEME_DIR)/../../bundle/manifests/ibm-common-service-operator.clusterserviceversion.yaml -------------------------------------------------------------------------------- /hack/keycloak-themes/README.md: -------------------------------------------------------------------------------- 1 | # keycloak-themes 2 | 3 | A Keycloak theme for IBM Cloud Paks. 4 | 5 | See https://www.keycloak.org/docs/latest/server_development/index.html#_themes 6 | 7 | **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`.** 8 | For example, for CS 4.6: 9 | theme/cloudpak/login/resources/css/styles470.css 10 | theme/cloudpak/login/theme.properies styles=css/styles470.css 11 | NOTE: this would likely apply to any of the files - images, fonts, etc. If updated, they must be renamed. 12 | 13 | ### Style version for release 4.11.0 14 | theme/cloudpak/login/resources/css/styles4100.css 15 | theme/cloudpak/login/theme.properies styles=css/styles4100.css 16 | 17 | ## Testing 18 | 19 | Easiest way to play with it is to mount it into a local keycloak dev container. 20 | 21 | 1. Run the container: 22 | 23 | ``` 24 | 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 25 | ``` 26 | 27 | 1. Log into Keycloak with your chosen admin password at http://localhost:8080/ 28 | 29 | 1. Create a realm 30 | 31 | 1. Assign the theme to the realm 32 | 33 | Any changes you make will be immediately visible, although you might need to force refresh to avoid caching. 34 | 35 | ## Developing 36 | 37 | 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. 38 | 39 | 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. 40 | 41 | 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. 42 | -------------------------------------------------------------------------------- /hack/keycloak-themes/theme/cloudpak/account/theme.properties: -------------------------------------------------------------------------------- 1 | parent=keycloak.v2 2 | import=common/cloudpak 3 | deprecatedMode=false 4 | 5 | developmentMode=false 6 | 7 | # This is the logo in upper lefthand corner. 8 | # It must be a relative path. 9 | logo=/img/logo.svg 10 | 11 | # This is the link followed when clicking on the logo. 12 | # It can be any valid URL, including an external site. 13 | logoUrl=./ 14 | 15 | # This is the icon for the account console. 16 | # It must be a relative path. 17 | favIcon=/img/favicon.ico 18 | -------------------------------------------------------------------------------- /hack/keycloak-themes/theme/cloudpak/admin/theme.properties: -------------------------------------------------------------------------------- 1 | parent=keycloak.v2 2 | import=common/cloudpak 3 | deprecatedMode=false 4 | 5 | developmentMode=false 6 | 7 | # This is the logo in upper lefthand corner. 8 | # It must be a relative path. 9 | logo=/img/logo.svg 10 | 11 | # This is the link followed when clicking on the logo. 12 | # It can be any valid URL, including an external site. 13 | logoUrl=./ 14 | 15 | # This is the icon for the account console. 16 | # It must be a relative path. 17 | favIcon=/img/favicon.ico 18 | -------------------------------------------------------------------------------- /hack/keycloak-themes/theme/cloudpak/common/resources/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM/ibm-common-service-operator/34b3d3fb70108852ef6aac2cc1e972f164853d4c/hack/keycloak-themes/theme/cloudpak/common/resources/img/favicon.ico -------------------------------------------------------------------------------- /hack/keycloak-themes/theme/cloudpak/email/theme.properties: -------------------------------------------------------------------------------- 1 | parent=base 2 | -------------------------------------------------------------------------------- /hack/keycloak-themes/theme/cloudpak/login/messages/messages_de.properties: -------------------------------------------------------------------------------- 1 | usernameOrEmail=Benutzername 2 | loginAccountTitle=Anmelden 3 | doLogIn=Anmelden 4 | identity-provider-login-label=Alternative Anmeldungen 5 | loginProfileTitle=Kontoinformationen aktualisieren 6 | loginIdpReviewProfileTitle=Kontoinformationen aktualisieren 7 | doForgotPassword=Kennwort vergessen? 8 | -------------------------------------------------------------------------------- /hack/keycloak-themes/theme/cloudpak/login/messages/messages_en.properties: -------------------------------------------------------------------------------- 1 | usernameOrEmail=Username 2 | loginAccountTitle=Log in 3 | doLogIn=Log in 4 | identity-provider-login-label=Alternative logins 5 | loginProfileTitle=Update account information 6 | loginIdpReviewProfileTitle=Update account information 7 | doForgotPassword=Forgot password? 8 | -------------------------------------------------------------------------------- /hack/keycloak-themes/theme/cloudpak/login/messages/messages_es.properties: -------------------------------------------------------------------------------- 1 | usernameOrEmail=Nombre de usuario 2 | loginAccountTitle=Iniciar sesión 3 | doLogIn=Iniciar sesión 4 | identity-provider-login-label=Inicios de sesión alternativos 5 | loginProfileTitle=Actualizar información de cuenta 6 | loginIdpReviewProfileTitle=Actualizar información de cuenta 7 | doForgotPassword=¿Ha olvidado la contraseña? 8 | -------------------------------------------------------------------------------- /hack/keycloak-themes/theme/cloudpak/login/messages/messages_fr.properties: -------------------------------------------------------------------------------- 1 | usernameOrEmail=Nom d''utilisateur 2 | loginAccountTitle=Connexion 3 | doLogIn=Connexion 4 | identity-provider-login-label=Connexions alternatives 5 | loginProfileTitle=Mettre à jour les informations de compte 6 | loginIdpReviewProfileTitle=Mettre à jour les informations de compte 7 | doForgotPassword=Mot de passe oublié ? 8 | -------------------------------------------------------------------------------- /hack/keycloak-themes/theme/cloudpak/login/messages/messages_it.properties: -------------------------------------------------------------------------------- 1 | usernameOrEmail=Nome utente 2 | loginAccountTitle=Accedi 3 | doLogIn=Accedi 4 | identity-provider-login-label=Accessi alternativi 5 | loginProfileTitle=Aggiorna informazioni sull''account 6 | loginIdpReviewProfileTitle=Aggiorna informazioni sull''account 7 | doForgotPassword=Hai dimenticato la password? 8 | -------------------------------------------------------------------------------- /hack/keycloak-themes/theme/cloudpak/login/messages/messages_ja.properties: -------------------------------------------------------------------------------- 1 | usernameOrEmail=ユーザー名 2 | loginAccountTitle=ログイン 3 | doLogIn=ログイン 4 | identity-provider-login-label=代替ログイン 5 | loginProfileTitle=アカウント情報の更新 6 | loginIdpReviewProfileTitle=アカウント情報の更新 7 | doForgotPassword=パスワードを忘れましたか? 8 | -------------------------------------------------------------------------------- /hack/keycloak-themes/theme/cloudpak/login/messages/messages_ko.properties: -------------------------------------------------------------------------------- 1 | usernameOrEmail=사용자 이름 2 | loginAccountTitle=로그인 3 | doLogIn=로그인 4 | identity-provider-login-label=대체 로그인 5 | loginProfileTitle=계정 정보 업데이트 6 | loginIdpReviewProfileTitle=계정 정보 업데이트 7 | doForgotPassword=비밀번호를 잊으셨습니까? 8 | -------------------------------------------------------------------------------- /hack/keycloak-themes/theme/cloudpak/login/messages/messages_pt_BR.properties: -------------------------------------------------------------------------------- 1 | usernameOrEmail=Nome do usuário 2 | loginAccountTitle=Efetuar login 3 | doLogIn=Efetuar login 4 | identity-provider-login-label=Logins alternativos 5 | loginProfileTitle=Atualizar informações da conta 6 | loginIdpReviewProfileTitle=Atualizar informações da conta 7 | doForgotPassword=Esqueceu a senha? 8 | -------------------------------------------------------------------------------- /hack/keycloak-themes/theme/cloudpak/login/messages/messages_zh_CN.properties: -------------------------------------------------------------------------------- 1 | usernameOrEmail=用户名 2 | loginAccountTitle=登录 3 | doLogIn=登录 4 | identity-provider-login-label=备用登录 5 | loginProfileTitle=更新帐户信息 6 | loginIdpReviewProfileTitle=更新帐户信息 7 | doForgotPassword=忘记密码? 8 | -------------------------------------------------------------------------------- /hack/keycloak-themes/theme/cloudpak/login/messages/messages_zh_TW.properties: -------------------------------------------------------------------------------- 1 | usernameOrEmail=使用者名稱 2 | loginAccountTitle=登入 3 | doLogIn=登入 4 | identity-provider-login-label=替代登入 5 | loginProfileTitle=更新帳戶資訊 6 | loginIdpReviewProfileTitle=更新帳戶資訊 7 | doForgotPassword=忘記密碼? 8 | -------------------------------------------------------------------------------- /hack/keycloak-themes/theme/cloudpak/login/resources/fonts/IBMPlexSans-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM/ibm-common-service-operator/34b3d3fb70108852ef6aac2cc1e972f164853d4c/hack/keycloak-themes/theme/cloudpak/login/resources/fonts/IBMPlexSans-Regular.woff -------------------------------------------------------------------------------- /hack/keycloak-themes/theme/cloudpak/login/resources/fonts/IBMPlexSans-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM/ibm-common-service-operator/34b3d3fb70108852ef6aac2cc1e972f164853d4c/hack/keycloak-themes/theme/cloudpak/login/resources/fonts/IBMPlexSans-Regular.woff2 -------------------------------------------------------------------------------- /hack/keycloak-themes/theme/cloudpak/login/resources/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM/ibm-common-service-operator/34b3d3fb70108852ef6aac2cc1e972f164853d4c/hack/keycloak-themes/theme/cloudpak/login/resources/img/favicon.ico -------------------------------------------------------------------------------- /hack/keycloak-themes/theme/cloudpak/login/resources/img/login-header.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /hack/keycloak-themes/theme/cloudpak/login/resources/img/view--off.svg: -------------------------------------------------------------------------------- 1 | view--off -------------------------------------------------------------------------------- /hack/keycloak-themes/theme/cloudpak/login/resources/img/view.svg: -------------------------------------------------------------------------------- 1 | view -------------------------------------------------------------------------------- /hack/keycloak-themes/theme/cloudpak/login/theme.properties: -------------------------------------------------------------------------------- 1 | parent=keycloak 2 | import=common/keycloak 3 | 4 | styles=css/styles4100.css 5 | locales=en,de,es,fr,it,ja,ko,pt_BR,zh_CN,zh_TW -------------------------------------------------------------------------------- /helm-cluster-scoped/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: ibm-common-service-operator-cluster-scoped 3 | description: A Helm chart for ibm-common-service-operator 4 | type: application 5 | version: 4.13.0 6 | appVersion: 4.13.0 -------------------------------------------------------------------------------- /helm-cluster-scoped/templates/cluster-rbac.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: ibm-common-service-operator-{{ .Values.global.operatorNamespace }} 5 | labels: 6 | component-id: {{ .Chart.Name }} 7 | rules: 8 | - apiGroups: 9 | - "" 10 | resourceNames: 11 | - common-service-maps 12 | resources: 13 | - configmaps 14 | verbs: 15 | - delete 16 | - update 17 | - apiGroups: 18 | - "" 19 | resourceNames: 20 | - cloud-native-postgresql-image-list 21 | resources: 22 | - configmaps 23 | verbs: 24 | - delete 25 | - apiGroups: 26 | - "" 27 | resources: 28 | - configmaps 29 | verbs: 30 | - create 31 | - get 32 | - list 33 | - watch 34 | - update 35 | - apiGroups: 36 | - "" 37 | resources: 38 | - secrets 39 | verbs: 40 | - get 41 | - apiGroups: 42 | - storage.k8s.io 43 | resources: 44 | - storageclasses 45 | verbs: 46 | - get 47 | - list 48 | - watch 49 | - apiGroups: 50 | - admissionregistration.k8s.io 51 | resources: 52 | - mutatingwebhookconfigurations 53 | - validatingwebhookconfigurations 54 | verbs: 55 | - create 56 | - delete 57 | - get 58 | - list 59 | - patch 60 | - update 61 | - watch 62 | - apiGroups: 63 | - config.openshift.io 64 | resources: 65 | - infrastructures 66 | verbs: 67 | - get 68 | - apiGroups: 69 | - rbac.authorization.k8s.io 70 | resources: 71 | - clusterrolebindings 72 | - clusterroles 73 | verbs: 74 | - create 75 | - delete 76 | - get 77 | - list 78 | - patch 79 | - update 80 | - watch 81 | --- 82 | apiVersion: rbac.authorization.k8s.io/v1 83 | kind: ClusterRoleBinding 84 | metadata: 85 | name: ibm-common-service-operator-{{ .Values.global.operatorNamespace }} 86 | labels: 87 | component-id: {{ .Chart.Name }} 88 | roleRef: 89 | kind: ClusterRole 90 | apiGroup: rbac.authorization.k8s.io 91 | name: ibm-common-service-operator-{{ .Values.global.operatorNamespace }} 92 | subjects: 93 | - kind: ServiceAccount 94 | name: ibm-common-service-operator 95 | namespace: {{ .Values.global.operatorNamespace }} 96 | 97 | --- 98 | -------------------------------------------------------------------------------- /helm-cluster-scoped/templates/cluster-webhook.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IBM/ibm-common-service-operator/34b3d3fb70108852ef6aac2cc1e972f164853d4c/helm-cluster-scoped/templates/cluster-webhook.yaml -------------------------------------------------------------------------------- /helm-cluster-scoped/values.yaml: -------------------------------------------------------------------------------- 1 | # Note there are no leading or trailing /'s 2 | cpfs: 3 | imageRegistryNamespaceOperator: cpopen 4 | imageRegistryNamespaceOperand: cpopen/cpfs 5 | 6 | global: 7 | operatorNamespace: operator-ns 8 | 9 | -------------------------------------------------------------------------------- /helm/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: ibm-common-service-operator 3 | description: A Helm chart for ibm-common-service-operator 4 | type: application 5 | version: 4.13.0 6 | appVersion: 4.13.0 -------------------------------------------------------------------------------- /helm/templates/operator-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: ibm-common-service-operator 5 | namespace: {{ .Values.global.operatorNamespace }} 6 | labels: 7 | component-id: {{ .Chart.Name }} 8 | {{- with .Values.cpfs.labels }} 9 | {{- toYaml . | nindent 4 }} 10 | {{- end }} 11 | annotations: 12 | alm-examples: | 13 | [ 14 | { 15 | "apiVersion": "operator.ibm.com/v3", 16 | "kind": "CommonService", 17 | "metadata": { 18 | "labels": { 19 | "component-id": "{{ .Chart.Name }}", 20 | "foundationservices.cloudpak.ibm.com": "commonservice" 21 | {{- range $key, $val := .Values.cpfs.labels }} 22 | , 23 | "{{ $key }}": "{{ $val }}" 24 | {{- end}} 25 | }, 26 | "annotations": { 27 | "apiVersion": "-1" 28 | }, 29 | "name": "common-service", 30 | "namespace": "{{ .Values.global.operatorNamespace }}" 31 | }, 32 | "spec": { 33 | "license": { 34 | "accept": {{ .Values.global.licenseAccept | default "false" }} 35 | }, 36 | "operatorNamespace": "{{ .Values.global.operatorNamespace }}", 37 | "servicesNamespace": "{{ .Values.global.instanceNamespace }}", 38 | "size": "{{ .Values.cpfs.size }}", 39 | "storageClass": "{{ .Values.global.blockStorageClass }}" 40 | } 41 | } 42 | ] 43 | spec: 44 | replicas: 1 45 | selector: 46 | matchLabels: 47 | name: ibm-common-service-operator 48 | strategy: 49 | type: Recreate 50 | template: 51 | metadata: 52 | annotations: 53 | productID: 068a62892a1e4db39641342e592daa25 54 | productMetric: FREE 55 | productName: IBM Cloud Platform Common Services 56 | labels: 57 | app.kubernetes.io/instance: ibm-common-service-operator 58 | app.kubernetes.io/managed-by: ibm-common-service-operator 59 | app.kubernetes.io/name: ibm-common-service-operator 60 | name: ibm-common-service-operator 61 | productName: IBM_Cloud_Platform_Common_Services 62 | spec: 63 | affinity: 64 | nodeAffinity: 65 | requiredDuringSchedulingIgnoredDuringExecution: 66 | nodeSelectorTerms: 67 | - matchExpressions: 68 | - key: kubernetes.io/arch 69 | operator: In 70 | values: 71 | - amd64 72 | - ppc64le 73 | - s390x 74 | containers: 75 | - name: ibm-common-service-operator 76 | image: {{ .Values.cpfs.imagePullPrefix | default .Values.global.imagePullPrefix }}/{{ .Values.cpfs.imageRegistryNamespaceOperator}}/common-service-operator:4.13.0 77 | command: 78 | - /manager 79 | env: 80 | - name: OPERATOR_NAMESPACE 81 | valueFrom: 82 | fieldRef: 83 | apiVersion: v1 84 | fieldPath: metadata.namespace 85 | {{- $watchNamespaces := .Values.global.tetheredNamespaces | default list -}} 86 | {{- if .Values.global.instanceNamespace -}} 87 | {{- $watchNamespaces = append $watchNamespaces .Values.global.instanceNamespace -}} 88 | {{- end -}} 89 | {{- $watchNamespaces = prepend $watchNamespaces .Values.global.operatorNamespace }} 90 | - name: WATCH_NAMESPACE 91 | value: {{ uniq $watchNamespaces | join "," | quote }} 92 | - name: NO_OLM 93 | value: "true" 94 | - name: ENABLE_WEBHOOKS 95 | value: "false" 96 | - name: OPERATOR_NAME 97 | value: ibm-common-service-operator 98 | imagePullPolicy: IfNotPresent 99 | livenessProbe: 100 | failureThreshold: 10 101 | httpGet: 102 | path: /healthz 103 | port: 8081 104 | initialDelaySeconds: 120 105 | periodSeconds: 60 106 | timeoutSeconds: 10 107 | readinessProbe: 108 | failureThreshold: 10 109 | httpGet: 110 | path: /readyz 111 | port: 8081 112 | initialDelaySeconds: 5 113 | periodSeconds: 20 114 | timeoutSeconds: 20 115 | resources: 116 | limits: 117 | cpu: 500m 118 | memory: 512Mi 119 | requests: 120 | cpu: 100m 121 | ephemeral-storage: 256Mi 122 | memory: 200Mi 123 | securityContext: 124 | allowPrivilegeEscalation: false 125 | capabilities: 126 | drop: 127 | - ALL 128 | privileged: false 129 | readOnlyRootFilesystem: true 130 | runAsNonRoot: true 131 | seccompProfile: 132 | type: RuntimeDefault 133 | imagePullSecrets: 134 | - name: {{ .Values.global.imagePullSecret }} 135 | serviceAccountName: ibm-common-service-operator 136 | terminationGracePeriodSeconds: 10 137 | -------------------------------------------------------------------------------- /helm/values.yaml: -------------------------------------------------------------------------------- 1 | # Note there are no leading or trailing /'s 2 | cpfs: 3 | imageRegistryNamespaceOperator: cpopen 4 | imageRegistryNamespaceOperand: cpopen/cpfs 5 | labels: 6 | # CR configurations 7 | size: starterset 8 | 9 | # Commented out values are handled by a global values file 10 | # imagePullPrefix: icr.io 11 | # imagePullSecret: ibm-entitlement-key 12 | 13 | # other configuration you think you might need for your operator 14 | # following are examples, not required: 15 | # operatorNamespace: "" 16 | # servicesNamespace: "" 17 | 18 | global: 19 | imagePullPrefix: icr.io 20 | tetheredNamespaces: [] 21 | operatorNamespace: operator-ns 22 | instanceNamespace: 23 | -------------------------------------------------------------------------------- /internal/controller/cert-manager/suite_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package certmanager 18 | 19 | import ( 20 | "path/filepath" 21 | "testing" 22 | 23 | . "github.com/onsi/ginkgo" 24 | . "github.com/onsi/gomega" 25 | "k8s.io/client-go/kubernetes/scheme" 26 | "k8s.io/client-go/rest" 27 | "sigs.k8s.io/controller-runtime/pkg/client" 28 | "sigs.k8s.io/controller-runtime/pkg/envtest" 29 | "sigs.k8s.io/controller-runtime/pkg/envtest/printer" 30 | logf "sigs.k8s.io/controller-runtime/pkg/log" 31 | "sigs.k8s.io/controller-runtime/pkg/log/zap" 32 | 33 | certmanagerv1 "github.com/ibm/ibm-cert-manager-operator/apis/cert-manager/v1" 34 | //+kubebuilder:scaffold:imports 35 | ) 36 | 37 | // These tests use Ginkgo (BDD-style Go testing framework). Refer to 38 | // http://onsi.github.io/ginkgo/ to learn more about Ginkgo. 39 | 40 | var cfg *rest.Config 41 | var k8sClient client.Client 42 | var testEnv *envtest.Environment 43 | 44 | func TestAPIs(t *testing.T) { 45 | RegisterFailHandler(Fail) 46 | 47 | RunSpecsWithDefaultAndCustomReporters(t, 48 | "Controller Suite", 49 | []Reporter{printer.NewlineReporter{}}) 50 | } 51 | 52 | var _ = BeforeSuite(func() { 53 | logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) 54 | 55 | By("bootstrapping test environment") 56 | testEnv = &envtest.Environment{ 57 | CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")}, 58 | ErrorIfCRDPathMissing: true, 59 | } 60 | 61 | var err error 62 | cfg, err = testEnv.Start() 63 | Expect(err).NotTo(HaveOccurred()) 64 | Expect(cfg).NotTo(BeNil()) 65 | 66 | err = certmanagerv1.AddToScheme(scheme.Scheme) 67 | Expect(err).NotTo(HaveOccurred()) 68 | 69 | err = certmanagerv1.AddToScheme(scheme.Scheme) 70 | Expect(err).NotTo(HaveOccurred()) 71 | 72 | //+kubebuilder:scaffold:scheme 73 | 74 | k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) 75 | Expect(err).NotTo(HaveOccurred()) 76 | Expect(k8sClient).NotTo(BeNil()) 77 | 78 | }, 60) 79 | 80 | var _ = AfterSuite(func() { 81 | By("tearing down the test environment") 82 | err := testEnv.Stop() 83 | Expect(err).NotTo(HaveOccurred()) 84 | }) 85 | -------------------------------------------------------------------------------- /internal/controller/cert-manager/v1_add_label_controller.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package certmanager 18 | 19 | import ( 20 | "context" 21 | 22 | corev1 "k8s.io/api/core/v1" 23 | "k8s.io/apimachinery/pkg/api/errors" 24 | "k8s.io/apimachinery/pkg/runtime" 25 | "k8s.io/apimachinery/pkg/types" 26 | "k8s.io/klog" 27 | ctrl "sigs.k8s.io/controller-runtime" 28 | "sigs.k8s.io/controller-runtime/pkg/client" 29 | "sigs.k8s.io/controller-runtime/pkg/controller" 30 | "sigs.k8s.io/controller-runtime/pkg/handler" 31 | "sigs.k8s.io/controller-runtime/pkg/log" 32 | "sigs.k8s.io/controller-runtime/pkg/source" 33 | 34 | certmanagerv1 "github.com/ibm/ibm-cert-manager-operator/apis/cert-manager/v1" 35 | 36 | "github.com/IBM/ibm-common-service-operator/v4/internal/controller/constant" 37 | ) 38 | 39 | // V1AddLabelReconciler reconciles a Certificate object 40 | type V1AddLabelReconciler struct { 41 | client.Client 42 | Scheme *runtime.Scheme 43 | } 44 | 45 | // //+kubebuilder:rbac:groups=cert-manager.io,resources=certificates,verbs=get;list;watch;create;update;patch 46 | // //+kubebuilder:rbac:groups=cert-manager.io,resources=certificates/status,verbs=get;update;patch 47 | 48 | // Reconcile is part of the main kubernetes reconciliation loop which aims to 49 | // move the current state of the cluster closer to the desired state. 50 | // TODO(user): Modify the Reconcile function to compare the state specified by 51 | // the Certificate object against the actual cluster state, and then 52 | // perform operations to make the cluster state reflect the state specified by 53 | // the user. 54 | // 55 | // For more details, check Reconcile and its Result here: 56 | // - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.10.0/pkg/reconcile 57 | func (r *V1AddLabelReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { 58 | logd = log.FromContext(ctx) 59 | 60 | reqLogger := logd.WithValues("req.Namespace", req.Namespace, "req.Name", req.Name) 61 | reqLogger.Info("Reconciling CertificateRefresh") 62 | 63 | cert := &certmanagerv1.Certificate{} 64 | err := r.Client.Get(context.TODO(), req.NamespacedName, cert) 65 | if err != nil { 66 | if errors.IsNotFound(err) { 67 | return ctrl.Result{}, nil 68 | } 69 | logd.Error(err, "Error getting v1 Certificate") 70 | return ctrl.Result{}, err 71 | } 72 | 73 | // Get secret corresponding to the certificate 74 | secretInstance, err := r.getSecret(cert) 75 | if err != nil { 76 | if errors.IsNotFound(err) { 77 | return ctrl.Result{}, nil 78 | } 79 | logd.Error(err, "Error getting Secret") 80 | return ctrl.Result{}, err 81 | } 82 | 83 | oldLabelsMap := secretInstance.GetLabels() 84 | if oldLabelsMap == nil { 85 | oldLabelsMap = make(map[string]string) 86 | } 87 | if _, ok := oldLabelsMap[constant.SecretWatchLabel]; !ok { 88 | oldLabelsMap[constant.SecretWatchLabel] = "" 89 | secretInstance.SetLabels(oldLabelsMap) 90 | } 91 | 92 | if err = r.updateSecret(secretInstance); err != nil { 93 | logd.Error(err, "Error updating Secret") 94 | return ctrl.Result{}, err 95 | } 96 | return ctrl.Result{}, nil 97 | } 98 | 99 | // getSecret finds corresponding secret of the certmanagerv1 certificate 100 | func (r *V1AddLabelReconciler) getSecret(cert *certmanagerv1.Certificate) (*corev1.Secret, error) { 101 | secretName := cert.Spec.SecretName 102 | secret := &corev1.Secret{} 103 | err := r.Client.Get(context.TODO(), types.NamespacedName{Name: secretName, Namespace: cert.Namespace}, secret) 104 | 105 | return secret, err 106 | } 107 | 108 | // updateSecret updates corresponding secret 109 | func (r *V1AddLabelReconciler) updateSecret(secret *corev1.Secret) error { 110 | return r.Client.Update(context.TODO(), secret) 111 | } 112 | 113 | // SetupWithManager sets up the controller with the Manager. 114 | func (r *V1AddLabelReconciler) SetupWithManager(mgr ctrl.Manager) error { 115 | klog.V(2).Infof("Set up") 116 | 117 | // Create a new controller 118 | c, err := controller.New("addlabel-controller", mgr, controller.Options{Reconciler: r}) 119 | if err != nil { 120 | return err 121 | } 122 | 123 | // Watch for changes to Certificates in the cluster 124 | err = c.Watch(&source.Kind{Type: &certmanagerv1.Certificate{}}, &handler.EnqueueRequestForObject{}) 125 | if err != nil { 126 | return err 127 | } 128 | 129 | return nil 130 | } 131 | -------------------------------------------------------------------------------- /internal/controller/common/util_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2022 IBM Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package common 18 | 19 | import ( 20 | "testing" 21 | 22 | "github.com/stretchr/testify/assert" 23 | ) 24 | 25 | func TestSanitizeData(t *testing.T) { 26 | // Test case 1: valueType is "string" and isEmpty is true 27 | data1 := map[string]interface{}{ 28 | "key1": "value1", 29 | "key2": "", 30 | "key3": 123, 31 | } 32 | expectedResult1 := map[string]interface{}{ 33 | "key1": "value1", 34 | "key2": "", 35 | } 36 | result1 := SanitizeData(data1, "string", true) 37 | assert.Equal(t, expectedResult1, result1) 38 | 39 | // Test case 2: valueType is "string" and isEmpty is false 40 | data2 := map[string]interface{}{ 41 | "key1": "value1", 42 | "key2": "", 43 | "key3": 123, 44 | } 45 | expectedResult2 := map[string]interface{}{ 46 | "key1": "value1", 47 | } 48 | result2 := SanitizeData(data2, "string", false) 49 | assert.Equal(t, expectedResult2, result2) 50 | 51 | // Test case 3: valueType is "bool" 52 | data3 := map[string]interface{}{ 53 | "key1": "value1", 54 | "key2": true, 55 | "key3": 123, 56 | } 57 | expectedResult3 := map[string]interface{}{ 58 | "key2": true, 59 | } 60 | result3 := SanitizeData(data3, "bool", false) 61 | assert.Equal(t, expectedResult3, result3) 62 | 63 | // Test case 4: valueType is not "string" or "bool" 64 | data4 := map[string]interface{}{ 65 | "key1": "value1", 66 | "key2": true, 67 | "key3": 123, 68 | } 69 | expectedResult4 := map[string]interface{}{} 70 | result4 := SanitizeData(data4, "other", false) 71 | assert.Equal(t, expectedResult4, result4) 72 | } 73 | -------------------------------------------------------------------------------- /internal/controller/configurationcollector/collector.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2022 IBM Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package configurationcollector 18 | 19 | import ( 20 | "context" 21 | "reflect" 22 | "strings" 23 | 24 | corev1 "k8s.io/api/core/v1" 25 | storagev1 "k8s.io/api/storage/v1" 26 | "k8s.io/apimachinery/pkg/api/errors" 27 | "k8s.io/apimachinery/pkg/types" 28 | "k8s.io/klog" 29 | 30 | "github.com/IBM/ibm-common-service-operator/v4/internal/controller/bootstrap" 31 | util "github.com/IBM/ibm-common-service-operator/v4/internal/controller/common" 32 | "github.com/IBM/ibm-common-service-operator/v4/internal/controller/constant" 33 | ) 34 | 35 | func Buildconfig(config map[string]string, bs *bootstrap.Bootstrap) map[string]string { 36 | builder := configbuilder{data: config, bs: bs} 37 | updatedConfig := builder.setDefaultStorageClass().setKeycloakOperatorChannels() 38 | return updatedConfig.data 39 | } 40 | 41 | type configbuilder struct { 42 | data map[string]string 43 | bs *bootstrap.Bootstrap 44 | } 45 | 46 | func (b *configbuilder) setDefaultStorageClass() *configbuilder { 47 | scList := &storagev1.StorageClassList{} 48 | err := b.bs.Reader.List(context.TODO(), scList) 49 | if err != nil { 50 | return b 51 | } 52 | if len(scList.Items) == 0 { 53 | return b 54 | } 55 | 56 | var defaultSC string 57 | var defaultSCList []string 58 | var allSCList []string 59 | 60 | for _, sc := range scList.Items { 61 | if defaultSC == "" { 62 | defaultSC = sc.Name 63 | } 64 | if sc.ObjectMeta.GetAnnotations()["storageclass.kubernetes.io/is-default-class"] == "true" { 65 | defaultSCList = append(defaultSCList, sc.Name) 66 | } 67 | if sc.Provisioner == "kubernetes.io/no-provisioner" { 68 | continue 69 | } 70 | allSCList = append(allSCList, sc.GetName()) 71 | } 72 | 73 | if b.data == nil { 74 | b.data = make(map[string]string) 75 | } 76 | if defaultSC != "" { 77 | b.data["storageclass.default"] = defaultSC 78 | } 79 | 80 | if len(defaultSCList) != 1 { 81 | b.data["storageclass.default.list"] = strings.Join(defaultSCList, ",") 82 | } 83 | 84 | if len(allSCList) != 0 { 85 | b.data["storageclass.list"] = strings.Join(allSCList, ",") 86 | } 87 | 88 | return b 89 | } 90 | 91 | // setKeycloakOperatorChannels sets the keycloak operator channels in the config 92 | func (b *configbuilder) setKeycloakOperatorChannels() *configbuilder { 93 | if b.data == nil { 94 | b.data = make(map[string]string) 95 | } 96 | 97 | keycloakChannels, exists := constant.DefaultChannels["keycloak-operator"] 98 | if !exists || len(keycloakChannels) == 0 { 99 | keycloakChannels = []string{"stable-v24", "stable-v22"} 100 | } 101 | 102 | var channelStr strings.Builder 103 | for _, channel := range keycloakChannels { 104 | channelStr.WriteString("- ") 105 | channelStr.WriteString(channel) 106 | channelStr.WriteString("\n") 107 | } 108 | 109 | b.data["keycloak-operator"] = channelStr.String() 110 | 111 | return b 112 | } 113 | 114 | // CreateUpdateConfig deploys config builder for global cpp configmap 115 | func CreateUpdateConfig(bs *bootstrap.Bootstrap) error { 116 | config := &corev1.ConfigMap{} 117 | if err := bs.Reader.Get(context.TODO(), types.NamespacedName{Name: constant.IBMCPPCONFIG, Namespace: bs.CSData.ServicesNs}, config); err != nil && !errors.IsNotFound(err) { 118 | klog.Errorf("Failed to get ConfigMap %s/%s: %v", bs.CSData.ServicesNs, constant.IBMCPPCONFIG, err) 119 | return err 120 | } else if errors.IsNotFound(err) { 121 | config.ObjectMeta.Name = constant.IBMCPPCONFIG 122 | config.ObjectMeta.Namespace = bs.CSData.ServicesNs 123 | config.Data = make(map[string]string) 124 | config.Data = Buildconfig(config.Data, bs) 125 | if !(config.Labels != nil && config.Labels[constant.CsManagedLabel] == "true") { 126 | util.EnsureLabelsForConfigMap(config, map[string]string{ 127 | constant.CsManagedLabel: "true", 128 | }) 129 | } 130 | if err := bs.Client.Create(context.TODO(), config); err != nil { 131 | klog.Errorf("Failed to create ConfigMap %s/%s: %v", bs.CSData.ServicesNs, constant.IBMCPPCONFIG, err) 132 | return err 133 | } 134 | klog.Infof("Global CPP config %s/%s is created", bs.CSData.ServicesNs, constant.IBMCPPCONFIG) 135 | } else { 136 | orgConfig := config.DeepCopy() 137 | config.Data = Buildconfig(config.Data, bs) 138 | if !(config.Labels != nil && config.Labels[constant.CsManagedLabel] == "true") { 139 | util.EnsureLabelsForConfigMap(config, map[string]string{ 140 | constant.CsManagedLabel: "true", 141 | }) 142 | } 143 | if !reflect.DeepEqual(orgConfig, config) { 144 | if err := bs.Client.Update(context.TODO(), config); err != nil { 145 | klog.Errorf("Failed to update ConfigMap %s/%s: %v", bs.CSData.ServicesNs, constant.IBMCPPCONFIG, err) 146 | return err 147 | } 148 | klog.Infof("Global CPP config %s/%s is updated", bs.CSData.ServicesNs, constant.IBMCPPCONFIG) 149 | } 150 | } 151 | 152 | if err := bs.PropagateCPPConfig(config); err != nil { 153 | klog.Error(err) 154 | return err 155 | } 156 | return nil 157 | } 158 | -------------------------------------------------------------------------------- /internal/controller/constant/apicatalog.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2022 IBM Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package constant 18 | 19 | const APICatalogTemplate = ` 20 | - name: ibm-apicatalog 21 | spec: 22 | apicatalogmanager: 23 | externalDB: 24 | databaseVolumeClaimTemplate: 25 | storageClassName: placeholder 26 | ` 27 | -------------------------------------------------------------------------------- /internal/controller/constant/autoScaleConfig.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2025 IBM Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package constant 18 | 19 | const AutoScaleConfigTemplate = ` 20 | - name: ibm-im-operator 21 | spec: 22 | authentication: 23 | autoScaleConfig: {{ .AutoScaleConfigEnable }} 24 | - name: ibm-idp-config-ui-operator 25 | spec: 26 | commonWebUI: 27 | autoScaleConfig: {{ .AutoScaleConfigEnable }} 28 | ` 29 | -------------------------------------------------------------------------------- /internal/controller/constant/certmanager.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2022 IBM Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package constant 18 | 19 | // SecretWatchLabel is a string of secrets that watched by cert manager operator labels 20 | const SecretWatchLabel string = "operator.ibm.com/watched-by-cert-manager" 21 | 22 | // Labels and Annotations added by this operator 23 | const ( 24 | OperatorGeneratedAnno = "ibm-cert-manager-operator-generated" 25 | ProperV1Label = "ibm-cert-manager-operator/conditionally-generated-v1" 26 | RefreshCALabel = "ibm-cert-manager-operator/refresh-ca-chain" 27 | ManageCertRotationLabel = "manage-cert-rotation" 28 | ) 29 | 30 | var ( 31 | CertManagerAPIGroupVersionV1Alpha1 = "certmanager.k8s.io/v1alpha1" 32 | CertManagerAPIGroupVersionV1 = "cert-manager.io/v1" 33 | CertManagerKinds = []string{"Issuer", "Certificate"} 34 | CertManagerIssuers = []string{CSSSIssuer, CSCAIssuer} 35 | CertManagerCerts = []string{CSCACert} 36 | KeycloakCert = "cs-keycloak-tls-cert" 37 | ) 38 | 39 | // CSCAIssuer is the CR of cs-ca-issuer 40 | const CSCAIssuer = ` 41 | apiVersion: cert-manager.io/v1 42 | kind: Issuer 43 | metadata: 44 | labels: 45 | app.kubernetes.io/instance: cs-ca-issuer 46 | app.kubernetes.io/managed-by: cert-manager-controller 47 | app.kubernetes.io/name: Issuer 48 | operator.ibm.com/managedByCsOperator: "true" 49 | name: cs-ca-issuer 50 | namespace: "placeholder" 51 | spec: 52 | ca: 53 | secretName: cs-ca-certificate-secret 54 | ` 55 | 56 | // CSSSIsuuer is the CR of cs-ss-issuer 57 | const CSSSIssuer = ` 58 | apiVersion: cert-manager.io/v1 59 | kind: Issuer 60 | metadata: 61 | labels: 62 | app.kubernetes.io/instance: cs-ss-issuer 63 | app.kubernetes.io/managed-by: cert-manager-controller 64 | app.kubernetes.io/name: Issuer 65 | operator.ibm.com/managedByCsOperator: "true" 66 | name: cs-ss-issuer 67 | namespace: "placeholder" 68 | spec: 69 | selfSigned: {} 70 | ` 71 | 72 | // CSCACert is the CR of cs-ca-certificate 73 | const CSCACert = ` 74 | apiVersion: cert-manager.io/v1 75 | kind: Certificate 76 | metadata: 77 | labels: 78 | app.kubernetes.io/instance: cs-ca-certificate 79 | app.kubernetes.io/managed-by: cert-manager-controller 80 | app.kubernetes.io/name: Certificate 81 | operator.ibm.com/managedByCsOperator: 'true' 82 | ibm-cert-manager-operator/refresh-ca-chain: 'true' 83 | manage-cert-rotation: 'true' 84 | name: cs-ca-certificate 85 | namespace: "placeholder" 86 | spec: 87 | secretName: cs-ca-certificate-secret 88 | secretTemplate: 89 | labels: 90 | ibm-cert-manager-operator/refresh-ca-chain: 'true' 91 | issuerRef: 92 | name: cs-ss-issuer 93 | kind: Issuer 94 | commonName: cs-ca-certificate 95 | isCA: true 96 | duration: 17520h0m0s 97 | renewBefore: 5840h0m0s 98 | ` 99 | 100 | const KeycloakCertTemplate = ` 101 | apiVersion: cert-manager.io/v1 102 | kind: Certificate 103 | metadata: 104 | name: cs-keycloak-tls-cert 105 | namespace: {{ .ServicesNs }} 106 | spec: 107 | commonName: cs-keycloak-service 108 | dnsNames: 109 | - cs-keycloak-service 110 | - cs-keycloak-service.{{ .ServicesNs }} 111 | - cs-keycloak-service.{{ .ServicesNs }}.svc 112 | - cs-keycloak-service.{{ .ServicesNs }}.svc.cluster.local 113 | issuerRef: 114 | kind: Issuer 115 | name: cs-ca-issuer 116 | secretName: cs-keycloak-tls-secret 117 | ` 118 | -------------------------------------------------------------------------------- /internal/controller/constant/cloudNativePostgresql.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2022 IBM Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package constant 18 | 19 | const EDBImageConfigMap = ` 20 | apiVersion: v1 21 | kind: ConfigMap 22 | metadata: 23 | name: cloud-native-postgresql-image-list 24 | namespace: "{{ .CPFSNs }}" 25 | labels: 26 | operator.ibm.com/managedByCsOperator: "true" 27 | operator.ibm.com/watched-by-odlm: "true" 28 | annotations: 29 | version: {{ .Version }} 30 | data: 31 | ibm-postgresql-13-operand-image: icr.io/cpopen/edb/postgresql:13.20@sha256:4ccd786884e39641a74096d783742c219fb277caafe80b667a80396c3a9cf6c3 32 | ibm-postgresql-14-operand-image: icr.io/cpopen/edb/postgresql:14.17@sha256:99589ee11b50af8ed6355a5f9c2272ce1fc7f9a13e80fda8eda5883a332782a3 33 | ibm-postgresql-15-operand-image: icr.io/cpopen/edb/postgresql:15.12@sha256:0341c499ae144ee81dc2b92e8b99ee313ff6759374b7c1a6469156c20f522921 34 | ibm-postgresql-16-operand-image: icr.io/cpopen/edb/postgresql:16.8@sha256:6d903fd4bd0ef3ef361d22b209ba7b686601b49d6f8d4e29b5d030da8d949dd5 35 | ibm-postgresql-17-operand-image: icr.io/cpopen/edb/postgresql:17.4@sha256:c330a321438943fdd264b292b68fdfb8be89c3bde93a7bd987bd92c9dd2512b0 36 | edb-postgres-license-provider-image: cp.icr.io/cp/cpd/edb-postgres-license-provider@sha256:443b51f8b10acc85bdefde7193e0f45b1c423fa7fbdcaa28342805815c43db3d 37 | ` 38 | -------------------------------------------------------------------------------- /internal/controller/constant/defaultAdminUser.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2022 IBM Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package constant 18 | 19 | const DefaultAdminUserTemplate = ` 20 | - name: ibm-im-operator 21 | spec: 22 | authentication: 23 | config: 24 | defaultAdminUser: placeholder 25 | - name: ibm-im-operator-v4.0 26 | spec: 27 | authentication: 28 | config: 29 | defaultAdminUser: placeholder 30 | ` 31 | -------------------------------------------------------------------------------- /internal/controller/constant/docLink.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2022 IBM Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package constant 18 | 19 | const GeneralTroubleshooting = `https://ibm.biz/cpfs_general_troubleshooting` 20 | -------------------------------------------------------------------------------- /internal/controller/constant/fipsEnable.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2022 IBM Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package constant 18 | 19 | const FipsEnabledTemplate = ` 20 | - name: ibm-iam-operator 21 | spec: 22 | authentication: 23 | config: 24 | fipsEnabled: placeholder 25 | - name: ibm-ingress-nginx-operator 26 | spec: 27 | nginxIngress: 28 | fips_enabled: placeholder 29 | - name: ibm-management-ingress-operator 30 | spec: 31 | managementIngress: 32 | fipsEnabled: placeholder 33 | - name: ibm-im-operator 34 | spec: 35 | authentication: 36 | config: 37 | fipsEnabled: placeholder 38 | - name: ibm-im-operator-v4.0 39 | spec: 40 | authentication: 41 | config: 42 | fipsEnabled: placeholder 43 | - name: ibm-im-operator-v4.1 44 | spec: 45 | authentication: 46 | config: 47 | fipsEnabled: placeholder 48 | - name: ibm-im-operator-v4.2 49 | spec: 50 | authentication: 51 | config: 52 | fipsEnabled: placeholder 53 | - name: ibm-im-operator-v4.3 54 | spec: 55 | authentication: 56 | config: 57 | fipsEnabled: placeholder 58 | - name: ibm-im-operator-v4.4 59 | spec: 60 | authentication: 61 | config: 62 | fipsEnabled: placeholder 63 | - name: ibm-im-operator-v4.5 64 | spec: 65 | authentication: 66 | config: 67 | fipsEnabled: placeholder 68 | - name: ibm-im-operator-v4.6 69 | spec: 70 | authentication: 71 | config: 72 | fipsEnabled: placeholder 73 | ` 74 | -------------------------------------------------------------------------------- /internal/controller/constant/hugepages.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2022 IBM Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package constant 18 | 19 | const HugePagesTemplate = ` 20 | - name: ibm-im-operator 21 | spec: 22 | authentication: 23 | authService: 24 | resources: 25 | limits: 26 | placeholder1: placeholder2 27 | clientRegistration: 28 | resources: 29 | limits: 30 | placeholder1: placeholder2 31 | identityManager: 32 | resources: 33 | limits: 34 | placeholder1: placeholder2 35 | identityProvider: 36 | resources: 37 | limits: 38 | placeholder1: placeholder2 39 | - name: common-service-postgresql 40 | resources: 41 | - apiVersion: postgresql.k8s.enterprisedb.io/v1 42 | data: 43 | spec: 44 | resources: 45 | limits: 46 | placeholder1: placeholder2 47 | kind: Cluster 48 | name: common-service-db 49 | ` 50 | -------------------------------------------------------------------------------- /internal/controller/constant/instanaEnable.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2024 IBM Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package constant 18 | 19 | const InstanaEnableTemplate = ` 20 | - name: ibm-im-operator 21 | spec: 22 | authentication: 23 | enableInstanaMetricCollection: {{ .InstanaEnable }} 24 | - name: ibm-idp-config-ui-operator 25 | spec: 26 | commonWebUI: 27 | enableInstanaMetricCollection: {{ .InstanaEnable }} 28 | ` 29 | -------------------------------------------------------------------------------- /internal/controller/constant/keycloakThemes.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2022 IBM Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package constant 18 | 19 | const KeycloakThemesJar = `/hack/keycloak-themes/cloudpak-theme.jar` 20 | 21 | const KeycloakThemesConfigMap = ` 22 | apiVersion: v1 23 | kind: ConfigMap 24 | metadata: 25 | name: cs-keycloak-theme 26 | namespace: "{{ .ServicesNs }}" 27 | labels: 28 | operator.ibm.com/managedByCsOperator: "true" 29 | annotations: 30 | version: {{ .Version }} 31 | themesVersion: {{ .CloudPakThemesVersion }} 32 | binaryData: 33 | cloudpak-theme.jar: {{ .CloudPakThemes }} 34 | ` 35 | -------------------------------------------------------------------------------- /internal/controller/constant/namespace.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2022 IBM Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package constant 18 | 19 | // NamespaceScopeConfigMap is the init configmap 20 | const NamespaceScopeConfigMap = ` 21 | apiVersion: v1 22 | data: 23 | namespaces: "{{ .WatchNamespaces }}" 24 | kind: ConfigMap 25 | metadata: 26 | name: namespace-scope 27 | namespace: "{{ .CPFSNs }}" 28 | ` 29 | 30 | const NSRestrictedSubscription = ` 31 | apiVersion: operators.coreos.com/v1alpha1 32 | kind: Subscription 33 | metadata: 34 | name: ibm-namespace-scope-operator-restricted 35 | namespace: "{{ .CPFSNs }}" 36 | spec: 37 | channel: {{ .Channel }} 38 | installPlanApproval: {{ .ApprovalMode }} 39 | name: ibm-namespace-scope-operator-restricted 40 | source: {{ .CatalogSourceName }} 41 | sourceNamespace: "{{ .CatalogSourceNs }}" 42 | ` 43 | 44 | const NSSubscription = ` 45 | apiVersion: operators.coreos.com/v1alpha1 46 | kind: Subscription 47 | metadata: 48 | name: ibm-namespace-scope-operator 49 | namespace: "{{ .CPFSNs }}" 50 | spec: 51 | channel: {{ .Channel }} 52 | installPlanApproval: {{ .ApprovalMode }} 53 | name: ibm-namespace-scope-operator 54 | source: {{ .CatalogSourceName }} 55 | sourceNamespace: "{{ .CatalogSourceNs }}" 56 | ` 57 | -------------------------------------------------------------------------------- /internal/controller/constant/odlm_operatorconfig.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2024 IBM Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package constant 18 | 19 | import "fmt" 20 | 21 | var PostGresOperatorConfig string 22 | 23 | // Populate PostGresOperatorConfig at package initialization 24 | func init() { 25 | services := []string{ 26 | "edb-keycloak", 27 | "cloud-native-postgresql", 28 | "common-service-postgresql", 29 | "cloud-native-postgresql-v1.22", 30 | "cloud-native-postgresql-v1.25", 31 | } 32 | 33 | servicesConfig := "" 34 | for _, service := range services { 35 | servicesConfig += fmt.Sprintf(postgresServiceTemplate, service) 36 | } 37 | 38 | PostGresOperatorConfig = `apiVersion: operator.ibm.com/v1alpha1 39 | kind: OperatorConfig 40 | metadata: 41 | name: cloud-native-postgresql-operator-config 42 | namespace: "{{ .ServicesNs }}" 43 | labels: 44 | operator.ibm.com/managedByCsOperator: "true" 45 | operator.ibm.com/experimental: "true" 46 | annotations: 47 | version: {{ .Version }} 48 | spec: 49 | services:` + servicesConfig 50 | } 51 | 52 | const postgresServiceTemplate = ` 53 | - name: %s 54 | replicas: placeholder-size 55 | affinity: 56 | nodeAffinity: 57 | requiredDuringSchedulingIgnoredDuringExecution: 58 | nodeSelectorTerms: 59 | - matchExpressions: 60 | - key: kubernetes.io/arch 61 | operator: In 62 | values: 63 | - amd64 64 | - ppc64le 65 | - s390x 66 | podAntiAffinity: 67 | preferredDuringSchedulingIgnoredDuringExecution: 68 | - weight: 90 69 | podAffinityTerm: 70 | topologyKey: topology.kubernetes.io/zone 71 | labelSelector: 72 | matchExpressions: 73 | - key: app.kubernetes.io/name 74 | operator: In 75 | values: 76 | - cloud-native-postgresql 77 | - weight: 50 78 | podAffinityTerm: 79 | topologyKey: kubernetes.io/hostname 80 | labelSelector: 81 | matchExpressions: 82 | - key: app.kubernetes.io/name 83 | operator: In 84 | values: 85 | - cloud-native-postgresql 86 | topologySpreadConstraints: 87 | - maxSkew: 1 88 | topologyKey: topology.kubernetes.io/zone 89 | whenUnsatisfiable: ScheduleAnyway 90 | labelSelector: 91 | matchLabels: 92 | app.kubernetes.io/name: cloud-native-postgresql 93 | - maxSkew: 1 94 | topologyKey: topology.kubernetes.io/region 95 | whenUnsatisfiable: ScheduleAnyway 96 | labelSelector: 97 | matchLabels: 98 | app.kubernetes.io/name: cloud-native-postgresql` 99 | -------------------------------------------------------------------------------- /internal/controller/constant/routeHost.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2022 IBM Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package constant 18 | 19 | const RouteHostTemplate = ` 20 | - name: ibm-management-ingress-operator 21 | spec: 22 | managementIngress: 23 | routeHost: placeholder 24 | ` 25 | -------------------------------------------------------------------------------- /internal/controller/constant/serviceLabel.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2022 IBM Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package constant 18 | 19 | // still need flink and elastic 20 | const ServiceLabelTemplate = ` 21 | - name: ibm-im-mongodb-operator 22 | spec: 23 | mongoDB: 24 | labels: 25 | placeholder1: placeholder2 26 | - name: ibm-im-mongodb-operator-v4.0 27 | spec: 28 | mongoDB: 29 | labels: 30 | placeholder1: placeholder2 31 | - name: ibm-im-mongodb-operator-v4.1 32 | spec: 33 | mongoDB: 34 | labels: 35 | placeholder1: placeholder2 36 | - name: ibm-im-mongodb-operator-v4.2 37 | spec: 38 | mongoDB: 39 | labels: 40 | placeholder1: placeholder2 41 | - name: ibm-im-operator 42 | spec: 43 | authentication: 44 | labels: 45 | placeholder1: placeholder2 46 | - name: ibm-im-operator-v4.0 47 | spec: 48 | authentication: 49 | labels: 50 | placeholder1: placeholder2 51 | - name: ibm-im-operator-v4.1 52 | spec: 53 | authentication: 54 | labels: 55 | placeholder1: placeholder2 56 | - name: ibm-im-operator-v4.2 57 | spec: 58 | authentication: 59 | labels: 60 | placeholder1: placeholder2 61 | - name: ibm-im-operator-v4.3 62 | spec: 63 | authentication: 64 | labels: 65 | placeholder1: placeholder2 66 | - name: ibm-im-operator-v4.4 67 | spec: 68 | authentication: 69 | labels: 70 | placeholder1: placeholder2 71 | - name: ibm-im-operator-v4.5 72 | spec: 73 | authentication: 74 | labels: 75 | placeholder1: placeholder2 76 | - name: ibm-im-operator-v4.6 77 | spec: 78 | authentication: 79 | labels: 80 | placeholder1: placeholder2 81 | - name: ibm-idp-config-ui-operator-v4.0 82 | spec: 83 | commonWebUI: 84 | labels: 85 | placeholder1: placeholder2 86 | - name: ibm-idp-config-ui-operator-v4.1 87 | spec: 88 | commonWebUI: 89 | labels: 90 | placeholder1: placeholder2 91 | - name: ibm-idp-config-ui-operator-v4.2 92 | spec: 93 | commonWebUI: 94 | labels: 95 | placeholder1: placeholder2 96 | - name: ibm-idp-config-ui-operator-v4.3 97 | spec: 98 | commonWebUI: 99 | labels: 100 | placeholder1: placeholder2 101 | - name: ibm-idp-config-ui-operator-v4.4 102 | spec: 103 | commonWebUI: 104 | labels: 105 | placeholder1: placeholder2 106 | - name: ibm-idp-config-ui-operator-v4.5 107 | spec: 108 | commonWebUI: 109 | labels: 110 | placeholder1: placeholder2 111 | ` 112 | -------------------------------------------------------------------------------- /internal/controller/constant/storageclass.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2022 IBM Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package constant 18 | 19 | const StorageClassTemplate = ` 20 | - name: ibm-im-mongodb-operator 21 | spec: 22 | mongoDB: 23 | storageClass: placeholder 24 | - name: ibm-im-mongodb-operator-v4.0 25 | spec: 26 | mongoDB: 27 | storageClass: placeholder 28 | - name: ibm-im-mongodb-operator-v4.1 29 | spec: 30 | mongoDB: 31 | storageClass: placeholder 32 | - name: ibm-im-mongodb-operator-v4.2 33 | spec: 34 | mongoDB: 35 | storageClass: placeholder 36 | - name: ibm-healthcheck-operator 37 | spec: 38 | mustgatherService: 39 | persistentVolumeClaim: 40 | storageClassName: placeholder 41 | - name: edb-keycloak 42 | resources: 43 | - apiVersion: postgresql.k8s.enterprisedb.io/v1 44 | data: 45 | spec: 46 | storage: 47 | storageClass: placeholder 48 | walStorage: 49 | storageClass: placeholder 50 | kind: Cluster 51 | name: keycloak-edb-cluster 52 | - name: common-service-postgresql 53 | resources: 54 | - apiVersion: postgresql.k8s.enterprisedb.io/v1 55 | data: 56 | spec: 57 | storage: 58 | storageClass: placeholder 59 | walStorage: 60 | storageClass: placeholder 61 | kind: Cluster 62 | name: common-service-db 63 | ` 64 | -------------------------------------------------------------------------------- /internal/controller/goroutines/waitToCreateCsCR.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2023 IBM Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package goroutines 18 | 19 | import ( 20 | "fmt" 21 | "os" 22 | "strings" 23 | "time" 24 | 25 | "k8s.io/klog" 26 | 27 | "github.com/IBM/ibm-common-service-operator/v4/internal/controller/bootstrap" 28 | ) 29 | 30 | // WaitToCreateCsCR waits for the creation of the CommonService CR in the operator namespace. 31 | func WaitToCreateCsCR(bs *bootstrap.Bootstrap) { 32 | for { 33 | klog.Infof("Start to Create CommonService CR in the namespace %s", bs.CSData.OperatorNs) 34 | if err := bs.CreateCsCR(); err != nil { 35 | if strings.Contains(fmt.Sprint(err), "failed to call webhook") { 36 | klog.Infof("Webhook Server not ready, waiting for it to be ready : %v", err) 37 | time.Sleep(time.Second * 20) 38 | } else { 39 | klog.Errorf("Failed to create CommonService CR : %v", err) 40 | os.Exit(1) 41 | } 42 | } else { 43 | break 44 | } 45 | 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /internal/controller/goroutines/waitToCreateCsCrNoOLM.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2025 IBM Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package goroutines 18 | 19 | import ( 20 | "fmt" 21 | "os" 22 | "strings" 23 | "time" 24 | 25 | "k8s.io/klog" 26 | 27 | "github.com/IBM/ibm-common-service-operator/v4/internal/controller/bootstrap" 28 | ) 29 | 30 | // WaitToCreateCsCR waits for the creation of the CommonService CR in the operator namespace. 31 | func WaitToCreateCsCRNoOLM(bs *bootstrap.Bootstrap) { 32 | for { 33 | klog.Infof("Start to Create CommonService CR in the namespace %s", bs.CSData.OperatorNs) 34 | if err := bs.CreateCsCRNoOLM(); err != nil { 35 | if strings.Contains(fmt.Sprint(err), "failed to call webhook") { 36 | klog.Infof("Webhook Server not ready, waiting for it to be ready : %v", err) 37 | time.Sleep(time.Second * 20) 38 | } else { 39 | klog.Errorf("Failed to create CommonService CR : %v", err) 40 | os.Exit(1) 41 | } 42 | } else { 43 | break 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /internal/controller/operatorconfig.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2024 IBM Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package controllers 18 | 19 | import ( 20 | "context" 21 | "errors" 22 | "fmt" 23 | "strings" 24 | 25 | apierrors "k8s.io/apimachinery/pkg/api/errors" 26 | "k8s.io/apimachinery/pkg/types" 27 | "k8s.io/klog" 28 | 29 | v3 "github.com/IBM/ibm-common-service-operator/v4/api/v3" 30 | util "github.com/IBM/ibm-common-service-operator/v4/internal/controller/common" 31 | "github.com/IBM/ibm-common-service-operator/v4/internal/controller/constant" 32 | odlm "github.com/IBM/operand-deployment-lifecycle-manager/v4/api/v1alpha1" 33 | ) 34 | 35 | func (r *CommonServiceReconciler) updateOperatorConfig(ctx context.Context, configList []v3.OperatorConfig) (bool, error) { 36 | klog.Info("Applying OperatorConfig") 37 | 38 | if configList == nil { 39 | if err := r.clearAllUserManaged(ctx); err != nil { 40 | return false, err 41 | } 42 | return true, nil 43 | } 44 | 45 | // TODO: remove when this feature is generalized to all other operators 46 | for _, c := range configList { 47 | config := c 48 | packageName, err := r.fetchPackageNameFromOpReg(ctx, config.Name) 49 | if err != nil { 50 | return false, err 51 | } 52 | if packageName != "cloud-native-postgresql" { 53 | return false, errors.New("failed to update OperatorConfig. This feature is only available for cloud-native-postgresql operator") 54 | } 55 | if err := r.updateUserManaged(ctx, config.Name, config.UserManaged); err != nil { 56 | return false, err 57 | } 58 | if config.Replicas == nil { 59 | return true, nil 60 | } 61 | } 62 | 63 | operatorConfig := &odlm.OperatorConfig{} 64 | if err := r.Reader.Get(ctx, types.NamespacedName{ 65 | Name: "test-operator-config", 66 | Namespace: r.Bootstrap.CSData.ServicesNs, 67 | }, operatorConfig); err != nil { 68 | if !apierrors.IsNotFound(err) { 69 | klog.Errorf("failed to get OperatorConfig %s/%s: %v", operatorConfig.GetNamespace(), operatorConfig.GetName(), err) 70 | return true, err 71 | } 72 | } 73 | replicas := *configList[0].Replicas 74 | replacer := strings.NewReplacer("placeholder-size", fmt.Sprintf("%d", replicas)) 75 | updatedConfig := replacer.Replace(constant.PostGresOperatorConfig) 76 | klog.V(2).Infof("OperatorConfig to be applied will be: %v", updatedConfig) 77 | 78 | if err := r.Bootstrap.InstallOrUpdateOperatorConfig(updatedConfig, true); err != nil { 79 | return false, err 80 | } 81 | return false, nil 82 | } 83 | 84 | func (r *CommonServiceReconciler) fetchPackageNameFromOpReg(ctx context.Context, name string) (string, error) { 85 | registry, err := r.GetOperandRegistry(ctx, "common-service", r.CSData.ServicesNs) 86 | if err != nil { 87 | return "", err 88 | } 89 | 90 | for _, r := range registry.Spec.Operators { 91 | operator := r 92 | if operator.Name == name { 93 | return operator.PackageName, nil 94 | } 95 | } 96 | return "", nil 97 | } 98 | 99 | func (r *CommonServiceReconciler) updateUserManaged(ctx context.Context, operatorName string, value bool) error { 100 | opreg := &odlm.OperandRegistry{} 101 | if err := r.Reader.Get(ctx, types.NamespacedName{Namespace: util.GetServicesNamespace(r.Reader), Name: "common-service"}, opreg); err != nil { 102 | return err 103 | } 104 | if err := util.UpdateOpRegUserManaged(opreg, operatorName, value); err != nil { 105 | return err 106 | } 107 | if err := r.Client.Update(ctx, opreg); err != nil { 108 | return err 109 | } 110 | return nil 111 | } 112 | 113 | func (r *CommonServiceReconciler) clearAllUserManaged(ctx context.Context) error { 114 | opreg := &odlm.OperandRegistry{} 115 | if err := r.Reader.Get(ctx, types.NamespacedName{Namespace: util.GetServicesNamespace(r.Reader), Name: "common-service"}, opreg); err != nil { 116 | return err 117 | } 118 | for i := range opreg.Spec.Operators { 119 | i := i 120 | opreg.Spec.Operators[i].UserManaged = false 121 | } 122 | return r.Client.Update(ctx, opreg) 123 | } 124 | -------------------------------------------------------------------------------- /internal/controller/recocile_pause.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2022 IBM Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package controllers 18 | 19 | import ( 20 | "k8s.io/klog" 21 | 22 | apiv3 "github.com/IBM/ibm-common-service-operator/v4/api/v3" 23 | ) 24 | 25 | const ( 26 | PauseRequestAnnoKey = "commonservices.operator.ibm.com/pause" 27 | SelfPauseRequestAnnoKey = "commonservices.operator.ibm.com/self-pause" 28 | PauseRequestValue = "true" 29 | ) 30 | 31 | func (r *CommonServiceReconciler) reconcilePauseRequest(instance *apiv3.CommonService) bool { 32 | 33 | //klog.Info("Request Stage: ReconcilePauseRequest") 34 | 35 | // if the given CommnService CR has not been existing 36 | if instance == nil { 37 | return false 38 | } 39 | 40 | // check if there is a pause request annotation in the CommonService CR 41 | return r.pauseRequestExists(instance) 42 | 43 | // future implementation: TO DO 44 | // check and set pauseExpire annotation 45 | // if the time is expired, remove the pause annotation 46 | } 47 | 48 | func (r *CommonServiceReconciler) pauseRequestExists(instance *apiv3.CommonService) bool { 49 | klog.Info("Checking annotations for pause request") 50 | 51 | // if there is pause or self-pause request annotation in the CommonService CR, pause request takes precedence over self-pause request 52 | var pauseRequestFound bool 53 | var selfpauseRequestFound bool 54 | if instance.ObjectMeta.Annotations != nil { 55 | for key := range instance.ObjectMeta.Annotations { 56 | if key == PauseRequestAnnoKey { 57 | pauseRequestFound = true 58 | klog.Infof("Found pause request annotation: %v", instance.ObjectMeta.Annotations[PauseRequestAnnoKey]) 59 | } else if key == SelfPauseRequestAnnoKey { 60 | selfpauseRequestFound = true 61 | klog.Infof("Found self-pause request annotation: %v", instance.ObjectMeta.Annotations[SelfPauseRequestAnnoKey]) 62 | } 63 | } 64 | // Pause request takes precedence over self-pause request 65 | if pauseRequestFound { 66 | return instance.ObjectMeta.Annotations[PauseRequestAnnoKey] == PauseRequestValue 67 | } else if selfpauseRequestFound { 68 | return instance.ObjectMeta.Annotations[SelfPauseRequestAnnoKey] == PauseRequestValue 69 | } 70 | return false 71 | } 72 | return false 73 | } 74 | -------------------------------------------------------------------------------- /internal/controller/render_template_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2022 IBM Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package controllers 18 | 19 | import ( 20 | "testing" 21 | 22 | . "github.com/onsi/ginkgo" 23 | . "github.com/onsi/gomega" 24 | 25 | apiv3 "github.com/IBM/ibm-common-service-operator/v4/api/v3" 26 | ) 27 | 28 | var _ = Describe("Render Template", func() { 29 | Describe("unmarshalHugePages", func() { 30 | It("should unmarshal the input map into a HugePages struct", func() { 31 | hugePages := map[string]interface{}{ 32 | "enable": true, 33 | "hugepages-2Gi": "", 34 | "hugepages-2Mi": "1Gi", 35 | } 36 | 37 | hugePagesStruct, err := UnmarshalHugePages(hugePages) 38 | Expect(err).To(BeNil()) 39 | Expect(hugePagesStruct).To(Equal(&apiv3.HugePages{ 40 | HugePagesSizes: map[string]string{ 41 | "hugepages-2Gi": "", 42 | "hugepages-2Mi": "1Gi", 43 | }, 44 | })) 45 | }) 46 | 47 | It("should unmarshal the input map into a HugePages struct and sanitize the invalid value", func() { 48 | hugePages := map[string]interface{}{ 49 | "enable": true, 50 | "replica": 1, // invalid value 51 | "hugepages-2Gi": "", 52 | "hugepages-2Mi": "1Gi", 53 | } 54 | 55 | hugePagesStruct, err := UnmarshalHugePages(hugePages) 56 | Expect(err).To(BeNil()) 57 | Expect(hugePagesStruct).To(Equal(&apiv3.HugePages{ 58 | Enable: true, 59 | HugePagesSizes: map[string]string{ 60 | "hugepages-2Gi": "", 61 | "hugepages-2Mi": "1Gi", 62 | }, 63 | })) 64 | }) 65 | }) 66 | }) 67 | 68 | func TestRenderTemplate(t *testing.T) { 69 | RegisterFailHandler(Fail) 70 | RunSpecs(t, "Render Template Suite") 71 | } 72 | -------------------------------------------------------------------------------- /internal/controller/rules/resource_comparison_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2022 IBM Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package rules 18 | 19 | import ( 20 | . "github.com/onsi/ginkgo" 21 | . "github.com/onsi/gomega" 22 | ) 23 | 24 | var _ = Describe("Resource Comparison", func() { 25 | 26 | Context("Compare CPU", func() { 27 | It("Should 1 be larger than 10m", func() { 28 | A := "1" 29 | B := "10m" 30 | expectedResult := "1" 31 | 32 | result, _, err := resourceStringComparison(A, B) 33 | Expect(err).NotTo(HaveOccurred()) 34 | 35 | Expect(result).Should(Equal(expectedResult)) 36 | }) 37 | It("Should 100m be larger than 10m", func() { 38 | A := "100m" 39 | B := "10m" 40 | expectedResult := "100m" 41 | 42 | result, _, err := resourceStringComparison(A, B) 43 | Expect(err).NotTo(HaveOccurred()) 44 | 45 | Expect(result).Should(Equal(expectedResult)) 46 | }) 47 | }) 48 | 49 | Context("Compare Memory", func() { 50 | It("Should 1Gi be larger than 10Mi", func() { 51 | A := "1Gi" 52 | B := "10Mi" 53 | expectedResult := "1Gi" 54 | 55 | result, _, err := resourceStringComparison(A, B) 56 | Expect(err).NotTo(HaveOccurred()) 57 | 58 | Expect(result).Should(Equal(expectedResult)) 59 | }) 60 | It("Should 100Mi be larger than 10Mi", func() { 61 | A := "100Mi" 62 | B := "10Mi" 63 | expectedResult := "100Mi" 64 | 65 | result, _, err := resourceStringComparison(A, B) 66 | Expect(err).NotTo(HaveOccurred()) 67 | 68 | Expect(result).Should(Equal(expectedResult)) 69 | }) 70 | }) 71 | }) 72 | -------------------------------------------------------------------------------- /internal/controller/rules/rules_suite_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2022 IBM Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package rules 18 | 19 | import ( 20 | . "github.com/onsi/ginkgo" 21 | . "github.com/onsi/gomega" 22 | 23 | "testing" 24 | ) 25 | 26 | func TestStatus(t *testing.T) { 27 | RegisterFailHandler(Fail) 28 | RunSpecs(t, "rules Suite") 29 | } 30 | -------------------------------------------------------------------------------- /internal/controller/suite_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2022 IBM Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package controllers 18 | 19 | import ( 20 | "os" 21 | "path/filepath" 22 | "testing" 23 | "time" 24 | 25 | . "github.com/onsi/ginkgo" 26 | . "github.com/onsi/gomega" 27 | olmv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1" 28 | clientgoscheme "k8s.io/client-go/kubernetes/scheme" 29 | "k8s.io/client-go/rest" 30 | ctrl "sigs.k8s.io/controller-runtime" 31 | "sigs.k8s.io/controller-runtime/pkg/client" 32 | "sigs.k8s.io/controller-runtime/pkg/envtest" 33 | "sigs.k8s.io/controller-runtime/pkg/envtest/printer" 34 | logf "sigs.k8s.io/controller-runtime/pkg/log" 35 | "sigs.k8s.io/controller-runtime/pkg/log/zap" 36 | 37 | apiv3 "github.com/IBM/ibm-common-service-operator/v4/api/v3" 38 | "github.com/IBM/ibm-common-service-operator/v4/internal/controller/bootstrap" 39 | "github.com/IBM/ibm-common-service-operator/v4/internal/controller/constant" 40 | "github.com/IBM/ibm-common-service-operator/v4/internal/controller/deploy" 41 | // +kubebuilder:scaffold:imports 42 | ) 43 | 44 | // These tests use Ginkgo (BDD-style Go testing framework). Refer to 45 | // http://onsi.github.io/ginkgo/ to learn more about Ginkgo. 46 | 47 | var ( 48 | cfg *rest.Config 49 | k8sClient client.Client 50 | k8sReader client.Reader 51 | deployMgr *deploy.Manager 52 | testEnv *envtest.Environment 53 | 54 | timeout = time.Second * 100 55 | interval = time.Second * 10 56 | ) 57 | 58 | func TestAPIs(t *testing.T) { 59 | RegisterFailHandler(Fail) 60 | 61 | RunSpecsWithDefaultAndCustomReporters(t, 62 | "Controller Suite", 63 | []Reporter{printer.NewlineReporter{}}) 64 | } 65 | 66 | var _ = BeforeSuite(func(done Done) { 67 | logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) 68 | 69 | By("bootstrapping test environment") 70 | testEnv = &envtest.Environment{ 71 | UseExistingCluster: UseExistingCluster(), 72 | CRDDirectoryPaths: []string{filepath.Join("..", "..", "config", "crd", "bases"), filepath.Join("..", "odlmcrds")}, 73 | } 74 | 75 | var err error 76 | cfg, err = testEnv.Start() 77 | Expect(err).ToNot(HaveOccurred()) 78 | Expect(cfg).ToNot(BeNil()) 79 | 80 | err = olmv1alpha1.AddToScheme(clientgoscheme.Scheme) 81 | Expect(err).NotTo(HaveOccurred()) 82 | 83 | err = apiv3.AddToScheme(clientgoscheme.Scheme) 84 | Expect(err).NotTo(HaveOccurred()) 85 | // +kubebuilder:scaffold:scheme 86 | 87 | // Start your controllers test logic 88 | k8sManager, err := ctrl.NewManager(cfg, ctrl.Options{ 89 | Scheme: clientgoscheme.Scheme, 90 | }) 91 | Expect(err).ToNot(HaveOccurred()) 92 | 93 | k8sClient = k8sManager.GetClient() 94 | Expect(k8sClient).ToNot(BeNil()) 95 | k8sReader = k8sManager.GetAPIReader() 96 | Expect(k8sReader).ToNot(BeNil()) 97 | 98 | deployMgr = deploy.NewDeployManager(k8sManager) 99 | 100 | b, err := bootstrap.NewBootstrap(k8sManager) 101 | Expect(err).ToNot(HaveOccurred()) 102 | 103 | // Setup Manager with CommonService Controller 104 | err = (&CommonServiceReconciler{ 105 | Bootstrap: b, 106 | Scheme: k8sManager.GetScheme(), 107 | }).SetupWithManager(k8sManager) 108 | Expect(err).ToNot(HaveOccurred()) 109 | 110 | // Start common service operator conntroller 111 | go func() { 112 | err = k8sManager.Start(ctrl.SetupSignalHandler()) 113 | Expect(err).ToNot(HaveOccurred()) 114 | }() 115 | // End your controllers test logic 116 | 117 | close(done) 118 | }, 60) 119 | 120 | var _ = AfterSuite(func() { 121 | By("tearing down the test environment") 122 | err := testEnv.Stop() 123 | Expect(err).ToNot(HaveOccurred()) 124 | }) 125 | 126 | func UseExistingCluster() *bool { 127 | use := false 128 | if os.Getenv(constant.UseExistingCluster) != "" && os.Getenv(constant.UseExistingCluster) == "true" { 129 | use = true 130 | } 131 | return &use 132 | } 133 | -------------------------------------------------------------------------------- /internal/controller/webhooks/commonservice/validatingwebhook_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2022 IBM Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package commonservice 18 | 19 | import ( 20 | "testing" 21 | 22 | "github.com/stretchr/testify/assert" 23 | "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" 24 | ) 25 | 26 | func TestHugePageSettingDenied(t *testing.T) { 27 | 28 | r := &Defaulter{} 29 | cs := &unstructured.Unstructured{ 30 | Object: map[string]interface{}{ 31 | "spec": map[string]interface{}{ 32 | "hugepages": map[string]interface{}{ 33 | "enable": true, 34 | }, 35 | }, 36 | }, 37 | } 38 | 39 | // Test case: Valid hugepages sizes and allocations 40 | cs.Object["spec"].(map[string]interface{})["hugepages"].(map[string]interface{})["hugepages-1Gi"] = "2Gi" 41 | cs.Object["spec"].(map[string]interface{})["hugepages"].(map[string]interface{})["hugepages-2Mi"] = "4Mi" 42 | isDenied, err := r.HugePageSettingDenied(cs) 43 | assert.False(t, isDenied) 44 | assert.Nil(t, err) 45 | 46 | // Test case: Invalid hugepages size format 47 | cs.Object["spec"].(map[string]interface{})["hugepages"].(map[string]interface{})["invalid-1Gi"] = "2Gi" 48 | isDenied, err = r.HugePageSettingDenied(cs) 49 | assert.True(t, isDenied) 50 | assert.Contains(t, err.Error(), "invalid hugepages size on prefix") 51 | // Delete invalid size 52 | delete(cs.Object["spec"].(map[string]interface{})["hugepages"].(map[string]interface{}), "invalid-1Gi") 53 | 54 | // Test case: Invalid hugepages size quantity 55 | cs.Object["spec"].(map[string]interface{})["hugepages"].(map[string]interface{})["hugepages-invalid"] = "invalid-quantity" 56 | isDenied, err = r.HugePageSettingDenied(cs) 57 | assert.True(t, isDenied) 58 | assert.Contains(t, err.Error(), "invalid hugepages size on Quantity") 59 | // Delete invalid quantity 60 | delete(cs.Object["spec"].(map[string]interface{})["hugepages"].(map[string]interface{}), "hugepages-invalid") 61 | 62 | // Test case: Invalid hugepages allocation format 63 | cs.Object["spec"].(map[string]interface{})["hugepages"].(map[string]interface{})["hugepages-1Gi"] = "2Gi" 64 | cs.Object["spec"].(map[string]interface{})["hugepages"].(map[string]interface{})["hugepages-2Mi"] = "invalid-allocation" 65 | isDenied, err = r.HugePageSettingDenied(cs) 66 | assert.True(t, isDenied) 67 | assert.Contains(t, err.Error(), "invalid hugepages allocation") 68 | // Delete invalid allocation 69 | delete(cs.Object["spec"].(map[string]interface{})["hugepages"].(map[string]interface{}), "hugepages-2Mi") 70 | 71 | // Test case: No hugepages enabled 72 | cs.Object["spec"].(map[string]interface{})["hugepages"].(map[string]interface{})["enable"] = false 73 | isDenied, err = r.HugePageSettingDenied(cs) 74 | assert.False(t, isDenied) 75 | assert.Nil(t, err) 76 | } 77 | -------------------------------------------------------------------------------- /internal/controller/webhooks/operandrequest/mutatingwebhook.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2022 IBM Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package operandrequest 18 | 19 | import ( 20 | "context" 21 | "encoding/json" 22 | "net/http" 23 | "strings" 24 | 25 | corev1 "k8s.io/api/core/v1" 26 | "k8s.io/apimachinery/pkg/api/errors" 27 | "k8s.io/apimachinery/pkg/types" 28 | "k8s.io/klog" 29 | ctrl "sigs.k8s.io/controller-runtime" 30 | "sigs.k8s.io/controller-runtime/pkg/client" 31 | "sigs.k8s.io/controller-runtime/pkg/webhook" 32 | "sigs.k8s.io/controller-runtime/pkg/webhook/admission" 33 | 34 | util "github.com/IBM/ibm-common-service-operator/v4/internal/controller/common" 35 | odlm "github.com/IBM/operand-deployment-lifecycle-manager/v4/api/v1alpha1" 36 | ) 37 | 38 | // +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 39 | 40 | // OperandRequestDefaulter points to correct RegistryNamespace 41 | type Defaulter struct { 42 | Reader client.Reader 43 | Client client.Client 44 | IsDormant bool 45 | decoder *admission.Decoder 46 | } 47 | 48 | // podAnnotator adds an annotation to every incoming pods. 49 | func (r *Defaulter) Handle(ctx context.Context, req admission.Request) admission.Response { 50 | klog.Infof("Webhook is invoked by OperandRequest %s/%s", req.AdmissionRequest.Namespace, req.AdmissionRequest.Name) 51 | opreq := &odlm.OperandRequest{} 52 | 53 | err := r.decoder.Decode(req, opreq) 54 | if err != nil { 55 | return admission.Errored(http.StatusBadRequest, err) 56 | } 57 | 58 | copy := opreq.DeepCopy() 59 | 60 | if !r.IsDormant { 61 | r.Default(copy) 62 | } 63 | 64 | marshaledCopy, err := json.Marshal(copy) 65 | if err != nil { 66 | return admission.Errored(http.StatusInternalServerError, err) 67 | } 68 | marshaledOpreq, err := json.Marshal(opreq) 69 | if err != nil { 70 | return admission.Errored(http.StatusInternalServerError, err) 71 | } 72 | 73 | return admission.PatchResponseFromRaw(marshaledOpreq, marshaledCopy) 74 | } 75 | 76 | // Default implements webhook.Defaulter so a webhook will be registered for the type 77 | func (r *Defaulter) Default(instance *odlm.OperandRequest) { 78 | watchNamespaces := util.GetWatchNamespace() 79 | for i, req := range instance.Spec.Requests { 80 | if req.RegistryNamespace == "" { 81 | continue 82 | } 83 | regNs := req.RegistryNamespace 84 | isDefaulting := false 85 | // watchNamespace is empty in All namespace mode 86 | if len(watchNamespaces) == 0 { 87 | ctx := context.Background() 88 | ns := &corev1.Namespace{} 89 | nsKey := types.NamespacedName{ 90 | Name: regNs, 91 | } 92 | if err := r.Client.Get(ctx, nsKey, ns); err != nil { 93 | if errors.IsNotFound(err) { 94 | klog.Infof("Not found registryNamespace %v for OperandRequest %v/%v", regNs, instance.Namespace, instance.Name) 95 | isDefaulting = true 96 | } else { 97 | klog.Errorf("Failed to get namespace %v: %v", regNs, err) 98 | } 99 | } 100 | } else if len(watchNamespaces) != 0 && !util.Contains(strings.Split(watchNamespaces, ","), regNs) { 101 | isDefaulting = true 102 | } 103 | if isDefaulting { 104 | serviceNs := util.GetServicesNamespace(r.Reader) 105 | instance.Spec.Requests[i].RegistryNamespace = serviceNs 106 | klog.V(2).Infof("Setting %vth RegistryNamespace for OperandRequest %v/%v to %v", i, instance.Namespace, instance.Name, serviceNs) 107 | } 108 | } 109 | } 110 | 111 | func (r *Defaulter) InjectDecoder(decoder *admission.Decoder) error { 112 | r.decoder = decoder 113 | return nil 114 | } 115 | 116 | func (r *Defaulter) SetupWebhookWithManager(mgr ctrl.Manager) error { 117 | 118 | mgr.GetWebhookServer(). 119 | Register("/mutate-operator-ibm-com-v1alpha1-operandrequest", 120 | &webhook.Admission{Handler: r}) 121 | 122 | return nil 123 | } 124 | -------------------------------------------------------------------------------- /testdata/deploy/cluster_rbac.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: ibm-common-service-operator-cluster 5 | rules: 6 | - apiGroups: ["*"] 7 | resources: ["*"] 8 | verbs: ["*"] 9 | 10 | --- 11 | apiVersion: rbac.authorization.k8s.io/v1 12 | kind: ClusterRoleBinding 13 | metadata: 14 | name: ibm-common-service-operator-cluster 15 | roleRef: 16 | apiGroup: rbac.authorization.k8s.io 17 | kind: ClusterRole 18 | name: ibm-common-service-operator-cluster 19 | subjects: 20 | - kind: ServiceAccount 21 | name: ibm-common-service-operator 22 | namespace: openshift-operators 23 | -------------------------------------------------------------------------------- /testdata/deploy/deploy.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: ibm-common-service-operator 5 | spec: 6 | progressDeadlineSeconds: 600 7 | replicas: 1 8 | revisionHistoryLimit: 10 9 | selector: 10 | matchLabels: 11 | name: ibm-common-service-operator 12 | template: 13 | metadata: 14 | labels: 15 | name: ibm-common-service-operator 16 | annotations: 17 | description: The IBM Common Service Operator is used to deploy IBM Common Services 18 | operatorChannel: v4.13 19 | operatorVersion: 4.13.0 20 | cloudPakThemesVersion: styles4100.css 21 | spec: 22 | affinity: 23 | nodeAffinity: 24 | requiredDuringSchedulingIgnoredDuringExecution: 25 | nodeSelectorTerms: 26 | - matchExpressions: 27 | - key: kubernetes.io/arch 28 | operator: In 29 | values: 30 | - amd64 31 | - ppc64le 32 | - s390x 33 | containers: 34 | - command: 35 | - /manager 36 | env: 37 | - name: OPERATOR_NAME 38 | value: ibm-common-service-operator 39 | image: siji/operator:cs 40 | imagePullPolicy: IfNotPresent 41 | name: ibm-common-service-operator 42 | resources: 43 | limits: 44 | cpu: 500m 45 | memory: 512Mi 46 | requests: 47 | cpu: 100m 48 | memory: 200Mi 49 | securityContext: 50 | allowPrivilegeEscalation: false 51 | capabilities: 52 | drop: 53 | - ALL 54 | privileged: false 55 | readOnlyRootFilesystem: true 56 | runAsNonRoot: true 57 | terminationMessagePath: /dev/termination-log 58 | terminationMessagePolicy: File 59 | dnsPolicy: ClusterFirst 60 | restartPolicy: Always 61 | schedulerName: default-scheduler 62 | securityContext: {} 63 | serviceAccount: ibm-common-service-operator 64 | serviceAccountName: ibm-common-service-operator 65 | terminationGracePeriodSeconds: 10 66 | -------------------------------------------------------------------------------- /testdata/deploy/role.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: ibm-common-service-operator 5 | rules: 6 | # create ibm-common-services namespace permission 7 | - apiGroups: 8 | - '' 9 | resources: 10 | - namespaces 11 | verbs: 12 | - create 13 | # create subscriptions & operatorgroup permission in ibm-common-services 14 | - apiGroups: 15 | - operators.coreos.com 16 | resources: 17 | - subscriptions 18 | - operatorgroups 19 | verbs: 20 | - list 21 | - get 22 | - create 23 | - update 24 | # delete existing subscriptions in openshift-operators/ibm-common-services 25 | - apiGroups: 26 | - operators.coreos.com 27 | resources: 28 | - subscriptions 29 | - clusterserviceversions 30 | verbs: 31 | - delete 32 | - get 33 | - list 34 | # check catalogsource migration for highest priority of internal dev build 35 | - apiGroups: 36 | - operators.coreos.com 37 | resources: 38 | - catalogsources 39 | verbs: 40 | - get 41 | # cluster watch CommonService 42 | - apiGroups: 43 | - operator.ibm.com 44 | resources: 45 | - commonservices 46 | verbs: 47 | - get 48 | - list 49 | - watch 50 | # create CRD permission 51 | - apiGroups: 52 | - apiextensions.k8s.io 53 | resources: 54 | - customresourcedefinitions 55 | verbs: 56 | - create 57 | - get 58 | - update 59 | # create rbac 60 | - apiGroups: 61 | - rbac.authorization.k8s.io 62 | resources: 63 | - clusterroles 64 | - clusterrolebindings 65 | - roles 66 | - rolebindings 67 | verbs: 68 | - create 69 | - delete 70 | - get 71 | - list 72 | - update 73 | - watch 74 | # create common-service-maps configmap in kube-public 75 | - apiGroups: 76 | - "" 77 | resources: 78 | - configmaps 79 | verbs: 80 | - create 81 | - get 82 | - list 83 | - patch 84 | - update 85 | - watch 86 | # cluster role from secretshare 87 | # create namespace it it doesn't exist 88 | - verbs: 89 | - create 90 | - get 91 | - list 92 | - watch 93 | apiGroups: 94 | - '' 95 | resources: 96 | - namespaces 97 | # copy secret and configmap to other namespaces 98 | - verbs: 99 | - create 100 | - delete 101 | - get 102 | - list 103 | - patch 104 | - update 105 | - watch 106 | apiGroups: 107 | - '' 108 | resources: 109 | - events 110 | - configmaps 111 | - secrets 112 | - pods 113 | # manage its own CR 114 | - verbs: 115 | - create 116 | - delete 117 | - get 118 | - list 119 | - patch 120 | - update 121 | - watch 122 | apiGroups: 123 | - ibmcpcs.ibm.com 124 | resources: 125 | - secretshares 126 | - secretshares/status 127 | # check if subscription is created 128 | - verbs: 129 | - get 130 | - list 131 | - watch 132 | apiGroups: 133 | - operators.coreos.com 134 | resources: 135 | - subscriptions 136 | # cluster role from ibm-common-service-webhook 137 | # patch labels to the namespace 138 | - apiGroups: 139 | - "" 140 | resources: 141 | - namespaces 142 | verbs: 143 | - list 144 | - get 145 | - update 146 | - watch 147 | # get and update pod 148 | - apiGroups: 149 | - "" 150 | resources: 151 | - pods 152 | verbs: 153 | - list 154 | - get 155 | - create 156 | - watch 157 | - update 158 | - patch 159 | # manage its own CR 160 | - apiGroups: 161 | - operator.ibm.com 162 | resources: 163 | - podpresets 164 | - podpresets/status 165 | verbs: 166 | - create 167 | - delete 168 | - get 169 | - list 170 | - patch 171 | - update 172 | - watch 173 | # manage mutation webhook configuration 174 | - apiGroups: 175 | - admissionregistration.k8s.io 176 | resources: 177 | - mutatingwebhookconfigurations 178 | - validatingwebhookconfigurations 179 | verbs: 180 | - create 181 | - delete 182 | - get 183 | - list 184 | - patch 185 | - update 186 | - watch 187 | --- 188 | apiVersion: rbac.authorization.k8s.io/v1 189 | kind: Role 190 | metadata: 191 | name: ibm-common-service-operator 192 | rules: 193 | - apiGroups: 194 | - "*" 195 | resources: 196 | - "*" 197 | verbs: 198 | - create 199 | - delete 200 | - get 201 | - list 202 | - patch 203 | - update 204 | - watch 205 | -------------------------------------------------------------------------------- /testdata/deploy/role.yaml.bak: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: ibm-common-service-operator 5 | rules: 6 | # create ibm-common-services namespace permission 7 | - apiGroups: 8 | - "" 9 | resourceNames: 10 | - ibm-common-services 11 | resources: 12 | - namespaces 13 | verbs: 14 | - list 15 | - get 16 | - watch 17 | - create 18 | - update 19 | # create subscriptions & operatorgroup permission in ibm-common-services 20 | - apiGroups: 21 | - operators.coreos.com 22 | resources: 23 | - subscriptions 24 | - operatorgroups 25 | verbs: 26 | - list 27 | - get 28 | - watch 29 | - create 30 | - update 31 | # create common-service-maps configmap in kube-public 32 | - apiGroups: 33 | - "" 34 | resources: 35 | - configmaps 36 | verbs: 37 | - create 38 | - get 39 | - list 40 | - patch 41 | - update 42 | - watch 43 | # create CRD permission 44 | - apiGroups: 45 | - apiextensions.k8s.io 46 | resources: 47 | - customresourcedefinitions 48 | verbs: 49 | - create 50 | - get 51 | - patch 52 | - update 53 | # create rbac 54 | - apiGroups: 55 | - rbac.authorization.k8s.io 56 | resources: 57 | - clusterroles 58 | - clusterrolebindings 59 | - roles 60 | - rolebindings 61 | verbs: 62 | - create 63 | - delete 64 | - get 65 | - list 66 | - patch 67 | - update 68 | - watch 69 | # ?? 70 | - apiGroups: 71 | - operator.ibm.com 72 | resources: 73 | - commonservices 74 | - operandconfigs 75 | - operandregistries 76 | verbs: 77 | - create 78 | - delete 79 | - get 80 | - list 81 | - patch 82 | - update 83 | - watch 84 | # ?? 85 | - apiGroups: 86 | - "" 87 | resources: 88 | - namespaces 89 | verbs: 90 | - list 91 | - get 92 | - update 93 | - watch 94 | # ?? 95 | - apiGroups: 96 | - "" 97 | resources: 98 | - pods 99 | verbs: 100 | - list 101 | - get 102 | - create 103 | # ?? 104 | - apiGroups: 105 | - operator.ibm.com 106 | resources: 107 | - '*' 108 | verbs: 109 | - create 110 | - delete 111 | - get 112 | - list 113 | - patch 114 | - update 115 | - watch 116 | # used for webhook operator 117 | - apiGroups: 118 | - admissionregistration.k8s.io 119 | resources: 120 | - mutatingwebhookconfigurations 121 | - validatingwebhookconfigurations 122 | verbs: 123 | - '*' 124 | - apiGroups: 125 | - "" 126 | resources: 127 | - pods 128 | - namespaces 129 | - services 130 | - services/finalizers 131 | - endpoints 132 | - persistentvolumeclaims 133 | - events 134 | - configmaps 135 | - secrets 136 | verbs: 137 | - create 138 | - delete 139 | - get 140 | - list 141 | - patch 142 | - update 143 | - watch 144 | - apiGroups: 145 | - apps 146 | resources: 147 | - deployments 148 | - daemonsets 149 | - replicasets 150 | - statefulsets 151 | verbs: 152 | - create 153 | - delete 154 | - get 155 | - list 156 | - patch 157 | - update 158 | - watch 159 | - apiGroups: 160 | - monitoring.coreos.com 161 | resources: 162 | - servicemonitors 163 | verbs: 164 | - get 165 | - create 166 | - apiGroups: 167 | - apps 168 | resourceNames: 169 | - secretshare 170 | resources: 171 | - deployments/finalizers 172 | verbs: 173 | - update 174 | - get 175 | - list 176 | - watch 177 | - apiGroups: 178 | - ibmcpcs.ibm.com 179 | resources: 180 | - '*' 181 | verbs: 182 | - create 183 | - delete 184 | - get 185 | - list 186 | - patch 187 | - update 188 | - watch 189 | - apiGroups: 190 | - ibmcpcs.ibm.com 191 | resources: 192 | - secretshares 193 | - secretshares/status 194 | verbs: 195 | - create 196 | - delete 197 | - get 198 | - list 199 | - patch 200 | - update 201 | - watch 202 | - apiGroups: 203 | - operators.coreos.com 204 | resources: 205 | - subscriptions 206 | verbs: 207 | - get 208 | - list 209 | - watch 210 | 211 | -- 212 | apiVersion: rbac.authorization.k8s.io/v1 213 | kind: Role 214 | metadata: 215 | name: ibm-common-service-operator 216 | rules: 217 | - apiGroups: 218 | - "*" 219 | resources: 220 | - "*" 221 | verbs: 222 | - create 223 | - delete 224 | - get 225 | - list 226 | - patch 227 | - update 228 | - watch 229 | -------------------------------------------------------------------------------- /testdata/deploy/role_binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: ibm-common-service-operator 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: ClusterRole 8 | name: ibm-common-service-operator 9 | subjects: 10 | - kind: ServiceAccount 11 | name: ibm-common-service-operator 12 | namespace: common-service 13 | - kind: ServiceAccount 14 | name: ibm-common-service-operator 15 | namespace: ibm-common-services 16 | 17 | --- 18 | apiVersion: rbac.authorization.k8s.io/v1 19 | kind: RoleBinding 20 | metadata: 21 | name: ibm-common-service-operator 22 | roleRef: 23 | apiGroup: rbac.authorization.k8s.io 24 | kind: Role 25 | name: ibm-common-service-operator 26 | subjects: 27 | - kind: ServiceAccount 28 | name: ibm-common-service-operator 29 | -------------------------------------------------------------------------------- /testdata/deploy/sa.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: ibm-common-service-operator 5 | -------------------------------------------------------------------------------- /testdata/sizing/large_mongodb.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: operator.ibm.com/v3 2 | kind: CommonService 3 | metadata: 4 | name: common-service 5 | spec: 6 | size: small 7 | services: 8 | - name: ibm-mongodb-operator 9 | spec: 10 | mongoDB: 11 | replicas: 3 12 | resources: 13 | limits: 14 | cpu: 5000m 15 | memory: 3Gi 16 | requests: 17 | cpu: 5000m 18 | memory: 3Gi 19 | -------------------------------------------------------------------------------- /testdata/sizing/large_size.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: operator.ibm.com/v3 2 | kind: CommonService 3 | metadata: 4 | name: common-service 5 | spec: 6 | size: large 7 | -------------------------------------------------------------------------------- /testdata/sizing/medium_size.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: operator.ibm.com/v3 2 | kind: CommonService 3 | metadata: 4 | name: common-service 5 | spec: 6 | size: medium 7 | -------------------------------------------------------------------------------- /testdata/sizing/operandrequest.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: operator.ibm.com/v1alpha1 2 | kind: OperandRequest 3 | metadata: 4 | name: common-service 5 | spec: 6 | requests: 7 | - registry: common-service 8 | operands: 9 | - name: ibm-mongodb-operator 10 | -------------------------------------------------------------------------------- /testdata/sizing/storage_class.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: operator.ibm.com/v3 2 | kind: CommonService 3 | metadata: 4 | name: common-service 5 | spec: 6 | services: 7 | - name: ibm-mongodb-operator 8 | spec: 9 | mongoDB: 10 | storageClass: rook-cephfs 11 | -------------------------------------------------------------------------------- /testdata/test_profile.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Copyright 2022 IBM Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | set -o errexit 19 | set -o nounset 20 | set -o errtrace 21 | set -o pipefail 22 | 23 | YQ=$1 24 | BASE_DIR=testdata 25 | 26 | test_profile() { 27 | local size_file=$1 28 | 29 | echo "testing with file: $size_file" 30 | 31 | # keys to remove from controllers/size files before comparison 32 | # necessary because size files in controllers/size missing many keys that 33 | # OperandConfig can have 34 | local REMOVE_KEYS=".IBMLicenseServiceReporter?, .operandBindInfo?, .operandRequest?, \ 35 | .datasource?, .mustgatherConfig?, .mustgatherService?, .navconfiguration?, \ 36 | .switcheritem?, .certificate?, .clusterIssuer?, .issuer?" 37 | 38 | # get expected size 39 | # first sed gets the variable in size file 40 | # second sed strips first and last line to remove "`" 41 | # jq commands are to sort and delete unnecessary keys for proper comparison 42 | sed -n '/`/,/`/p' $size_file | sed '1d;$d' | $YQ eval -j '.' - \ 43 | | jq -S '. |= sort_by (.name)' | jq "del(.. | $REMOVE_KEYS)" \ 44 | > $BASE_DIR/expected.yaml 45 | 46 | # get actual size 47 | oc -n ibm-common-services get operandconfig common-service -o json \ 48 | | jq '.spec.services' - | jq -S '. |= sort_by (.name)' \ 49 | | jq "del(.. | $REMOVE_KEYS)" \ 50 | > $BASE_DIR/actual.yaml 51 | 52 | # if files are different, show the difference 53 | diff --brief $BASE_DIR/expected.yaml $BASE_DIR/actual.yaml 54 | } 55 | 56 | NAMESPACE=test-profile-ns 57 | oc create ns $NAMESPACE 58 | 59 | cleanup() { 60 | oc delete ns $NAMESPACE 61 | } 62 | 63 | trap 'cleanup' EXIT 64 | 65 | test_profile controllers/size/small_amd64.go 66 | 67 | oc -n $NAMESPACE apply -f testdata/sizing/medium_size.yaml 68 | sleep 15 69 | test_profile controllers/size/medium_amd64.go 70 | 71 | oc -n $NAMESPACE apply -f testdata/sizing/large_size.yaml 72 | sleep 15 73 | test_profile controllers/size/large_amd64.go 74 | -------------------------------------------------------------------------------- /testing.md: -------------------------------------------------------------------------------- 1 | # How to test changes 2 | The testing commands rely on having access to the following registries: 3 | ``` 4 | quay.io/opencloudio 5 | docker-na-public.artifactory.swg-devops.com/hyc-cloud-private-scratch-docker-local/ibmcom 6 | ``` 7 | 8 | If you do not have access or would prefer to use different registries then you can overwrite them with: 9 | ``` 10 | export QUAY_REGISTRY= 11 | export REGISTRY= 12 | ``` 13 | 14 | The QUAY_REGISTRY value must point to a public registry because `operator-sdk run bundle` does not work with private registries currently (as of v1.5.0). 15 | 16 | If pushing an image to your quay.io registry with its first tag, the image repository may be set to private by default, so you will need to login to quay.io and change the repository settings to public. 17 | 18 | Also create a CatalogSource 19 | ``` 20 | cat <(oc apply -f -) | cat 21 | apiVersion: operators.coreos.com/v1alpha1 22 | kind: CatalogSource 23 | metadata: 24 | name: opencloud-operators 25 | namespace: openshift-marketplace 26 | spec: 27 | displayName: opencloud-operators 28 | publisher: IBM 29 | sourceType: grpc 30 | image: quay.io/opencloudio/ibm-common-service-catalog:3.7.1 31 | updateStrategy: 32 | registryPoll: 33 | interval: 45m 34 | EOF 35 | ``` 36 | 37 | The actual testing consist of: 38 | 1. verify common-service operator pod is Running 39 | 2. verify namespace scope operator and ODLM operator are installed 40 | 3. verify secretshare and common-service-webhook pods are running 41 | 4. verify functionality of common-service operator such as: 42 | - size profile 43 | 44 | ## Test fresh installation with bundle 45 | 1. add features/fixes to repo 46 | 2. change `image` value in config/manager/manager.yaml to `quay.io//common-service-operator:dev` 47 | - and any of the operand image values if necessary 48 | 3. build operator with changes 49 | ``` 50 | make build-dev-image 51 | ``` 52 | 4. build bundle containing changes and bundle image 53 | ``` 54 | make bundle-manifests RELEASE_VERSION=99.99.99 55 | make build-bundle-image RELEASE_VERSION=dev 56 | ``` 57 | 5. deploy operator using bundle format 58 | ``` 59 | make run-bundle RELEASE_VERSION=dev 60 | ``` 61 | 6. run tests 62 | 7. clean up 63 | ``` 64 | make cleanup-bundle 65 | ``` 66 | 67 | ## Test upgrade with bundle 68 | Similar to fresh installation test except you will first deploy the operator/bundle of the most recent release without any changes, i.e. the operator/bundle code from the most recent commit in master branch 69 | 70 | 1. deploy unchanged operator with official bundle image 71 | ``` 72 | make run-bundle BUNDLE_IMAGE_NAME=ibm-common-service-operator-bundle 73 | ``` 74 | 75 | If using your own registries, you can pull the official bundle image, and then push it to your registry 76 | ``` 77 | docker pull quay.io/opencloudio/ibm-common-service-operator-bundle: 78 | docker tag quay.io/opencloudio/ibm-common-service-operator-bundle: /dev-common-service-operator-bundle: 79 | docker push /dev-common-service-operator-bundle: 80 | make run-bundle 81 | ``` 82 | 2. add features/fixes to repo 83 | 3. change `image` value in config/manager/manager.yaml to `quay.io//common-service-operator:dev` 84 | - and any of the operand image values if necessary 85 | 4. build operator with changes 86 | ``` 87 | make build-dev-image 88 | ``` 89 | 5. build bundle containing changes and bundle image 90 | ``` 91 | make bundle-manifests RELEASE_VERSION=99.99.99 92 | make build-bundle-image RELEASE_VERSION=dev 93 | ``` 94 | 6. upgrade operator 95 | ``` 96 | make upgrade-bundle 97 | ``` 98 | 7. run tests 99 | 8. clean up 100 | ``` 101 | make cleanup-bundle 102 | ``` 103 | -------------------------------------------------------------------------------- /version/version.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2022 IBM Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package version 18 | 19 | var ( 20 | Version = "4.13.0" 21 | ) 22 | --------------------------------------------------------------------------------