├── .github ├── .codecov.yaml └── workflows │ ├── changelog_config.json │ ├── pr.yml │ ├── release.yml │ └── tests │ ├── cleanup.sh │ ├── pre-release.json │ └── release.json ├── .gitignore ├── .golangci.yml ├── Dockerfile ├── LICENSE ├── Makefile ├── PROJECT ├── api └── v1 │ ├── components │ ├── controller.go │ ├── csi.go │ ├── drivemgr.go │ ├── driver.go │ ├── image.go │ ├── log.go │ ├── logreceiver.go │ ├── metrics.go │ ├── node.go │ ├── node_controller.go │ ├── node_selector.go │ ├── openshift_secondary_scheduler.go │ ├── patcher.go │ ├── pod_security_policy.go │ ├── resources.go │ ├── scheduler.go │ ├── security_context.go │ └── sidecar.go │ ├── deployment_types.go │ ├── groupversion_info.go │ └── zz_generated.deepcopy.go ├── charts ├── README.md ├── csi-baremetal-deployment │ ├── Chart.yaml │ ├── templates │ │ ├── NOTES.txt │ │ ├── _helpers.tpl │ │ ├── configmap │ │ │ ├── fluent-bit-config-map.yaml │ │ │ ├── loopbackmgr-config.yaml │ │ │ └── node-config.yaml │ │ ├── csi-baremetal_v1_deployment.yaml │ │ ├── csidriver │ │ │ └── csidriver.yaml │ │ ├── rbac │ │ │ ├── controller-rbac.yaml │ │ │ ├── csibm-rbac.yaml │ │ │ ├── node-rbac.yaml │ │ │ └── scheduler-rbac.yaml │ │ ├── service │ │ │ └── csi-smart-info-backend-svc.yaml │ │ └── storageclass │ │ │ ├── default-sc.yaml │ │ │ ├── hdd-sc.yaml │ │ │ ├── hddlvg-sc.yaml │ │ │ ├── nvme-raw-part-sc.yaml │ │ │ ├── nvme-sc.yaml │ │ │ ├── nvmelvg-sc.yaml │ │ │ ├── ssd-sc.yaml │ │ │ ├── ssdlvg-sc.yaml │ │ │ └── syslvg-sc.yaml │ └── values.yaml ├── csi-baremetal-operator │ ├── Chart.yaml │ ├── crds │ │ ├── csi-baremetal.dell.com_availablecapacities.yaml │ │ ├── csi-baremetal.dell.com_availablecapacityreservations.yaml │ │ ├── csi-baremetal.dell.com_deployments.yaml │ │ ├── csi-baremetal.dell.com_drives.yaml │ │ ├── csi-baremetal.dell.com_logicalvolumegroups.yaml │ │ ├── csi-baremetal.dell.com_nodes.yaml │ │ ├── csi-baremetal.dell.com_storagegroups.yaml │ │ └── csi-baremetal.dell.com_volumes.yaml │ ├── templates │ │ ├── manager.yaml │ │ ├── pre-upgrade-crds.yaml │ │ └── rbac.yaml │ └── values.yaml └── secondary-scheduler-operator │ ├── Chart.yaml │ ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── post-install-job.yaml │ ├── pre-delete-job.yaml │ ├── pre-install-job.yaml │ ├── role.yaml │ ├── rolebinding.yaml │ ├── serviceaccount.yaml │ └── subscription.yaml │ └── values.yaml ├── config ├── certmanager │ ├── certificate.yaml │ ├── kustomization.yaml │ └── kustomizeconfig.yaml ├── crd │ ├── kustomization.yaml │ ├── kustomizeconfig.yaml │ └── patches │ │ ├── cainjection_in_deployments.yaml │ │ └── webhook_in_deployments.yaml ├── default │ ├── kustomization.yaml │ ├── manager_auth_proxy_patch.yaml │ ├── manager_webhook_patch.yaml │ └── webhookcainjection_patch.yaml ├── manager │ ├── kustomization.yaml │ └── manager.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 │ ├── deployment_editor_role.yaml │ ├── deployment_viewer_role.yaml │ ├── kustomization.yaml │ ├── leader_election_role.yaml │ ├── leader_election_role_binding.yaml │ ├── role.yaml │ └── role_binding.yaml └── webhook │ ├── kustomization.yaml │ ├── kustomizeconfig.yaml │ ├── manifests.yaml │ └── service.yaml ├── controllers └── deployment_controller.go ├── deploy ├── configmap │ ├── fluent-bit-config-map.yaml │ ├── loopbackmgr-config.yaml │ └── patcher-configmap.yaml ├── csidriver │ └── csidriver.yaml ├── monitoring │ ├── csi-pod-monitor.yaml │ └── monitoring-configmap.yaml ├── rbac │ ├── controller-rbac.yaml │ ├── csibm-rbac.yaml │ ├── node-rbac.yaml │ └── rbac.yaml └── storageclass │ ├── default-sc.yaml │ ├── hdd-sc.yaml │ ├── hddlvg-sc.yaml │ ├── nvme-sc.yaml │ ├── ssd-sc.yaml │ ├── ssdlvg-sc.yaml │ └── syslvg-sc.yaml ├── docs ├── CODEOWNERS ├── MANUAL_SCHEDULER_CONFIGURATION.md ├── MIGRATION_BETWEEN_NAMESPACES.md ├── MONITORING_ON_OPENSHIFT.md ├── PULL_REQUEST_TEMPLATE.md └── README.md ├── go.mod ├── go.sum ├── hack └── boilerplate.go.txt ├── hook └── Dockerfile ├── main.go ├── pkg ├── acrvalidator │ ├── acr_validator.go │ └── acr_validator_test.go ├── common │ ├── common.go │ ├── common_test.go │ ├── update.go │ └── update_test.go ├── constant │ ├── const.go │ └── platforms.go ├── controller.go ├── controller_test.go ├── csi_deployment.go ├── csi_deployment_test.go ├── feature │ └── security_verifier │ │ ├── error.go │ │ ├── interface.go │ │ ├── models │ │ └── components.go │ │ ├── pod_security_policy.go │ │ └── security_context_constraints.go ├── imports │ └── imports.go ├── node │ ├── node.go │ ├── node_daemonset.go │ ├── node_daemonset_test.go │ ├── node_test.go │ ├── parser.go │ ├── parser_test.go │ └── platform_description.go ├── node_controller.go ├── node_controller_test.go ├── nodeoperations │ ├── controller.go │ ├── controller_test.go │ ├── delete_objects.go │ └── delete_objects_test.go ├── patcher │ ├── extender_readiness.go │ ├── extender_readiness_test.go │ ├── patcher_configuration.go │ ├── patcher_configuration_test.go │ ├── scheduler_patcher.go │ ├── scheduler_patcher_openshift.go │ ├── scheduler_patcher_openshift_test.go │ ├── scheduler_patcher_vanilla.go │ └── scheduler_patcher_vanilla_test.go ├── scheduler_extender.go ├── scheduler_extender_test.go └── validator │ ├── interfaces.go │ ├── models │ └── rbac.go │ ├── rbac │ ├── error.go │ ├── matcher.go │ ├── models │ │ └── rules.go │ └── validator.go │ └── validator.go └── variables.mk /.github/.codecov.yaml: -------------------------------------------------------------------------------- 1 | coverage: 2 | range: 70..85 3 | round: down 4 | precision: 2 5 | status: 6 | project: 7 | default: 8 | threshold: 1% 9 | ignore: 10 | - "pkg/node/node_daemonset.go" 11 | - "pkg/patcher/scheduler_patcher_vanilla.go" 12 | -------------------------------------------------------------------------------- /.github/workflows/changelog_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "categories": [ 3 | { 4 | "title": "## 🚀 Enhancements", 5 | "labels": [ 6 | "enhancement" 7 | ] 8 | }, 9 | { 10 | "title": "## 🐛 Bugs", 11 | "labels": [ 12 | "bug" 13 | ] 14 | }, 15 | { 16 | "title": "## 📙 Documentation", 17 | "labels": [ 18 | "documentation" 19 | ] 20 | } 21 | ], 22 | "sort": "ASC", 23 | "template": "${{CHANGELOG}}\n\n
\nUncategorized\n\n${{UNCATEGORIZED}}\n
", 24 | "pr_template": "- ${{TITLE}}\n - PR: #${{NUMBER}}", 25 | "empty_template": "- no changes", 26 | "label_extractor": [ 27 | { 28 | "pattern": "(.) (.+)", 29 | "target": "$1", 30 | "flags": "gu" 31 | }, 32 | { 33 | "pattern": "\\[Issue\\]", 34 | "on_property": "title", 35 | "method": "match" 36 | } 37 | ], 38 | "duplicate_filter": { 39 | "pattern": "\\[ABC-....\\]", 40 | "on_property": "title", 41 | "method": "match" 42 | }, 43 | "transformers": [ 44 | { 45 | "pattern": "[\\-\\*] (\\[(...|TEST|CI|SKIP)\\])( )?(.+?)\n(.+?[\\-\\*] )(.+)", 46 | "target": "- $4\n - $6" 47 | } 48 | ], 49 | "max_tags_to_fetch": 200, 50 | "max_pull_requests": 200, 51 | "max_back_track_time_days": 365, 52 | "tag_resolver": { 53 | "method": "semver" 54 | }, 55 | "base_branches": [ 56 | "master" 57 | ] 58 | } -------------------------------------------------------------------------------- /.github/workflows/pr.yml: -------------------------------------------------------------------------------- 1 | name: PR validation 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | env: 9 | go_version: '1.21.12' 10 | golangci_version: '1.55.2' 11 | jobs: 12 | lint-test: 13 | name: Validate code and build it 14 | runs-on: ubuntu-22.04 15 | container: 16 | image: ghcr.io/dell/csi-baremetal/csi-baremetal-devkit:latest 17 | env: 18 | EUID: 0 19 | EGID: 0 20 | USER_NAME: root 21 | STDOUT: true 22 | volumes: 23 | - /root:/root 24 | - /tmp:/tmp 25 | - /var/run/docker.sock:/var/run/docker.sock 26 | steps: 27 | - name: Trust My Directory # workaround for https://github.com/actions/checkout/issues/760 28 | run: git config --global --add safe.directory /__w/csi-baremetal-operator/csi-baremetal-operator 29 | 30 | - name: Check out code 31 | uses: actions/checkout@v3 32 | 33 | - name: Set go_version variable 34 | run: echo "go_version=`echo "$(go version)" | grep -oE '[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}'`" >> $GITHUB_ENV 35 | 36 | - name: Load dep cache 37 | uses: actions/cache@v2 38 | with: 39 | path: ~/go/pkg/mod 40 | key: go-dep-${{ env.go_version }}-${{ hashFiles('**/go.sum') }} 41 | restore-keys: go-dep-${{ env.go_version }}- 42 | 43 | - name: Load build and linter cache 44 | uses: actions/cache@v2 45 | with: 46 | path: | 47 | ~/.cache/go-build 48 | ~/.cache/golangci-lint 49 | key: go-build-${{ env.go_version }}-${{ hashFiles('**/go.sum') }}-${{ hashFiles('**/pkg') }} 50 | restore-keys: | 51 | go-build-${{ env.go_version }}-${{ hashFiles('**/go.sum') }} 52 | go-build-${{ env.go_version }}- 53 | 54 | - name: Get dependencies 55 | run: go mod download 56 | 57 | - name: Lint code 58 | run: GOGC=300 make lint-code 59 | 60 | - name: Lint chart 61 | run: make lint-operator-chart 62 | 63 | - name: Build binary 64 | run: | 65 | make manager 66 | 67 | - name: Run tests 68 | run: | 69 | make test 70 | 71 | - name: Coverage 72 | run: make coverage 73 | 74 | - name: Upload coverage report to artifacts 75 | uses: actions/upload-artifact@v4.6.0 76 | with: 77 | name: coverage.html 78 | path: ./coverage.html 79 | 80 | - name: Upload coverage report to codecov 81 | uses: codecov/codecov-action@v3 82 | with: 83 | file: ./coverage.out 84 | flags: unittests 85 | verbose: true 86 | 87 | # - name: Generate CRD 88 | # run: | 89 | # make generate-operator-crds 90 | # 91 | # - name: Verify CRD changes 92 | # uses: tj-actions/verify-changed-files@v16.1.1 93 | # id: changed_files 94 | # with: 95 | # files: | 96 | # charts/csi-baremetal-operator/crds/*.yaml 97 | # 98 | # - name: Display changed files 99 | # if: steps.changed_files.outputs.files_changed == 'true' 100 | # run: | 101 | # echo "Changed files: ${{ steps.changed_files.outputs.changed_files }}" 102 | # 103 | # - name: Fail action when files change 104 | # if: steps.changed_files.outputs.files_changed == 'true' 105 | # run: | 106 | # exit 1 107 | -------------------------------------------------------------------------------- /.github/workflows/tests/cleanup.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/bash 2 | GH_USER="dell" 3 | GH_API_URL="https://api.github.com" 4 | REPO="csi-baremetal-operator" 5 | TEST_TAG="v1.1.0-test" 6 | TEST_RELEASE_ID=$(curl $GH_API_URL/repos/$GH_USER/$REPO/releases/tags/$TEST_TAG | jq -r '.id') 7 | CR_PAT=$(cat .github/workflows/tests/wf.secrets | awk -F "=" '{print $2}') 8 | TEST_RELEASE_URL=$GH_API_URL/repos/$GH_USER/$REPO/releases/$TEST_RELEASE_ID 9 | curl -u $GH_USER:$CR_PAT -X DELETE $TEST_RELEASE_URL 10 | git tag -d $TEST_TAG 11 | git push --delete https://$GH_USER:$CR_PAT@github.com/$GH_USER/$REPO.git $TEST_TAG -------------------------------------------------------------------------------- /.github/workflows/tests/pre-release.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputs": { 3 | "csi_version": "1.1.0-569.d875c82", 4 | "csi_operator_version": "1.1.0-99.36a85e3", 5 | "release_tag": "v1.1.0-test", 6 | "branch": "master", 7 | "prerelease": false 8 | }, 9 | "workflow": ".github/workflows/release.yml" 10 | } -------------------------------------------------------------------------------- /.github/workflows/tests/release.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputs": { 3 | "csi_version": "1.1.0-569.d875c82", 4 | "csi_operator_version": "1.1.0-99.36a85e3", 5 | "release_tag": "v1.1.0-test", 6 | "branch": "master", 7 | "prerelease": false 8 | }, 9 | "workflow": ".github/workflows/release.yml" 10 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Binaries for programs and plugins 3 | *.exe 4 | *.exe~ 5 | *.dll 6 | *.so 7 | *.dylib 8 | bin/controller-gen 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 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Build the manager binary 2 | ARG BASE_IMAGE 3 | FROM $BASE_IMAGE as builder 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 main.go main.go 15 | COPY api/ api/ 16 | COPY controllers/ controllers/ 17 | COPY pkg/ pkg/ 18 | 19 | # Build 20 | RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -a -o manager main.go 21 | 22 | # Use distroless as minimal base image to package the manager binary 23 | # Refer to https://github.com/GoogleContainerTools/distroless for more details 24 | FROM gcr.io/distroless/static:nonroot 25 | WORKDIR / 26 | COPY --from=builder /workspace/manager . 27 | USER nonroot:nonroot 28 | 29 | ENTRYPOINT ["/manager"] 30 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | include variables.mk 2 | 3 | # Image URL to use all building/pushing image targets 4 | IMG ?= ${REGISTRY}/csi-baremetal-operator:${TAG} 5 | 6 | # Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) 7 | ifeq (,$(shell go env GOBIN)) 8 | GOBIN=$(shell go env GOPATH)/bin 9 | else 10 | GOBIN=$(shell go env GOBIN) 11 | endif 12 | 13 | # Print version 14 | version: 15 | @printf $(TAG) 16 | 17 | all: manager 18 | 19 | ### Unit tests 20 | 21 | coverage: 22 | go tool cover -html=coverage.out -o coverage.html 23 | 24 | test: 25 | ${GO_ENV_VARS} go test `go list ./... | grep pkg` -race -cover -coverprofile=coverage.out -covermode=atomic 26 | 27 | # Build manager binary 28 | manager: fmt vet 29 | go build -o bin/manager main.go 30 | 31 | # Run against the configured Kubernetes cluster in ~/.kube/config 32 | run: fmt vet resources 33 | go run ./main.go 34 | 35 | # Install CRDs into a cluster 36 | install: 37 | kustomize build config/crd | kubectl apply -f - 38 | 39 | # Uninstall CRDs from a cluster 40 | uninstall: manifests 41 | kustomize build config/crd | kubectl delete -f - 42 | 43 | # Deploy controller in the configured Kubernetes cluster in ~/.kube/config 44 | deploy: 45 | cd config/manager && kustomize edit set image controller=${IMG} 46 | kustomize build config/default | kubectl apply -f - 47 | 48 | # Deploy CSI resources from ~/deploy 49 | resources: 50 | kubectl apply -f config/crd/bases 51 | kubectl apply -f deploy/rbac 52 | kubectl apply -f deploy/storageclass 53 | kubectl apply -f deploy/configmap 54 | kubectl apply -f deploy/csidriver 55 | 56 | # Generate manifests e.g. CRD, RBAC etc. 57 | manifests: controller-gen 58 | $(CONTROLLER_GEN) $(CRD_OPTIONS) rbac:roleName=manager-role webhook paths="./..." output:crd:artifacts:config=config/crd/bases 59 | 60 | # Run go fmt against code 61 | fmt: 62 | go fmt ./... 63 | 64 | # Run go vet against code 65 | vet: 66 | go vet ./... 67 | 68 | # Build the docker image 69 | docker-build: build-pre-upgrade-crds-image 70 | docker build --build-arg BASE_IMAGE=${BASE_IMAGE} . -t ${IMG} 71 | 72 | # Build the docker image 73 | kind-load: kind-load-pre-upgrade-crds-image 74 | kind load docker-image ${IMG} 75 | 76 | # Push the docker image 77 | docker-push: push-pre-upgrade-crds-image 78 | docker push ${IMG} 79 | 80 | # build controller-gen executable 81 | install-controller-gen: 82 | ${GO_ENV_VARS} go build -mod='' -o ./bin/ sigs.k8s.io/controller-tools/cmd/controller-gen 83 | 84 | # generate crds with controller-gen 85 | generate-operator-crds: install-controller-gen 86 | $(CONTROLLER_GEN_BIN) $(CRD_OPTIONS) paths=api/v1/deployment_types.go paths=api/v1/groupversion_info.go output:crd:dir=$(CSI_CHART_CRDS_PATH) 87 | 88 | lint-operator-chart: 89 | helm lint ./${CSI_OPERATOR_CHART_PATH} 90 | 91 | lint-code: 92 | ${GO_ENV_VARS} golangci-lint -v run --timeout 3m ./... 93 | 94 | ### Workflows 95 | workflows-lint: 96 | actionlint 97 | 98 | test-release: 99 | act workflow_dispatch -e .github/workflows/tests/release.json --secret-file .github/workflows/tests/wf.secrets 100 | $(MAKE) cleanup 101 | 102 | test-pre-release: 103 | act workflow_dispatch -e .github/workflows/tests/pre-release.json --secret-file .github/workflows/tests/wf.secrets 104 | $(MAKE) cleanup 105 | 106 | test-release-workflow: test-pre-release test-release 107 | 108 | cleanup: 109 | bash .github/workflows/tests/cleanup.sh 110 | 111 | build-pre-upgrade-crds-image: 112 | echo "Building container image pre-upgrade-crds" 113 | docker build -t ${CRD_BUILD_IMAGE} --build-arg KUBECTL_IMAGE=${KUBECTL_IMAGE} -f ./hook/Dockerfile . 114 | 115 | push-pre-upgrade-crds-image: 116 | docker push ${CRD_BUILD_IMAGE} 117 | 118 | kind-load-pre-upgrade-crds-image: 119 | kind load docker-image ${CRD_BUILD_IMAGE} 120 | -------------------------------------------------------------------------------- /PROJECT: -------------------------------------------------------------------------------- 1 | domain: dell.com 2 | repo: github.com/dell/csi-baremetal-operator 3 | resources: 4 | - group: csi-baremetal 5 | kind: Deployment 6 | version: v1 7 | version: "2" 8 | -------------------------------------------------------------------------------- /api/v1/components/controller.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2021 Dell Inc. or its subsidiaries. All Rights Reserved. 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 components 18 | 19 | // Controller encapsulates logic for CSI controller component 20 | type Controller struct { 21 | Image *Image `json:"image,omitempty"` 22 | Log *Log `json:"log,omitempty"` 23 | Sidecars map[string]*Sidecar `json:"sidecars,omitempty"` 24 | // +nullable 25 | // +optional 26 | Resources *ResourceRequirements `json:"resources,omitempty"` 27 | // FastDelay is the parameter for NewItemFastSlowRateLimiter in Reservation Controller 28 | // +kubebuilder:default:="1500ms" 29 | FastDelay string `json:"fastDelay,omitempty"` 30 | // SlowDelay is the parameter for NewItemFastSlowRateLimiter in Reservation Controller 31 | // +kubebuilder:default:="12s" 32 | SlowDelay string `json:"slowDelay,omitempty"` 33 | // MaxFastAttempts is the parameter for NewItemFastSlowRateLimiter in Reservation Controller 34 | // +kubebuilder:default:=30 35 | MaxFastAttempts uint `json:"maxFastAttempts,omitempty"` 36 | SecurityContext *SecurityContext `json:"securityContext,omitempty"` 37 | } 38 | -------------------------------------------------------------------------------- /api/v1/components/csi.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2021 Dell Inc. or its subsidiaries. All Rights Reserved. 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 components 18 | 19 | // DeploymentSpec represent all CSI components need to be deployed by operator 20 | type DeploymentSpec struct { 21 | Driver *Driver `json:"driver,omitempty"` 22 | NodeController *NodeController `json:"nodeController,omitempty"` 23 | Scheduler *Scheduler `json:"scheduler,omitempty"` 24 | 25 | // +nullable 26 | // +optional 27 | GlobalRegistry string `json:"globalRegistry"` 28 | // +nullable 29 | // +optional 30 | RegistrySecret string `json:"registrySecret"` 31 | // +kubebuilder:validation:Enum=IfNotPresent;Always;Never 32 | // +kubebuilder:default:=IfNotPresent 33 | PullPolicy string `json:"pullPolicy"` 34 | 35 | NodeSelector *NodeSelector `json:"nodeSelector,omitempty"` 36 | NodeIDAnnotation bool `json:"nodeIDAnnotation,omitempty"` 37 | SequentialLVGReservation bool `json:"sequentialLVGReservation,omitempty"` 38 | 39 | // +kubebuilder:validation:Enum=rke;openshift;vanilla 40 | // +kubebuilder:default:=vanilla 41 | Platform string `json:"platform"` 42 | } 43 | -------------------------------------------------------------------------------- /api/v1/components/drivemgr.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2021 Dell Inc. or its subsidiaries. All Rights Reserved. 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 components 18 | 19 | // DriveMgr represents drive manager node component 20 | type DriveMgr struct { 21 | Image *Image `json:"image,omitempty"` 22 | Endpoint string `json:"endpoint"` 23 | // +nullable 24 | // +optional 25 | Resources *ResourceRequirements `json:"resources,omitempty"` 26 | } 27 | -------------------------------------------------------------------------------- /api/v1/components/driver.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2021 Dell Inc. or its subsidiaries. All Rights Reserved. 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 components 18 | 19 | // Driver represent CSI driver with all necessary CSI components 20 | type Driver struct { 21 | Controller *Controller `json:"controller,omitempty"` 22 | Node *Node `json:"node,omitempty"` 23 | Metrics *Metrics `json:"metrics,omitempty"` 24 | LogReceiver *LogReceiver `json:"logReceiver,omitempty"` 25 | // TODO need to implement this 26 | // +optional 27 | MountRootHost bool `json:"mountRootHost"` 28 | } 29 | -------------------------------------------------------------------------------- /api/v1/components/image.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2021 Dell Inc. or its subsidiaries. All Rights Reserved. 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 components 18 | 19 | // Image contain information for components docker images 20 | type Image struct { 21 | Name string `json:"name"` 22 | Tag string `json:"tag"` 23 | } 24 | -------------------------------------------------------------------------------- /api/v1/components/log.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2021 Dell Inc. or its subsidiaries. All Rights Reserved. 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 components 18 | 19 | // Format is format in which log will appear 20 | type Format string 21 | 22 | const ( 23 | // JSONFormat indicates that log are shown in json format 24 | JSONFormat Format = "json" 25 | // TextFormat indicates that log are shown in usual format 26 | TextFormat Format = "text" 27 | ) 28 | 29 | // Level indicates which types if logging need to be show 30 | type Level string 31 | 32 | const ( 33 | // InfoLevel includes Info, Error, Fatal, Warn logs 34 | InfoLevel Level = "info" 35 | // debug includes InfoLevel and Debug 36 | DebugLevel Level = "debug" 37 | // debug includes InfoLevel, DebugLevel and Trace 38 | TraceLevel Level = "trace" 39 | ) 40 | 41 | // Log is a configuration for logger in components 42 | type Log struct { 43 | Format Format `json:"format"` 44 | Level Level `json:"level"` 45 | } 46 | -------------------------------------------------------------------------------- /api/v1/components/logreceiver.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2021 Dell Inc. or its subsidiaries. All Rights Reserved. 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 components 18 | 19 | // LogReceiver encapsulates information needed to establish log receiver for components 20 | type LogReceiver struct { 21 | Name string `json:"name"` 22 | Image *Image `json:"image,omitempty"` 23 | } 24 | -------------------------------------------------------------------------------- /api/v1/components/metrics.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2021 Dell Inc. or its subsidiaries. All Rights Reserved. 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 components 18 | 19 | // Metrics encapsulates necessary information to expose metric for different components 20 | type Metrics struct { 21 | Path string `json:"path"` 22 | Port uint64 `json:"port"` 23 | } 24 | -------------------------------------------------------------------------------- /api/v1/components/node.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2021 Dell Inc. or its subsidiaries. All Rights Reserved. 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 components 18 | 19 | // Node encapsulates information for CSI node components 20 | type Node struct { 21 | ServiceAccount string `json:"serviceAccount"` 22 | DriveMgr *DriveMgr `json:"driveMgr,omitempty"` 23 | Image *Image `json:"image,omitempty"` 24 | Log *Log `json:"log,omitempty"` 25 | Sidecars map[string]*Sidecar `json:"sidecars,omitempty"` 26 | // +nullable 27 | // +optional 28 | Resources *ResourceRequirements `json:"resources,omitempty"` 29 | PodSecurityPolicy *PodSecurityPolicy `json:"podSecurityPolicy,omitempty"` 30 | } 31 | -------------------------------------------------------------------------------- /api/v1/components/node_controller.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2021 Dell Inc. or its subsidiaries. All Rights Reserved. 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 components 18 | 19 | // NodeController represent operator for CSI bare-metal nodes 20 | type NodeController struct { 21 | Enable bool `json:"enable"` 22 | Image *Image `json:"image,omitempty"` 23 | Log *Log `json:"log,omitempty"` 24 | // +nullable 25 | // +optional 26 | Resources *ResourceRequirements `json:"resources,omitempty"` 27 | } 28 | -------------------------------------------------------------------------------- /api/v1/components/node_selector.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2021 Dell Inc. or its subsidiaries. All Rights Reserved. 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 components 18 | 19 | // NodeSelector contains key-value pair to deploy node components on specific k8sNodes 20 | type NodeSelector struct { 21 | Key string `json:"key,omitempty"` 22 | Value string `json:"value,omitempty"` 23 | } 24 | -------------------------------------------------------------------------------- /api/v1/components/openshift_secondary_scheduler.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2021 Dell Inc. or its subsidiaries. All Rights Reserved. 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 components 18 | 19 | // OpenshiftSecondaryScheduler represents information to deploy Openshift Secondary Scheduler if applicable 20 | type OpenshiftSecondaryScheduler struct { 21 | Image *Image `json:"image,omitempty"` 22 | } 23 | -------------------------------------------------------------------------------- /api/v1/components/patcher.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2021 Dell Inc. or its subsidiaries. All Rights Reserved. 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 components 18 | 19 | // Patcher represents scheduler patcher container, which tries to patch Kubernetes scheduler 20 | type Patcher struct { 21 | Enable bool `json:"enable"` 22 | Image *Image `json:"image,omitempty"` 23 | Interval int `json:"interval,omitempty"` 24 | RestoreOnShutdown bool `json:"restoreOnShutdown,omitempty"` 25 | ConfigMapName string `json:"configMapName,omitempty"` 26 | ReadinessTimeout int `json:"readinessTimeout,omitempty"` 27 | // +nullable 28 | // +optional 29 | Resources *ResourceRequirements `json:"resources,omitempty"` 30 | } 31 | -------------------------------------------------------------------------------- /api/v1/components/pod_security_policy.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2021 Dell Inc. or its subsidiaries. All Rights Reserved. 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 components 18 | 19 | // PodSecurityPolicy encapsulates information about pod security policy 20 | type PodSecurityPolicy struct { 21 | Enable bool `json:"enable"` 22 | ResourceName string `json:"resourceName"` 23 | } 24 | -------------------------------------------------------------------------------- /api/v1/components/resources.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2021 Dell Inc. or its subsidiaries. All Rights Reserved. 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 | package components 17 | 18 | import ( 19 | corev1 "k8s.io/api/core/v1" 20 | ) 21 | 22 | // ResourceRequirements contain information for mem/cpu requirements 23 | type ResourceRequirements struct { 24 | // +nullable 25 | // +optional 26 | Limits corev1.ResourceList `json:"limits,omitempty"` 27 | // +nullable 28 | // +optional 29 | Requests corev1.ResourceList `json:"requests,omitempty"` 30 | // +optional 31 | Claims []corev1.ResourceClaim `json:"claims,omitempty" protobuf:"bytes,3,opt,name=claims"` 32 | } 33 | -------------------------------------------------------------------------------- /api/v1/components/scheduler.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2021 Dell Inc. or its subsidiaries. All Rights Reserved. 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 components 18 | 19 | // Scheduler encapsulates information to deploy CSI scheduler 20 | type Scheduler struct { 21 | Enable bool `json:"enable"` 22 | ServiceAccount string `json:"serviceAccount"` 23 | Image *Image `json:"image,omitempty"` 24 | Log *Log `json:"log,omitempty"` 25 | Metrics *Metrics `json:"metrics,omitempty"` 26 | Patcher *Patcher `json:"patcher,omitempty"` 27 | ExtenderPort string `json:"extenderPort,omitempty"` 28 | StorageProvisioner string `json:"storageProvisioner"` 29 | 30 | OpenshiftSecondaryScheduler *OpenshiftSecondaryScheduler `json:"openshiftSecondaryScheduler,omitempty"` 31 | // +nullable 32 | // +optional 33 | Resources *ResourceRequirements `json:"resources,omitempty"` 34 | SecurityContext *SecurityContext `json:"securityContext,omitempty"` 35 | PodSecurityPolicy *PodSecurityPolicy `json:"podSecurityPolicy,omitempty"` 36 | } 37 | -------------------------------------------------------------------------------- /api/v1/components/security_context.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2021 Dell Inc. or its subsidiaries. All Rights Reserved. 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 components 18 | 19 | // SecurityContext represents security context 20 | type SecurityContext struct { 21 | Enable bool `json:"enable"` 22 | Privileged *bool `json:"privileged,omitempty"` 23 | // +kubebuilder:default:=true 24 | RunAsNonRoot *bool `json:"runAsNonRoot,omitempty"` 25 | // +kubebuilder:default:=1000 26 | RunAsUser *int64 `json:"runAsUser,omitempty"` 27 | } 28 | -------------------------------------------------------------------------------- /api/v1/components/sidecar.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2021 Dell Inc. or its subsidiaries. All Rights Reserved. 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 components 18 | 19 | // Sidecar represent CSI sidecar containers 20 | type Sidecar struct { 21 | Image *Image `json:"image,omitempty"` 22 | // Arguments to the entrypoint. 23 | // +kubebuilder:validation:Type=object 24 | // +kubebuilder:validation:Required 25 | Args *Args `json:"args,omitempty"` 26 | // +nullable 27 | // +optional 28 | Resources *ResourceRequirements `json:"resources,omitempty"` 29 | } 30 | 31 | type Args struct { 32 | Timeout string `json:"timeout,omitempty"` 33 | RetryIntervalStart string `json:"retryIntervalStart,omitempty"` 34 | RetryIntervalMax string `json:"retryIntervalMax,omitempty"` 35 | WorkerThreads int `json:"workerThreads,omitempty"` 36 | } 37 | -------------------------------------------------------------------------------- /api/v1/deployment_types.go: -------------------------------------------------------------------------------- 1 | /* 2 | 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 v1 18 | 19 | import ( 20 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 21 | 22 | "github.com/dell/csi-baremetal-operator/api/v1/components" 23 | ) 24 | 25 | // DeploymentStatus defines the observed state of Deployment 26 | type DeploymentStatus struct { 27 | // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster 28 | // Important: Run "make" to regenerate code after modifying this file 29 | } 30 | 31 | // +kubebuilder:object:root=true 32 | // +kubebuilder:resource:shortName={bmcsi,bmcsis} 33 | // Deployment is the Schema for the deployments API 34 | type Deployment struct { 35 | metav1.TypeMeta `json:",inline"` 36 | metav1.ObjectMeta `json:"metadata,omitempty"` 37 | 38 | Spec components.DeploymentSpec `json:"spec,omitempty"` 39 | Status DeploymentStatus `json:"status,omitempty"` 40 | } 41 | 42 | // +kubebuilder:object:root=true 43 | 44 | // DeploymentList contains a list of Deployment 45 | type DeploymentList struct { 46 | metav1.TypeMeta `json:",inline"` 47 | metav1.ListMeta `json:"metadata,omitempty"` 48 | Items []Deployment `json:"items"` 49 | } 50 | 51 | func (in *Deployment) DeepCopyInto(out *Deployment) { 52 | *out = *in 53 | out.TypeMeta = in.TypeMeta 54 | in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) 55 | out.Spec = in.Spec 56 | } 57 | 58 | func init() { 59 | SchemeBuilder.Register(&Deployment{}, &DeploymentList{}) 60 | } 61 | -------------------------------------------------------------------------------- /api/v1/groupversion_info.go: -------------------------------------------------------------------------------- 1 | /* 2 | 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 v1 contains API Schema definitions for the csi-baremetal v1 API group 18 | // +kubebuilder:object:generate=true 19 | // +groupName=csi-baremetal.dell.com 20 | package v1 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: "csi-baremetal.dell.com", Version: "v1"} 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 | -------------------------------------------------------------------------------- /api/v1/zz_generated.deepcopy.go: -------------------------------------------------------------------------------- 1 | // +build !ignore_autogenerated 2 | 3 | // Code generated by controller-gen. DO NOT EDIT. 4 | 5 | package v1 6 | 7 | import ( 8 | runtime "k8s.io/apimachinery/pkg/runtime" 9 | ) 10 | 11 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Deployment. 12 | func (in *Deployment) DeepCopy() *Deployment { 13 | if in == nil { 14 | return nil 15 | } 16 | out := new(Deployment) 17 | in.DeepCopyInto(out) 18 | return out 19 | } 20 | 21 | // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. 22 | func (in *Deployment) DeepCopyObject() runtime.Object { 23 | if c := in.DeepCopy(); c != nil { 24 | return c 25 | } 26 | return nil 27 | } 28 | 29 | // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. 30 | func (in *DeploymentList) DeepCopyInto(out *DeploymentList) { 31 | *out = *in 32 | out.TypeMeta = in.TypeMeta 33 | in.ListMeta.DeepCopyInto(&out.ListMeta) 34 | if in.Items != nil { 35 | in, out := &in.Items, &out.Items 36 | *out = make([]Deployment, len(*in)) 37 | for i := range *in { 38 | (*in)[i].DeepCopyInto(&(*out)[i]) 39 | } 40 | } 41 | } 42 | 43 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeploymentList. 44 | func (in *DeploymentList) DeepCopy() *DeploymentList { 45 | if in == nil { 46 | return nil 47 | } 48 | out := new(DeploymentList) 49 | in.DeepCopyInto(out) 50 | return out 51 | } 52 | 53 | // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. 54 | func (in *DeploymentList) DeepCopyObject() runtime.Object { 55 | if c := in.DeepCopy(); c != nil { 56 | return c 57 | } 58 | return nil 59 | } 60 | 61 | // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. 62 | func (in *DeploymentStatus) DeepCopyInto(out *DeploymentStatus) { 63 | *out = *in 64 | } 65 | 66 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeploymentStatus. 67 | func (in *DeploymentStatus) DeepCopy() *DeploymentStatus { 68 | if in == nil { 69 | return nil 70 | } 71 | out := new(DeploymentStatus) 72 | in.DeepCopyInto(out) 73 | return out 74 | } 75 | -------------------------------------------------------------------------------- /charts/README.md: -------------------------------------------------------------------------------- 1 | Deploy CSI Baremetal to kind-cluster using operator 2 | --------------------- 3 | 4 | Last update: 26.03.2021 5 | 6 | ! Kind-cluster has pre-loaded csi images 7 | 8 | 1. Set CSI version 9 | 10 | ``` 11 | export csiVersion=... 12 | ``` 13 | 14 | 2. Build operator image and load to kind 15 | 16 | ``` 17 | make docker-build 18 | make kind-load 19 | ``` 20 | 21 | 3. Deploy operator 22 | 23 | ``` 24 | helm install csi-baremetal-operator ./charts/csi-baremetal-operator/ 25 | ``` 26 | 27 | 4. Deploy csi-baremetal 28 | 29 | ``` 30 | helm install csi-baremetal ./charts/csi-baremetal-deployment/ --set image.tag=${csiVersion} --set image.pullPolicy=IfNotPresent --set driver.drivemgr.type=loopbackmgr --set driver.drivemgr.deployConfig=true --set scheduler.patcher.enable=true 31 | ``` 32 | -------------------------------------------------------------------------------- /charts/csi-baremetal-deployment/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | appVersion: 1.5.0 3 | description: Bare-metal CSI Deployment 4 | name: csi-baremetal-deployment 5 | version: 1.1.0 6 | -------------------------------------------------------------------------------- /charts/csi-baremetal-deployment/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | This CSI plugin is a part of platform Atlantic. 2 | It is used to provide dynamic volume provisioning on bare-metal k8s cluster. 3 | To create Persistent Volume for a pod it's needed to set Storage Class {{ .Values.storageClass.name }} 4 | in corresponding Persistent Volume Claim. 5 | 6 | Your release is named {{ .Release.Name }}. 7 | -------------------------------------------------------------------------------- /charts/csi-baremetal-deployment/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{- define "setResources" }} 2 | {{- if .resources }} 3 | {{- if or .resources.requests .resources.limits }} 4 | 5 | {{- $requestsValues := .resources.requests | values | compact }} 6 | {{- $limitsValues := .resources.limits | values | compact }} 7 | 8 | {{- if $limitsValues }} 9 | limits: 10 | {{- if .resources.limits.memory }} 11 | memory: {{ .resources.limits.memory }} 12 | {{- end }} 13 | {{- if .resources.limits.cpu }} 14 | cpu: {{ .resources.limits.cpu }} 15 | {{- end }} 16 | {{- end }} 17 | 18 | {{- if $requestsValues }} 19 | requests: 20 | {{- if .resources.requests.memory }} 21 | memory: {{ .resources.requests.memory }} 22 | {{- end }} 23 | {{- if .resources.requests.cpu }} 24 | cpu: {{ .resources.requests.cpu }} 25 | {{- end }} 26 | {{- end }} 27 | 28 | {{- end }} 29 | {{- end }} 30 | {{- end }} 31 | -------------------------------------------------------------------------------- /charts/csi-baremetal-deployment/templates/configmap/fluent-bit-config-map.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.driver.logReceiver.create }} 2 | --- 3 | apiVersion: v1 4 | kind: ConfigMap 5 | metadata: 6 | namespace: {{ .Release.Namespace }} 7 | name: {{ .Release.Name }}-logs-config 8 | # labels: 9 | # helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} 10 | data: 11 | fluent-bit.conf: | 12 | [SERVICE] 13 | Flush 5 14 | Log_Level info 15 | Daemon off 16 | Parsers_File fluent-parsers.conf 17 | HTTP_Server On 18 | HTTP_Listen 0.0.0.0 19 | HTTP_Port 2020 20 | [INPUT] 21 | Name tail 22 | Path /var/log/csi.log 23 | DB /var/log/flb.db 24 | Path_Key filename 25 | Parser csi-logs 26 | Mem_Buf_Limit 5MB 27 | Skip_Long_Lines Off 28 | Refresh_Interval 5 29 | Tag csi-baremetal 30 | [INPUT] 31 | Name tail 32 | Path /var/log/drivemgr.log 33 | DB /var/log/flb.db 34 | Path_Key filename 35 | Parser csi-logs 36 | Mem_Buf_Limit 5MB 37 | Skip_Long_Lines Off 38 | Refresh_Interval 5 39 | Tag kubernetes_cluster-csi-baremetal 40 | [FILTER] 41 | Name record_modifier 42 | Match * 43 | Record pod_name ${POD_NAME} 44 | Record node_name ${NODE_NAME} 45 | Record namespace ${NAMESPACE} 46 | [OUTPUT] 47 | {{- if eq .Values.driver.logReceiver.output "es"}} 48 | Name es 49 | Match * 50 | {{- if eq .Values.driver.logReceiver.protocol "http"}} 51 | tls Of 52 | {{- else}} 53 | tls On 54 | HTTP_User {{ .Values.driver.logReceiver.user }} 55 | HTTP_Passwd {{ .Values.driver.logReceiver.password }} 56 | tls.verify Off 57 | {{- end}} 58 | Type logEvent 59 | Host {{ .Values.driver.logReceiver.host }} 60 | Port {{ .Values.driver.logReceiver.port }} 61 | Logstash_Format on 62 | Retry_Limit False 63 | Logstash_Prefix kubernetes_cluster-csi-baremetal 64 | {{- end}} 65 | {{- if eq .Values.driver.logReceiver.output "stdout"}} 66 | Name stdout 67 | Match * 68 | Format msgpack 69 | {{- end}} 70 | fluent-parsers.conf: | 71 | [PARSER] 72 | Name csi-logs 73 | Format json 74 | Time_Key time 75 | Time_Format %Y-%m-%dT%H:%M:%S %z 76 | {{- end}} 77 | -------------------------------------------------------------------------------- /charts/csi-baremetal-deployment/templates/configmap/loopbackmgr-config.yaml: -------------------------------------------------------------------------------- 1 | {{- if eq .Values.driver.drivemgr.deployConfig true }} 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | namespace: {{ .Release.Namespace }} 6 | name: loopback-config 7 | labels: 8 | app: csi-baremetal-node 9 | data: 10 | config.yaml: |- 11 | defaultDrivePerNodeCount: {{ .Values.driver.drivemgr.amountOfLoopDevices }} 12 | defaultDriveSize: {{ .Values.driver.drivemgr.sizeOfLoopDevices }} 13 | {{- end }} 14 | -------------------------------------------------------------------------------- /charts/csi-baremetal-deployment/templates/configmap/node-config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | namespace: {{ .Release.Namespace }} 5 | name: node-config 6 | labels: 7 | app: csi-baremetal-node 8 | data: 9 | wbt-config.yaml: |- 10 | enable: true 11 | wbt_lat_usec_value: 0 12 | acceptable_volume_options: 13 | # Values - FS, RAW, RAWPART 14 | # Block volumes don't take any impact from WBT 15 | modes: 16 | - FS 17 | # Name from "kubectl get sc" 18 | # It is risky to change WBT settings for LVG Volumes 19 | storage_classes: 20 | - csi-baremetal-sc-hdd 21 | - csi-baremetal-sc-ssd 22 | - csi-baremetal-sc-nvme 23 | 24 | wbt-acceptable_kernels.yaml: |- 25 | enable_for_all: false 26 | # The list of acceptable kernel versions 27 | # Used only if enable_for_all is false 28 | node_kernel_versions: 29 | # RHEL 8 30 | - 4.18.0-193.65.2.el8_2.x86_64 31 | - 4.18.0-305.45.1.el8_4.x86_64 32 | - 4.18.0-372.43.1.el8_6.x86_64 33 | -------------------------------------------------------------------------------- /charts/csi-baremetal-deployment/templates/csidriver/csidriver.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: storage.k8s.io/v1 2 | kind: CSIDriver 3 | metadata: 4 | name: csi-baremetal 5 | spec: 6 | attachRequired: false 7 | # pass pod info to NodePublishRequest 8 | podInfoOnMount: true 9 | volumeLifecycleModes: 10 | - Persistent 11 | - Ephemeral 12 | -------------------------------------------------------------------------------- /charts/csi-baremetal-deployment/templates/rbac/csibm-rbac.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: csi-node-controller-sa 5 | namespace: {{ .Release.Namespace }} 6 | --- 7 | kind: ClusterRole 8 | apiVersion: rbac.authorization.k8s.io/v1 9 | metadata: 10 | name: csi-node-controller-cr 11 | rules: 12 | - apiGroups: [""] 13 | resources: ["nodes"] 14 | verbs: ["get", "list", "watch", "update"] 15 | - apiGroups: ["csi-baremetal.dell.com"] 16 | resources: ["nodes"] 17 | verbs: ["watch", "get", "list", "create", "delete", "update"] 18 | --- 19 | kind: ClusterRoleBinding 20 | apiVersion: rbac.authorization.k8s.io/v1 21 | metadata: 22 | name: csi-node-controller-rb 23 | subjects: 24 | - kind: ServiceAccount 25 | name: csi-node-controller-sa 26 | namespace: {{ .Release.Namespace }} 27 | roleRef: 28 | kind: ClusterRole 29 | name: csi-node-controller-cr 30 | apiGroup: rbac.authorization.k8s.io 31 | -------------------------------------------------------------------------------- /charts/csi-baremetal-deployment/templates/rbac/node-rbac.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: csi-node-sa 6 | namespace: {{ .Release.Namespace }} 7 | 8 | 9 | --- 10 | kind: ClusterRole 11 | apiVersion: rbac.authorization.k8s.io/v1 12 | metadata: 13 | name: driver-registrar-runner 14 | rules: 15 | - apiGroups: [""] 16 | resources: ["persistentvolumes"] 17 | verbs: ["get", "list", "watch", "update"] 18 | - apiGroups: [""] 19 | resources: ["persistentvolumeclaims"] 20 | verbs: ["get", "list"] 21 | - apiGroups: [""] 22 | resources: ["nodes"] 23 | verbs: ["get", "list", "watch"] 24 | - apiGroups: ["csi.storage.k8s.io"] 25 | resources: ["csinodeinfos"] 26 | verbs: ["get", "list", "watch"] 27 | - apiGroups: ["storage.k8s.io"] 28 | resources: ["volumeattachments"] 29 | verbs: ["get", "list", "watch", "update"] 30 | - apiGroups: [""] 31 | resources: ["events"] 32 | verbs: ["get", "list", "watch", "create", "update", "patch"] 33 | - apiGroups: [""] 34 | resources: ["pods"] 35 | verbs: ["get"] 36 | 37 | --- 38 | kind: ClusterRoleBinding 39 | apiVersion: rbac.authorization.k8s.io/v1 40 | metadata: 41 | name: csi-driver-registrar-role 42 | subjects: 43 | - kind: ServiceAccount 44 | name: csi-node-sa 45 | namespace: {{ .Release.Namespace }} 46 | roleRef: 47 | kind: ClusterRole 48 | name: driver-registrar-runner 49 | apiGroup: rbac.authorization.k8s.io 50 | 51 | --- 52 | apiVersion: rbac.authorization.k8s.io/v1 53 | kind: ClusterRole 54 | metadata: 55 | name: node 56 | rules: 57 | - apiGroups: ["csi-baremetal.dell.com"] 58 | resources: ["*"] 59 | verbs: ["*"] 60 | 61 | --- 62 | apiVersion: rbac.authorization.k8s.io/v1 63 | kind: ClusterRoleBinding 64 | metadata: 65 | name: node-role 66 | subjects: 67 | - kind: ServiceAccount 68 | name: csi-node-sa 69 | namespace: {{ .Release.Namespace }} 70 | roleRef: 71 | apiGroup: rbac.authorization.k8s.io 72 | kind: ClusterRole 73 | name: node 74 | 75 | 76 | --- 77 | kind: ClusterRoleBinding 78 | apiVersion: rbac.authorization.k8s.io/v1 79 | metadata: 80 | name: controller-crd-node-role 81 | subjects: 82 | - kind: ServiceAccount 83 | name: csi-node-sa 84 | namespace: {{ .Release.Namespace }} 85 | roleRef: 86 | kind: ClusterRole 87 | name: controller 88 | apiGroup: rbac.authorization.k8s.io 89 | -------------------------------------------------------------------------------- /charts/csi-baremetal-deployment/templates/rbac/scheduler-rbac.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | namespace: {{ .Release.Namespace }} 6 | name: csi-baremetal-extender-sa 7 | --- 8 | apiVersion: rbac.authorization.k8s.io/v1 9 | kind: ClusterRole 10 | metadata: 11 | name: csi-baremetal-extender-cr 12 | rules: 13 | - apiGroups: ["csi-baremetal.dell.com"] 14 | resources: ["volumes"] 15 | verbs: ["get", "list", "watch"] 16 | - apiGroups: ["csi-baremetal.dell.com"] 17 | resources: ["availablecapacities"] 18 | verbs: ["get", "list"] 19 | - apiGroups: ["csi-baremetal.dell.com"] 20 | resources: ["availablecapacityreservations"] 21 | verbs: ["get", "list", "create", "update"] 22 | - apiGroups: [""] 23 | resources: ["persistentvolumeclaims"] 24 | verbs: ["get", "list", "watch"] 25 | - apiGroups: [""] 26 | resources: ["events"] 27 | verbs: ["get", "list", "watch"] 28 | - apiGroups: ["storage.k8s.io"] 29 | resources: ["storageclasses"] 30 | verbs: ["get", "list", "watch"] 31 | --- 32 | kind: ClusterRoleBinding 33 | apiVersion: rbac.authorization.k8s.io/v1 34 | metadata: 35 | name: csi-baremetal-extender-rb 36 | roleRef: 37 | apiGroup: rbac.authorization.k8s.io 38 | kind: ClusterRole 39 | name: csi-baremetal-extender-cr 40 | subjects: 41 | - kind: ServiceAccount 42 | namespace: {{ .Release.Namespace }} 43 | name: csi-baremetal-extender-sa 44 | -------------------------------------------------------------------------------- /charts/csi-baremetal-deployment/templates/service/csi-smart-info-backend-svc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: csi-smart-info-backend 5 | namespace: {{ .Release.Namespace }} 6 | spec: 7 | clusterIP: None 8 | ports: 9 | - name: http 10 | port: {{ .Values.driver.metrics.port }} 11 | targetPort: {{ .Values.driver.metrics.port }} 12 | protocol: TCP 13 | selector: 14 | app: csi-baremetal 15 | component: node 16 | -------------------------------------------------------------------------------- /charts/csi-baremetal-deployment/templates/storageclass/default-sc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: storage.k8s.io/v1 2 | kind: StorageClass 3 | metadata: 4 | name: {{ .Values.storageClass.name }} 5 | annotations: 6 | storageclass.kubernetes.io/is-default-class: "true" 7 | # CSI driver name 8 | provisioner: csi-baremetal 9 | reclaimPolicy: Delete 10 | volumeBindingMode: WaitForFirstConsumer 11 | parameters: 12 | # With ANY storage type CSI allocates volumes on top of ANY physical drive (non LVG) 13 | storageType: ANY 14 | fsType: xfs 15 | -------------------------------------------------------------------------------- /charts/csi-baremetal-deployment/templates/storageclass/hdd-sc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: storage.k8s.io/v1 2 | kind: StorageClass 3 | metadata: 4 | name: {{ .Values.storageClass.name }}-hdd 5 | # CSI driver name 6 | provisioner: csi-baremetal 7 | reclaimPolicy: Delete 8 | volumeBindingMode: WaitForFirstConsumer 9 | parameters: 10 | storageType: HDD 11 | fsType: xfs 12 | -------------------------------------------------------------------------------- /charts/csi-baremetal-deployment/templates/storageclass/hddlvg-sc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: storage.k8s.io/v1 2 | kind: StorageClass 3 | metadata: 4 | name: {{ .Values.storageClass.name }}-hddlvg 5 | # CSI driver name 6 | provisioner: csi-baremetal 7 | reclaimPolicy: Delete 8 | volumeBindingMode: WaitForFirstConsumer 9 | allowVolumeExpansion: true 10 | parameters: 11 | storageType: HDDLVG 12 | fsType: xfs 13 | -------------------------------------------------------------------------------- /charts/csi-baremetal-deployment/templates/storageclass/nvme-raw-part-sc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: storage.k8s.io/v1 2 | kind: StorageClass 3 | metadata: 4 | name: {{ .Values.storageClass.name }}-nvme-raw-part 5 | # CSI driver name 6 | provisioner: csi-baremetal 7 | reclaimPolicy: Delete 8 | volumeBindingMode: WaitForFirstConsumer 9 | parameters: 10 | storageType: NVME 11 | fsType: xfs 12 | isPartitioned: "true" 13 | -------------------------------------------------------------------------------- /charts/csi-baremetal-deployment/templates/storageclass/nvme-sc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: storage.k8s.io/v1 2 | kind: StorageClass 3 | metadata: 4 | name: {{ .Values.storageClass.name }}-nvme 5 | # CSI driver name 6 | provisioner: csi-baremetal 7 | reclaimPolicy: Delete 8 | volumeBindingMode: WaitForFirstConsumer 9 | parameters: 10 | storageType: NVME 11 | fsType: xfs 12 | -------------------------------------------------------------------------------- /charts/csi-baremetal-deployment/templates/storageclass/nvmelvg-sc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: storage.k8s.io/v1 2 | kind: StorageClass 3 | metadata: 4 | name: {{ .Values.storageClass.name }}-nvmelvg 5 | # CSI driver name 6 | provisioner: csi-baremetal 7 | reclaimPolicy: Delete 8 | volumeBindingMode: WaitForFirstConsumer 9 | allowVolumeExpansion: true 10 | parameters: 11 | storageType: NVMELVG 12 | fsType: xfs 13 | -------------------------------------------------------------------------------- /charts/csi-baremetal-deployment/templates/storageclass/ssd-sc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: storage.k8s.io/v1 2 | kind: StorageClass 3 | metadata: 4 | name: {{ .Values.storageClass.name }}-ssd 5 | # CSI driver name 6 | provisioner: csi-baremetal 7 | reclaimPolicy: Delete 8 | volumeBindingMode: WaitForFirstConsumer 9 | parameters: 10 | storageType: SSD 11 | fsType: xfs 12 | -------------------------------------------------------------------------------- /charts/csi-baremetal-deployment/templates/storageclass/ssdlvg-sc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: storage.k8s.io/v1 2 | kind: StorageClass 3 | metadata: 4 | name: {{ .Values.storageClass.name }}-ssdlvg 5 | # CSI driver name 6 | provisioner: csi-baremetal 7 | reclaimPolicy: Delete 8 | volumeBindingMode: WaitForFirstConsumer 9 | allowVolumeExpansion: true 10 | parameters: 11 | storageType: SSDLVG 12 | fsType: xfs 13 | -------------------------------------------------------------------------------- /charts/csi-baremetal-deployment/templates/storageclass/syslvg-sc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: storage.k8s.io/v1 2 | kind: StorageClass 3 | metadata: 4 | name: {{ .Values.storageClass.name }}-syslvg 5 | # CSI driver name 6 | provisioner: csi-baremetal 7 | reclaimPolicy: Delete 8 | volumeBindingMode: WaitForFirstConsumer 9 | allowVolumeExpansion: true 10 | parameters: 11 | storageType: SYSLVG 12 | fsType: xfs 13 | -------------------------------------------------------------------------------- /charts/csi-baremetal-operator/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | appVersion: 1.5.0 3 | description: Bare-metal CSI Operator 4 | name: csi-baremetal-operator 5 | version: 1.1.0 6 | -------------------------------------------------------------------------------- /charts/csi-baremetal-operator/crds/csi-baremetal.dell.com_availablecapacities.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | controller-gen.kubebuilder.io/version: v0.9.2 7 | creationTimestamp: null 8 | name: availablecapacities.csi-baremetal.dell.com 9 | spec: 10 | group: csi-baremetal.dell.com 11 | names: 12 | kind: AvailableCapacity 13 | listKind: AvailableCapacityList 14 | plural: availablecapacities 15 | shortNames: 16 | - ac 17 | - acs 18 | singular: availablecapacity 19 | scope: Cluster 20 | versions: 21 | - additionalPrinterColumns: 22 | - description: Size of AvailableCapacity 23 | jsonPath: .spec.Size 24 | name: SIZE 25 | type: string 26 | - description: StorageClass of AvailableCapacity 27 | jsonPath: .spec.storageClass 28 | name: STORAGE CLASS 29 | type: string 30 | - description: Drive/LVG UUID used by AvailableCapacity 31 | jsonPath: .spec.Location 32 | name: LOCATION 33 | type: string 34 | - description: Node id of Available Capacity 35 | jsonPath: .spec.NodeId 36 | name: NODE 37 | type: string 38 | name: v1 39 | schema: 40 | openAPIV3Schema: 41 | description: AvailableCapacity is the Schema for the availablecapacities API 42 | properties: 43 | apiVersion: 44 | description: 'APIVersion defines the versioned schema of this representation 45 | of an object. Servers should convert recognized schemas to the latest 46 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 47 | type: string 48 | kind: 49 | description: 'Kind is a string value representing the REST resource this 50 | object represents. Servers may infer this from the endpoint the client 51 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 52 | type: string 53 | metadata: 54 | type: object 55 | spec: 56 | properties: 57 | Location: 58 | type: string 59 | NodeId: 60 | type: string 61 | Size: 62 | format: int64 63 | type: integer 64 | storageClass: 65 | type: string 66 | type: object 67 | type: object 68 | served: true 69 | storage: true 70 | subresources: {} 71 | -------------------------------------------------------------------------------- /charts/csi-baremetal-operator/crds/csi-baremetal.dell.com_availablecapacityreservations.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | controller-gen.kubebuilder.io/version: v0.9.2 7 | creationTimestamp: null 8 | name: availablecapacityreservations.csi-baremetal.dell.com 9 | spec: 10 | group: csi-baremetal.dell.com 11 | names: 12 | kind: AvailableCapacityReservation 13 | listKind: AvailableCapacityReservationList 14 | plural: availablecapacityreservations 15 | shortNames: 16 | - acr 17 | - acrs 18 | singular: availablecapacityreservation 19 | scope: Cluster 20 | versions: 21 | - additionalPrinterColumns: 22 | - description: Pod namespace 23 | jsonPath: .spec.Namespace 24 | name: NAMESPACE 25 | type: string 26 | - description: Status of AvailableCapacityReservation 27 | jsonPath: .spec.Status 28 | name: STATUS 29 | type: string 30 | - description: List of requested nodes 31 | jsonPath: .spec.NodeRequests.Requested 32 | name: REQUESTED NODES 33 | priority: 1 34 | type: string 35 | - description: List of reserved nodes 36 | jsonPath: .spec.NodeRequests.Reserved 37 | name: RESERVED NODES 38 | priority: 1 39 | type: string 40 | name: v1 41 | schema: 42 | openAPIV3Schema: 43 | description: AvailableCapacityReservation is the Schema for the availablecapacitiereservations 44 | API 45 | properties: 46 | apiVersion: 47 | description: 'APIVersion defines the versioned schema of this representation 48 | of an object. Servers should convert recognized schemas to the latest 49 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 50 | type: string 51 | kind: 52 | description: 'Kind is a string value representing the REST resource this 53 | object represents. Servers may infer this from the endpoint the client 54 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 55 | type: string 56 | metadata: 57 | type: object 58 | spec: 59 | properties: 60 | Namespace: 61 | type: string 62 | NodeRequests: 63 | properties: 64 | Requested: 65 | description: requested - filled by scheduler/extender 66 | items: 67 | type: string 68 | type: array 69 | Reserved: 70 | description: reserved - filled by csi driver controller 71 | items: 72 | type: string 73 | type: array 74 | type: object 75 | ReservationRequests: 76 | items: 77 | properties: 78 | CapacityRequest: 79 | description: request per volume filled by scheduler/extender 80 | properties: 81 | Name: 82 | type: string 83 | Size: 84 | format: int64 85 | type: integer 86 | StorageClass: 87 | type: string 88 | StorageGroup: 89 | type: string 90 | type: object 91 | Reservations: 92 | description: reservation filled by csi driver controller 93 | items: 94 | type: string 95 | type: array 96 | type: object 97 | type: array 98 | Status: 99 | type: string 100 | type: object 101 | type: object 102 | served: true 103 | storage: true 104 | subresources: {} 105 | -------------------------------------------------------------------------------- /charts/csi-baremetal-operator/crds/csi-baremetal.dell.com_drives.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | controller-gen.kubebuilder.io/version: v0.9.2 7 | creationTimestamp: null 8 | name: drives.csi-baremetal.dell.com 9 | spec: 10 | group: csi-baremetal.dell.com 11 | names: 12 | kind: Drive 13 | listKind: DriveList 14 | plural: drives 15 | singular: drive 16 | scope: Cluster 17 | versions: 18 | - additionalPrinterColumns: 19 | - description: Drive capacity 20 | jsonPath: .spec.Size 21 | name: SIZE 22 | type: string 23 | - description: Drive type (HDD/LVG/NVME) 24 | jsonPath: .spec.Type 25 | name: TYPE 26 | type: string 27 | - description: Drive health status 28 | jsonPath: .spec.Health 29 | name: HEALTH 30 | type: string 31 | - description: Drive status online/offline 32 | jsonPath: .spec.Status 33 | name: STATUS 34 | priority: 1 35 | type: string 36 | - description: Drive usage 37 | jsonPath: .spec.Usage 38 | name: USAGE 39 | priority: 1 40 | type: string 41 | - description: Is system disk 42 | jsonPath: .spec.IsSystem 43 | name: SYSTEM 44 | priority: 1 45 | type: string 46 | - description: Drive path 47 | jsonPath: .spec.Path 48 | name: PATH 49 | priority: 1 50 | type: string 51 | - description: Drive serial number 52 | jsonPath: .spec.SerialNumber 53 | name: SERIAL NUMBER 54 | type: string 55 | - description: Drive node location 56 | jsonPath: .spec.NodeId 57 | name: NODE 58 | type: string 59 | - description: Drive slot 60 | jsonPath: .spec.Slot 61 | name: SLOT 62 | type: string 63 | - description: SED drive security status 64 | jsonPath: .spec.SecurityStatus 65 | name: Security Status 66 | type: string 67 | - description: SED drive or not 68 | jsonPath: .spec.EncryptionCapable 69 | name: Encryption Capable 70 | type: string 71 | - description: SED encryption protocol 72 | jsonPath: .spec.EncryptionProtocol 73 | name: Encryption Protocol 74 | type: string 75 | name: v1 76 | schema: 77 | openAPIV3Schema: 78 | description: Drive is the Schema for the drives API 79 | properties: 80 | apiVersion: 81 | description: 'APIVersion defines the versioned schema of this representation 82 | of an object. Servers should convert recognized schemas to the latest 83 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 84 | type: string 85 | kind: 86 | description: 'Kind is a string value representing the REST resource this 87 | object represents. Servers may infer this from the endpoint the client 88 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 89 | type: string 90 | metadata: 91 | type: object 92 | spec: 93 | properties: 94 | Bay: 95 | type: string 96 | Enclosure: 97 | type: string 98 | EncryptionCapable: 99 | type: string 100 | EncryptionProtocol: 101 | type: string 102 | Endurance: 103 | format: int64 104 | type: integer 105 | Firmware: 106 | type: string 107 | Health: 108 | type: string 109 | IsClean: 110 | type: boolean 111 | IsSystem: 112 | type: boolean 113 | LEDState: 114 | type: string 115 | NodeId: 116 | type: string 117 | PID: 118 | type: string 119 | Path: 120 | description: path to the device. may not be set by drivemgr. 121 | type: string 122 | SecurityStatus: 123 | type: string 124 | SerialNumber: 125 | type: string 126 | Size: 127 | description: size in bytes 128 | format: int64 129 | type: integer 130 | Slot: 131 | type: string 132 | Status: 133 | type: string 134 | Type: 135 | type: string 136 | UUID: 137 | type: string 138 | Usage: 139 | type: string 140 | VID: 141 | type: string 142 | type: object 143 | type: object 144 | served: true 145 | storage: true 146 | subresources: {} 147 | -------------------------------------------------------------------------------- /charts/csi-baremetal-operator/crds/csi-baremetal.dell.com_logicalvolumegroups.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | controller-gen.kubebuilder.io/version: v0.9.2 7 | creationTimestamp: null 8 | name: logicalvolumegroups.csi-baremetal.dell.com 9 | spec: 10 | group: csi-baremetal.dell.com 11 | names: 12 | kind: LogicalVolumeGroup 13 | listKind: LogicalVolumeGroupList 14 | plural: logicalvolumegroups 15 | shortNames: 16 | - lvg 17 | - lvgs 18 | singular: logicalvolumegroup 19 | scope: Cluster 20 | versions: 21 | - additionalPrinterColumns: 22 | - description: Size of Logical volume group 23 | jsonPath: .spec.Size 24 | name: SIZE 25 | type: string 26 | - description: LVG health 27 | jsonPath: .spec.Health 28 | name: HEALTH 29 | type: string 30 | - description: LVG status 31 | jsonPath: .spec.Status 32 | name: Status 33 | priority: 1 34 | type: string 35 | - description: LVG drives locations list 36 | jsonPath: .spec.Locations 37 | name: LOCATIONS 38 | type: string 39 | - description: LVG node location 40 | jsonPath: .spec.Node 41 | name: NODE 42 | type: string 43 | - description: Volume references 44 | jsonPath: .spec.VolumeRefs 45 | name: VOLUMES 46 | priority: 1 47 | type: string 48 | name: v1 49 | schema: 50 | openAPIV3Schema: 51 | description: LogicalVolumeGroup is the Schema for the LVGs API 52 | properties: 53 | apiVersion: 54 | description: 'APIVersion defines the versioned schema of this representation 55 | of an object. Servers should convert recognized schemas to the latest 56 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 57 | type: string 58 | kind: 59 | description: 'Kind is a string value representing the REST resource this 60 | object represents. Servers may infer this from the endpoint the client 61 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 62 | type: string 63 | metadata: 64 | type: object 65 | spec: 66 | properties: 67 | Health: 68 | type: string 69 | Locations: 70 | items: 71 | type: string 72 | type: array 73 | Name: 74 | type: string 75 | Node: 76 | type: string 77 | Size: 78 | format: int64 79 | type: integer 80 | Status: 81 | type: string 82 | VolumeRefs: 83 | items: 84 | type: string 85 | type: array 86 | type: object 87 | type: object 88 | served: true 89 | storage: true 90 | subresources: {} 91 | -------------------------------------------------------------------------------- /charts/csi-baremetal-operator/crds/csi-baremetal.dell.com_nodes.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | controller-gen.kubebuilder.io/version: v0.9.2 7 | creationTimestamp: null 8 | name: nodes.csi-baremetal.dell.com 9 | spec: 10 | group: csi-baremetal.dell.com 11 | names: 12 | kind: Node 13 | listKind: NodeList 14 | plural: nodes 15 | shortNames: 16 | - csibmnode 17 | - csibmnodes 18 | singular: node 19 | scope: Cluster 20 | versions: 21 | - additionalPrinterColumns: 22 | - description: Node Id 23 | jsonPath: .spec.UUID 24 | name: UUID 25 | type: string 26 | - description: Node hostname 27 | jsonPath: .spec.Addresses.Hostname 28 | name: HOSTNAME 29 | type: string 30 | - description: Node ip 31 | jsonPath: .spec.Addresses.InternalIP 32 | name: NODE_IP 33 | type: string 34 | name: v1 35 | schema: 36 | openAPIV3Schema: 37 | description: Node is the Schema for the Node API 38 | properties: 39 | apiVersion: 40 | description: 'APIVersion defines the versioned schema of this representation 41 | of an object. Servers should convert recognized schemas to the latest 42 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 43 | type: string 44 | kind: 45 | description: 'Kind is a string value representing the REST resource this 46 | object represents. Servers may infer this from the endpoint the client 47 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 48 | type: string 49 | metadata: 50 | type: object 51 | spec: 52 | properties: 53 | Addresses: 54 | additionalProperties: 55 | type: string 56 | description: key - address type, value - address, align with NodeAddress 57 | struct from k8s.io/api/core/v1 58 | type: object 59 | UUID: 60 | type: string 61 | type: object 62 | type: object 63 | served: true 64 | storage: true 65 | subresources: {} 66 | -------------------------------------------------------------------------------- /charts/csi-baremetal-operator/crds/csi-baremetal.dell.com_storagegroups.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | controller-gen.kubebuilder.io/version: v0.9.2 7 | creationTimestamp: null 8 | name: storagegroups.csi-baremetal.dell.com 9 | spec: 10 | group: csi-baremetal.dell.com 11 | names: 12 | kind: StorageGroup 13 | listKind: StorageGroupList 14 | plural: storagegroups 15 | shortNames: 16 | - sg 17 | - sgs 18 | singular: storagegroup 19 | scope: Cluster 20 | versions: 21 | - additionalPrinterColumns: 22 | - description: numberDrivesPerNode of StorageGroup's DriveSelector 23 | jsonPath: .spec.driveSelector.numberDrivesPerNode 24 | name: DRIVES_PER_NODE 25 | type: string 26 | - description: Match Fields of StorageGroup's DriveSelector to Select Drives on 27 | Field Values 28 | jsonPath: .spec.driveSelector.matchFields 29 | name: DRIVE_FIELDS 30 | type: string 31 | - description: status of StorageGroup 32 | jsonPath: .status.phase 33 | name: STATUS 34 | type: string 35 | name: v1 36 | schema: 37 | openAPIV3Schema: 38 | description: StorageGroup is the Schema for the StorageGroups API 39 | properties: 40 | apiVersion: 41 | description: 'APIVersion defines the versioned schema of this representation 42 | of an object. Servers should convert recognized schemas to the latest 43 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 44 | type: string 45 | kind: 46 | description: 'Kind is a string value representing the REST resource this 47 | object represents. Servers may infer this from the endpoint the client 48 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 49 | type: string 50 | metadata: 51 | type: object 52 | spec: 53 | properties: 54 | driveSelector: 55 | properties: 56 | matchFields: 57 | additionalProperties: 58 | type: string 59 | type: object 60 | numberDrivesPerNode: 61 | format: int32 62 | type: integer 63 | type: object 64 | type: object 65 | x-kubernetes-validations: 66 | - message: updates to storagegroup spec are forbidden 67 | rule: self == oldSelf 68 | status: 69 | properties: 70 | phase: 71 | type: string 72 | type: object 73 | type: object 74 | served: true 75 | storage: true 76 | subresources: {} 77 | -------------------------------------------------------------------------------- /charts/csi-baremetal-operator/crds/csi-baremetal.dell.com_volumes.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | controller-gen.kubebuilder.io/version: v0.9.2 7 | creationTimestamp: null 8 | name: volumes.csi-baremetal.dell.com 9 | spec: 10 | group: csi-baremetal.dell.com 11 | names: 12 | kind: Volume 13 | listKind: VolumeList 14 | plural: volumes 15 | singular: volume 16 | scope: Namespaced 17 | versions: 18 | - additionalPrinterColumns: 19 | - description: Volume allocated size 20 | jsonPath: .spec.Size 21 | name: SIZE 22 | type: string 23 | - description: Volume storage class 24 | jsonPath: .spec.StorageClass 25 | name: STORAGE CLASS 26 | type: string 27 | - description: Volume health status 28 | jsonPath: .spec.Health 29 | name: HEALTH 30 | type: string 31 | - description: Volume internal CSI status 32 | jsonPath: .spec.CSIStatus 33 | name: CSI_STATUS 34 | type: string 35 | - description: Volume operational status 36 | jsonPath: .spec.OperationalStatus 37 | name: OP_STATUS 38 | priority: 1 39 | type: string 40 | - description: Volume usage status 41 | jsonPath: .spec.Usage 42 | name: USAGE 43 | priority: 1 44 | type: string 45 | - description: Volume fs type 46 | jsonPath: .spec.Type 47 | name: TYPE 48 | priority: 1 49 | type: string 50 | - description: Volume LVG or drive location 51 | jsonPath: .spec.Location 52 | name: LOCATION 53 | type: string 54 | - description: Volume node location 55 | jsonPath: .spec.NodeId 56 | name: NODE 57 | type: string 58 | name: v1 59 | schema: 60 | openAPIV3Schema: 61 | description: Volume is the Schema for the volumes API 62 | properties: 63 | apiVersion: 64 | description: 'APIVersion defines the versioned schema of this representation 65 | of an object. Servers should convert recognized schemas to the latest 66 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 67 | type: string 68 | kind: 69 | description: 'Kind is a string value representing the REST resource this 70 | object represents. Servers may infer this from the endpoint the client 71 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 72 | type: string 73 | metadata: 74 | type: object 75 | spec: 76 | properties: 77 | CSIStatus: 78 | type: string 79 | Ephemeral: 80 | description: inline volumes are not support anymore. need to remove 81 | field in the next version 82 | type: boolean 83 | Health: 84 | type: string 85 | Id: 86 | type: string 87 | Location: 88 | type: string 89 | LocationType: 90 | type: string 91 | Mode: 92 | type: string 93 | NodeId: 94 | type: string 95 | OperationalStatus: 96 | type: string 97 | Owners: 98 | items: 99 | type: string 100 | type: array 101 | Size: 102 | format: int64 103 | type: integer 104 | StorageClass: 105 | type: string 106 | StorageGroup: 107 | type: string 108 | Type: 109 | type: string 110 | Usage: 111 | type: string 112 | type: object 113 | type: object 114 | served: true 115 | storage: true 116 | subresources: {} 117 | -------------------------------------------------------------------------------- /charts/csi-baremetal-operator/templates/manager.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: csi-baremetal-operator 5 | namespace: {{ .Release.Namespace }} 6 | labels: 7 | app: csi-baremetal 8 | app.kubernetes.io/name: csi-baremetal 9 | spec: 10 | selector: 11 | matchLabels: 12 | name: {{ .Release.Name }} 13 | replicas: 1 14 | template: 15 | metadata: 16 | labels: 17 | name: {{ .Release.Name }} 18 | app: csi-baremetal 19 | app.kubernetes.io/name: csi-baremetal 20 | component: operator 21 | app.kubernetes.io/component: operator 22 | app.kubernetes.io/instance: {{ .Release.Name }} 23 | spec: 24 | serviceAccount: csi-baremetal-operator-sa 25 | {{- if .Values.global.registrySecret }} 26 | imagePullSecrets: 27 | - name: {{ .Values.global.registrySecret }} 28 | {{- end }} 29 | {{- if .Values.securityContext.enable }} 30 | securityContext: 31 | runAsNonRoot: {{ .Values.securityContext.runAsNonRoot }} 32 | runAsUser: {{ .Values.securityContext.runAsUser }} 33 | {{- end }} 34 | containers: 35 | - command: 36 | - /manager 37 | args: 38 | - --enable-leader-election 39 | - --loglevel={{ .Values.log.level }} 40 | image: {{ if .Values.global.registry }}{{ .Values.global.registry }}/{{ end }}{{ .Values.operator.image.name }}:{{ default .Values.image.tag .Values.operator.image.tag }} 41 | name: manager 42 | imagePullPolicy: {{ default .Values.image.pullPolicy .Values.operator.image.pullPolicy }} 43 | resources: 44 | limits: 45 | cpu: {{ .Values.operator.resources.limits.cpu }} 46 | memory: {{ .Values.operator.resources.limits.memory }} 47 | requests: 48 | cpu: {{ .Values.operator.resources.requests.cpu }} 49 | memory: {{ .Values.operator.resources.requests.memory }} 50 | volumeMounts: 51 | - mountPath: /crash-dump 52 | name: crash-dump 53 | terminationGracePeriodSeconds: 10 54 | volumes: 55 | - name: crash-dump 56 | emptyDir: {} 57 | 58 | -------------------------------------------------------------------------------- /charts/csi-baremetal-operator/templates/pre-upgrade-crds.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright © 2022 Dell Inc. or its subsidiaries. 3 | # All Rights Reserved. 4 | # 5 | # This software contains the intellectual property of Dell Inc. 6 | # or is licensed to Dell Inc. from third parties. Use of this 7 | # software and the intellectual property contained therein is expressly 8 | # limited to the terms and conditions of the License Agreement under which 9 | # it is provided by or on behalf of Dell Inc. or its subsidiaries. 10 | # 11 | # 12 | 13 | # 14 | # Create the service account for replacing CRDs during upgrade. 15 | # 16 | apiVersion: v1 17 | kind: ServiceAccount 18 | metadata: 19 | name: "{{.Release.Namespace}}-{{.Release.Name}}-csi-baremetal-pre-crds-sa" 20 | namespace: {{ .Release.Namespace }} 21 | labels: 22 | app.kubernetes.io/name: {{ .Chart.Name }} 23 | app.kubernetes.io/instance: {{.Release.Name}} 24 | app.kubernetes.io/managed-by: csi-baremetal-operator 25 | release: {{.Release.Name}} 26 | annotations: 27 | "helm.sh/hook": pre-upgrade 28 | "helm.sh/hook-weight": "-4" 29 | "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed 30 | 31 | # 32 | # Create the cluster role for replacing CRDs during upgrade. 33 | # 34 | --- 35 | kind: ClusterRole 36 | apiVersion: rbac.authorization.k8s.io/v1 37 | metadata: 38 | name: "{{.Release.Namespace}}-{{.Release.Name}}-csi-baremetal-pre-crds-cr" 39 | labels: 40 | app.kubernetes.io/name: {{ .Chart.Name }} 41 | app.kubernetes.io/instance: {{.Release.Name}} 42 | app.kubernetes.io/managed-by: csi-baremetal-operator 43 | release: {{.Release.Name}} 44 | annotations: 45 | "helm.sh/hook": pre-upgrade 46 | "helm.sh/hook-weight": "-3" 47 | "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed 48 | rules: 49 | - apiGroups: 50 | - apiextensions.k8s.io 51 | resources: 52 | - customresourcedefinitions 53 | verbs: 54 | - "*" 55 | 56 | # 57 | # Create the cluster role binding for replacing CRDs during upgrade. 58 | # 59 | --- 60 | kind: ClusterRoleBinding 61 | apiVersion: rbac.authorization.k8s.io/v1 62 | metadata: 63 | name: "{{.Release.Namespace}}-{{.Release.Name}}-csi-baremetal-pre-crds-crb" 64 | labels: 65 | app.kubernetes.io/name: {{ .Chart.Name }} 66 | app.kubernetes.io/instance: {{.Release.Name}} 67 | app.kubernetes.io/managed-by: csi-baremetal-operator 68 | release: {{.Release.Name}} 69 | annotations: 70 | "helm.sh/hook": pre-upgrade 71 | "helm.sh/hook-weight": "-2" 72 | "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed 73 | subjects: 74 | - kind: ServiceAccount 75 | name: "{{.Release.Namespace}}-{{.Release.Name}}-csi-baremetal-pre-crds-sa" 76 | namespace: {{ .Release.Namespace }} 77 | roleRef: 78 | kind: ClusterRole 79 | name: "{{.Release.Namespace}}-{{.Release.Name}}-csi-baremetal-pre-crds-cr" 80 | apiGroup: rbac.authorization.k8s.io 81 | 82 | # 83 | # Create the job for replacing CRDs during upgrade. 84 | # 85 | --- 86 | apiVersion: batch/v1 87 | kind: Job 88 | metadata: 89 | name: "{{.Release.Namespace}}-{{.Release.Name}}-csi-baremetal-pre-crds-job" 90 | namespace: {{.Release.Namespace}} 91 | annotations: 92 | "helm.sh/hook": pre-upgrade 93 | "helm.sh/hook-weight": "-1" 94 | # It's common practice staying Job in cluster to have an opportunity to check logs 95 | #"helm.sh/hook-delete-policy": hook-succeeded 96 | labels: 97 | app.kubernetes.io/name: {{ .Chart.Name }} 98 | app.kubernetes.io/instance: {{.Release.Name}} 99 | app.kubernetes.io/managed-by: csi-baremetal-operator 100 | release: {{.Release.Name}} 101 | spec: 102 | backoffLimit: 4 103 | activeDeadlineSeconds: 300 104 | template: 105 | metadata: 106 | {{- with .Values.preUpgradeCRDsHooks.podAnnotations }} 107 | annotations: 108 | {{- toYaml . | nindent 8 }} 109 | {{- end }} 110 | name: "{{.Release.Namespace}}-{{.Release.Name}}-csi-baremetal-pre-crds-job" 111 | spec: 112 | serviceAccountName: "{{.Release.Namespace}}-{{.Release.Name}}-csi-baremetal-pre-crds-sa" 113 | restartPolicy: Never 114 | {{- if .Values.securityContext.enable }} 115 | securityContext: 116 | runAsNonRoot: {{ .Values.securityContext.runAsNonRoot }} 117 | runAsUser: {{ .Values.securityContext.runAsUser }} 118 | {{- end }} 119 | {{- if .Values.global.registrySecret }} 120 | imagePullSecrets: 121 | - name: {{ .Values.global.registrySecret }} 122 | {{- end }} 123 | containers: 124 | - name: "{{.Release.Namespace}}-{{.Release.Name}}-csi-baremetal-pre-crds-job" 125 | image: {{ if .Values.global.registry }}{{ .Values.global.registry }}/{{ end }}{{ .Values.preUpgradeCRDsHooks.image.name }}:{{ default .Values.image.tag .Values.preUpgradeCRDsHooks.image.tag }} 126 | imagePullPolicy: {{ default .Values.image.pullPolicy .Values.preUpgradeCRDsHooks.image.pullPolicy }} 127 | resources: 128 | limits: 129 | cpu: {{ .Values.operator.resources.limits.cpu }} 130 | memory: {{ .Values.operator.resources.limits.memory }} 131 | requests: 132 | cpu: {{ .Values.operator.resources.requests.cpu }} 133 | memory: {{ .Values.operator.resources.requests.memory }} 134 | command: ["/bin/sh", "-c"] 135 | args: 136 | - kubectl apply -f /crds; 137 | -------------------------------------------------------------------------------- /charts/csi-baremetal-operator/templates/rbac.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: csi-baremetal-operator-sa 5 | namespace: {{ .Release.Namespace }} 6 | --- 7 | apiVersion: rbac.authorization.k8s.io/v1 8 | kind: ClusterRole 9 | metadata: 10 | creationTimestamp: null 11 | name: csi-baremetal-operator-cr 12 | rules: 13 | - apiGroups: 14 | - "" 15 | resources: 16 | - configmaps 17 | - configmaps/status 18 | - events 19 | - nodes 20 | - pods 21 | verbs: 22 | - "*" 23 | - apiGroups: 24 | - coordination.k8s.io 25 | resources: 26 | - leases 27 | verbs: 28 | - "*" 29 | - apiGroups: 30 | - apps 31 | resources: 32 | - deployments 33 | - daemonsets 34 | verbs: 35 | - "*" 36 | - apiGroups: 37 | - csi-baremetal.dell.com 38 | resources: 39 | - "*" 40 | verbs: 41 | - "*" 42 | - apiGroups: 43 | - "rbac.authorization.k8s.io" 44 | resources: 45 | - rolebindings 46 | - roles 47 | verbs: 48 | - list 49 | - watch 50 | - apiGroups: 51 | - config.openshift.io 52 | resources: 53 | - schedulers 54 | verbs: 55 | - "*" 56 | - apiGroups: 57 | - operator.openshift.io 58 | resources: 59 | - secondaryschedulers 60 | verbs: 61 | - "*" 62 | --- 63 | apiVersion: rbac.authorization.k8s.io/v1 64 | kind: ClusterRoleBinding 65 | metadata: 66 | name: csi-baremetal-operator-rb 67 | roleRef: 68 | apiGroup: rbac.authorization.k8s.io 69 | kind: ClusterRole 70 | name: csi-baremetal-operator-cr 71 | subjects: 72 | - kind: ServiceAccount 73 | name: csi-baremetal-operator-sa 74 | namespace: {{ .Release.Namespace }} 75 | -------------------------------------------------------------------------------- /charts/csi-baremetal-operator/values.yaml: -------------------------------------------------------------------------------- 1 | # Docker registry to pull images 2 | global: 3 | registry: 4 | registrySecret: 5 | 6 | image: 7 | tag: green 8 | pullPolicy: Always 9 | 10 | securityContext: 11 | enable: 12 | runAsNonRoot: 13 | runAsUser: 14 | 15 | # Image pull settings 16 | operator: 17 | image: 18 | name: csi-baremetal-operator 19 | tag: 20 | pullPolicy: 21 | 22 | resources: 23 | limits: 24 | cpu: 100m 25 | memory: 200Mi 26 | requests: 27 | cpu: 100m 28 | memory: 20Mi 29 | 30 | preUpgradeCRDsHooks: 31 | image: 32 | name: csi-baremetal-pre-upgrade-crds 33 | tag: 34 | pullPolicy: 35 | 36 | resources: 37 | limits: 38 | cpu: 100m 39 | memory: 200Mi 40 | requests: 41 | cpu: 100m 42 | memory: 20Mi 43 | 44 | podAnnotations: {} 45 | 46 | log: 47 | level: info 48 | -------------------------------------------------------------------------------- /charts/secondary-scheduler-operator/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: secondaryscheduleroperator 3 | description: A Helm chart for Kubernetes 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 1.1.0 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | # It is recommended to use it with quotes. 24 | appVersion: "1.5.0" 25 | -------------------------------------------------------------------------------- /charts/secondary-scheduler-operator/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | 1. Check the secondary scheduler operator running status by running these commands: 2 | kubectl get pod -n {{ .Release.Namespace }} 3 | -------------------------------------------------------------------------------- /charts/secondary-scheduler-operator/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* 2 | Expand the name of the chart. 3 | */}} 4 | {{- define "secondaryscheduleroperator.name" -}} 5 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} 6 | {{- end }} 7 | 8 | {{/* 9 | Create a default fully qualified app name. 10 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 11 | If release name contains chart name it will be used as a full name. 12 | */}} 13 | {{- define "secondaryscheduleroperator.fullname" -}} 14 | {{- if .Values.fullnameOverride }} 15 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} 16 | {{- else }} 17 | {{- $name := default .Chart.Name .Values.nameOverride }} 18 | {{- if contains $name .Release.Name }} 19 | {{- .Release.Name | trunc 63 | trimSuffix "-" }} 20 | {{- else }} 21 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} 22 | {{- end }} 23 | {{- end }} 24 | {{- end }} 25 | 26 | {{/* 27 | Create chart name and version as used by the chart label. 28 | */}} 29 | {{- define "secondaryscheduleroperator.chart" -}} 30 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} 31 | {{- end }} 32 | 33 | {{/* 34 | Common labels 35 | */}} 36 | {{- define "secondaryscheduleroperator.labels" -}} 37 | helm.sh/chart: {{ include "secondaryscheduleroperator.chart" . }} 38 | {{ include "secondaryscheduleroperator.selectorLabels" . }} 39 | {{- if .Chart.AppVersion }} 40 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 41 | {{- end }} 42 | app.kubernetes.io/managed-by: {{ .Release.Service }} 43 | {{- end }} 44 | 45 | {{/* 46 | Selector labels 47 | */}} 48 | {{- define "secondaryscheduleroperator.selectorLabels" -}} 49 | app.kubernetes.io/name: {{ include "secondaryscheduleroperator.name" . }} 50 | app.kubernetes.io/instance: {{ .Release.Name }} 51 | {{- end }} 52 | 53 | {{/* 54 | Create the name of the service account to use 55 | */}} 56 | {{- define "secondaryscheduleroperator.serviceAccountName" -}} 57 | {{- if .Values.serviceAccount.create }} 58 | {{- default (include "secondaryscheduleroperator.fullname" .) .Values.serviceAccount.name }} 59 | {{- else }} 60 | {{- default "default" .Values.serviceAccount.name }} 61 | {{- end }} 62 | {{- end }} 63 | -------------------------------------------------------------------------------- /charts/secondary-scheduler-operator/templates/post-install-job.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | name: "{{ .Release.Name }}-post-install-script" 6 | namespace: {{ .Release.Namespace }} 7 | annotations: 8 | "helm.sh/hook": post-install 9 | "helm.sh/hook-weight": "-2" 10 | "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded 11 | data: 12 | post-install.sh: | 13 | #!/bin/sh 14 | set -e 15 | kubectl patch csv -n {{ .Release.Namespace }} {{ .Values.csv.version }} --type='json' -p '[{"op":"replace","path":"/spec/install/spec/deployments/0/spec/template/spec/containers/0/image", "value":"{{ .Values.global.registry }}/{{ .Values.secondaryOperator.image.name }}:{{ default .Values.image.tag .Values.secondaryOperator.image.tag }}"}]' 16 | 17 | 18 | --- 19 | apiVersion: batch/v1 20 | kind: Job 21 | metadata: 22 | name: "{{ .Release.Name }}-post-install-hook" 23 | namespace: {{ .Release.Namespace }} 24 | labels: 25 | app.kubernetes.io/managed-by: {{ .Release.Service | quote }} 26 | app.kubernetes.io/instance: {{ .Release.Name | quote }} 27 | app.kubernetes.io/version: {{ .Chart.AppVersion }} 28 | helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 29 | annotations: 30 | # This is what defines this resource as a hook. Without this line, the 31 | # job is considered part of the release. 32 | "helm.sh/hook": post-install 33 | "helm.sh/hook-weight": "-1" 34 | "helm.sh/hook-delete-policy": hook-succeeded 35 | spec: 36 | template: 37 | metadata: 38 | name: "{{ .Release.Name }}-post-install-hook" 39 | labels: 40 | app.kubernetes.io/instance: {{ .Release.Name | quote }} 41 | helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 42 | spec: 43 | restartPolicy: Never 44 | serviceAccountName: {{ include "secondaryscheduleroperator.serviceAccountName" . }} 45 | containers: 46 | - name: post-install-job 47 | image: "{{ .Values.global.registry }}/{{ .Values.helmHooks.repository }}:{{ default .Values.image.tag .Values.helmHooks.version }}" 48 | command: 49 | - /scripts/post-install.sh 50 | volumeMounts: 51 | - name: sh 52 | mountPath: /scripts 53 | readOnly: true 54 | volumes: 55 | - name: sh 56 | configMap: 57 | name: "{{ .Release.Name }}-post-install-script" 58 | defaultMode: 0555 59 | -------------------------------------------------------------------------------- /charts/secondary-scheduler-operator/templates/pre-delete-job.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | name: "{{ .Release.Name }}-pre-delete-script" 6 | namespace: {{ .Release.Namespace }} 7 | annotations: 8 | "helm.sh/hook": pre-delete 9 | "helm.sh/hook-weight": "-2" 10 | "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded 11 | data: 12 | pre-delete.sh: | 13 | #!/bin/sh 14 | set -e 15 | kubectl delete csv -n {{ .Release.Namespace }} --all 16 | 17 | 18 | --- 19 | apiVersion: batch/v1 20 | kind: Job 21 | metadata: 22 | name: "{{ .Release.Name }}-pre-delete-hook" 23 | namespace: {{ .Release.Namespace }} 24 | labels: 25 | app.kubernetes.io/managed-by: {{ .Release.Service | quote }} 26 | app.kubernetes.io/instance: {{ .Release.Name | quote }} 27 | app.kubernetes.io/version: {{ .Chart.AppVersion }} 28 | helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 29 | annotations: 30 | # This is what defines this resource as a hook. Without this line, the 31 | # job is considered part of the release. 32 | "helm.sh/hook": pre-delete 33 | "helm.sh/hook-weight": "-1" 34 | "helm.sh/hook-delete-policy": hook-succeeded 35 | spec: 36 | template: 37 | metadata: 38 | name: "{{ .Release.Name }}-post-install-hook" 39 | labels: 40 | app.kubernetes.io/instance: {{ .Release.Name | quote }} 41 | helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 42 | spec: 43 | restartPolicy: Never 44 | serviceAccountName: {{ include "secondaryscheduleroperator.serviceAccountName" . }} 45 | containers: 46 | - name: pre-delete-job 47 | image: "{{ .Values.global.registry }}/{{ .Values.helmHooks.repository }}:{{ default .Values.image.tag .Values.helmHooks.version }}" 48 | command: 49 | - /scripts/pre-delete.sh 50 | volumeMounts: 51 | - name: sh 52 | mountPath: /scripts 53 | readOnly: true 54 | volumes: 55 | - name: sh 56 | configMap: 57 | name: "{{ .Release.Name }}-pre-delete-script" 58 | defaultMode: 0555 59 | -------------------------------------------------------------------------------- /charts/secondary-scheduler-operator/templates/pre-install-job.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: "{{.Release.Name}}-puc" 6 | namespace: {{ .Release.Namespace }} 7 | labels: 8 | app.kubernetes.io/name: {{ .Chart.Name }} 9 | app.kubernetes.io/instance: {{.Release.Name}} 10 | release: {{.Release.Name}} 11 | annotations: 12 | "helm.sh/hook": pre-install 13 | "helm.sh/hook-weight": "-5" 14 | "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed 15 | 16 | # 17 | # Create the cluster role for replacing CRDs during upgrade. 18 | # 19 | --- 20 | kind: ClusterRole 21 | apiVersion: rbac.authorization.k8s.io/v1 22 | metadata: 23 | name: "{{.Release.Namespace}}-{{.Release.Name}}-puc" 24 | labels: 25 | app.kubernetes.io/name: {{ .Chart.Name }} 26 | app.kubernetes.io/instance: {{.Release.Name}} 27 | release: {{.Release.Name}} 28 | annotations: 29 | "helm.sh/hook": pre-install 30 | "helm.sh/hook-weight": "-4" 31 | "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed 32 | rules: 33 | - apiGroups: 34 | - operators.coreos.com 35 | resources: 36 | - operatorgroups 37 | verbs: 38 | - '*' 39 | # 40 | # Create the cluster role binding for replacing CRDs during upgrade. 41 | # 42 | --- 43 | kind: ClusterRoleBinding 44 | apiVersion: rbac.authorization.k8s.io/v1 45 | metadata: 46 | name: "{{.Release.Namespace}}-{{.Release.Name}}-puc" 47 | labels: 48 | app.kubernetes.io/name: {{ .Chart.Name }} 49 | app.kubernetes.io/instance: {{.Release.Name}} 50 | release: {{.Release.Name}} 51 | annotations: 52 | "helm.sh/hook": pre-install 53 | "helm.sh/hook-weight": "-3" 54 | "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed 55 | subjects: 56 | - kind: ServiceAccount 57 | name: "{{.Release.Name}}-puc" 58 | namespace: {{ .Release.Namespace }} 59 | roleRef: 60 | kind: ClusterRole 61 | name: "{{.Release.Namespace}}-{{.Release.Name}}-puc" 62 | apiGroup: rbac.authorization.k8s.io 63 | 64 | --- 65 | apiVersion: v1 66 | kind: ConfigMap 67 | metadata: 68 | name: "{{ .Release.Name }}-pre-install-script" 69 | namespace: {{ .Release.Namespace }} 70 | annotations: 71 | "helm.sh/hook": pre-install 72 | "helm.sh/hook-weight": "-2" 73 | "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed 74 | data: 75 | pre-install.sh: | 76 | #!/bin/sh 77 | set -e 78 | cat << EOF | kubectl apply -f - 79 | apiVersion: operators.coreos.com/v1 80 | kind: OperatorGroup 81 | metadata: 82 | annotations: 83 | olm.providedAPIs: SecondaryScheduler.v1.operator.openshift.io 84 | name: openshift-secondary-scheduler-operator-jh7wv 85 | namespace: {{ .Release.Namespace }} 86 | spec: 87 | targetNamespaces: 88 | - {{ .Release.Namespace }} 89 | upgradeStrategy: Default 90 | EOF 91 | 92 | # 93 | # Create the job for replacing CRDs during upgrade. 94 | # 95 | --- 96 | apiVersion: batch/v1 97 | kind: Job 98 | metadata: 99 | name: "{{ .Release.Name }}-puc" 100 | namespace: {{.Release.Namespace}} 101 | annotations: 102 | "helm.sh/hook": pre-install 103 | "helm.sh/hook-weight": "-1" 104 | "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed 105 | labels: 106 | app.kubernetes.io/name: {{ .Chart.Name }} 107 | app.kubernetes.io/instance: {{.Release.Name}} 108 | release: {{.Release.Name}} 109 | spec: 110 | backoffLimit: 4 111 | activeDeadlineSeconds: 300 112 | template: 113 | metadata: 114 | name: "{{ .Chart.Name }}-puc" 115 | spec: 116 | serviceAccountName: "{{.Release.Name}}-puc" 117 | restartPolicy: Never 118 | containers: 119 | - name: "{{ .Chart.Name }}-puc" 120 | image: "{{ .Values.global.registry }}/{{ .Values.helmHooks.repository }}:{{ default .Values.image.tag .Values.helmHooks.version }}" 121 | imagePullPolicy: "IfNotPresent" 122 | command: 123 | - /scripts/pre-install.sh 124 | volumeMounts: 125 | - name: sh 126 | mountPath: /scripts 127 | readOnly: true 128 | volumes: 129 | - name: sh 130 | configMap: 131 | name: "{{ .Release.Name }}-pre-install-script" 132 | defaultMode: 0555 133 | -------------------------------------------------------------------------------- /charts/secondary-scheduler-operator/templates/role.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: secondaryscheduleroperator-role 6 | namespace: {{ .Release.Namespace }} 7 | rules: 8 | - apiGroups: 9 | - operators.coreos.com 10 | resources: 11 | - subscriptions 12 | verbs: 13 | - '*' 14 | - apiGroups: 15 | - operators.coreos.com 16 | resources: 17 | - operatorgroups 18 | verbs: 19 | - '*' 20 | - apiGroups: 21 | - operators.coreos.com 22 | resources: 23 | - clusterserviceversions 24 | verbs: 25 | - '*' 26 | -------------------------------------------------------------------------------- /charts/secondary-scheduler-operator/templates/rolebinding.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRoleBinding 4 | metadata: 5 | name: secondaryscheduleroperator-rolebinding 6 | namespace: {{ .Release.Namespace }} 7 | roleRef: 8 | apiGroup: rbac.authorization.k8s.io 9 | kind: ClusterRole 10 | name: secondaryscheduleroperator-role 11 | subjects: 12 | - kind: ServiceAccount 13 | name: {{ template "secondaryscheduleroperator.serviceAccountName" . }} 14 | namespace: {{ .Release.Namespace }} 15 | -------------------------------------------------------------------------------- /charts/secondary-scheduler-operator/templates/serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.serviceAccount.create -}} 2 | --- 3 | apiVersion: v1 4 | kind: ServiceAccount 5 | metadata: 6 | name: {{ include "secondaryscheduleroperator.serviceAccountName" . }} 7 | labels: 8 | {{- include "secondaryscheduleroperator.labels" . | nindent 4 }} 9 | {{- with .Values.serviceAccount.annotations }} 10 | annotations: 11 | {{- toYaml . | nindent 4 }} 12 | {{- end }} 13 | {{- end }} 14 | -------------------------------------------------------------------------------- /charts/secondary-scheduler-operator/templates/subscription.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: operators.coreos.com/v1alpha1 2 | kind: Subscription 3 | metadata: 4 | labels: 5 | operators.coreos.com/openshift-secondary-scheduler-operator.openshift-secondary-sche: "" 6 | name: openshift-secondary-scheduler-operator 7 | namespace: {{ .Release.Namespace }} 8 | spec: 9 | channel: stable 10 | installPlanApproval: Automatic 11 | name: openshift-secondary-scheduler-operator 12 | source: redhat-operators 13 | sourceNamespace: openshift-marketplace 14 | startingCSV: {{ .Values.csv.version }} 15 | -------------------------------------------------------------------------------- /charts/secondary-scheduler-operator/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for secondaryscheduleroperator. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | global: 5 | registry: dellcorp 6 | 7 | replicaCount: 1 8 | 9 | secondaryOperator: 10 | image: 11 | name: secondary-scheduler-operator 12 | tag: 13 | 14 | image: 15 | pullPolicy: IfNotPresent 16 | tag: 1.1.0-113.dda98ea 17 | 18 | # Overrides the image tag whose default is the chart appVersion. 19 | 20 | imagePullSecrets: [] 21 | nameOverride: "" 22 | fullnameOverride: "" 23 | 24 | serviceAccount: 25 | # Specifies whether a service account should be created 26 | create: true 27 | # Annotations to add to the service account 28 | annotations: {} 29 | # The name of the service account to use. 30 | # If not set and create is true, a name is generated using the fullname template 31 | name: "secscheduleroperator" 32 | 33 | podAnnotations: {} 34 | 35 | podSecurityContext: {} 36 | # fsGroup: 2000 37 | 38 | securityContext: {} 39 | # capabilities: 40 | # drop: 41 | # - ALL 42 | # readOnlyRootFilesystem: true 43 | # runAsNonRoot: true 44 | # runAsUser: 1000 45 | 46 | resources: {} 47 | # We usually recommend not to specify default resources and to leave this as a conscious 48 | # choice for the user. This also increases chances charts run on environments with little 49 | # resources, such as Minikube. If you do want to specify resources, uncomment the following 50 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'. 51 | # limits: 52 | # cpu: 100m 53 | # memory: 128Mi 54 | # requests: 55 | # cpu: 100m 56 | # memory: 128Mi 57 | 58 | nodeSelector: {} 59 | 60 | tolerations: [] 61 | 62 | affinity: {} 63 | 64 | # hook for the pre-delete/pre-install/post-install 65 | helmHooks: 66 | repository: csi-baremetal-pre-upgrade-crds 67 | version: 68 | 69 | 70 | csv: 71 | version: secondaryscheduleroperator.v1.1.0 72 | -------------------------------------------------------------------------------- /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 0.11 check https://docs.cert-manager.io/en/latest/tasks/upgrading/index.html for 4 | # breaking changes 5 | apiVersion: cert-manager.io/v1alpha2 6 | kind: Issuer 7 | metadata: 8 | name: selfsigned-issuer 9 | namespace: system 10 | spec: 11 | selfSigned: {} 12 | --- 13 | apiVersion: cert-manager.io/v1alpha2 14 | kind: Certificate 15 | metadata: 16 | name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml 17 | namespace: system 18 | spec: 19 | # $(SERVICE_NAME) and $(SERVICE_NAMESPACE) will be substituted by kustomize 20 | dnsNames: 21 | - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc 22 | - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc.cluster.local 23 | issuerRef: 24 | kind: Issuer 25 | name: selfsigned-issuer 26 | secretName: webhook-server-cert # this secret will not be prefixed, since it's not managed by kustomize 27 | -------------------------------------------------------------------------------- /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/csi-baremetal.dell.com_deployments.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_deployments.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_deployments.yaml 17 | # +kubebuilder:scaffold:crdkustomizecainjectionpatch 18 | 19 | # the following config is for teaching kustomize how to do kustomization for CRDs. 20 | configurations: 21 | - kustomizeconfig.yaml 22 | -------------------------------------------------------------------------------- /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_deployments.yaml: -------------------------------------------------------------------------------- 1 | # The following patch adds a directive for certmanager to inject CA into the CRD 2 | # CRD conversion requires k8s 1.13 or later. 3 | apiVersion: apiextensions.k8s.io/v1beta1 4 | kind: CustomResourceDefinition 5 | metadata: 6 | annotations: 7 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 8 | name: deployments.csi-baremetal.dell.com 9 | -------------------------------------------------------------------------------- /config/crd/patches/webhook_in_deployments.yaml: -------------------------------------------------------------------------------- 1 | # The following patch enables conversion webhook for CRD 2 | # CRD conversion requires k8s 1.13 or later. 3 | apiVersion: apiextensions.k8s.io/v1beta1 4 | kind: CustomResourceDefinition 5 | metadata: 6 | name: deployments.csi-baremetal.dell.com 7 | spec: 8 | conversion: 9 | strategy: Webhook 10 | webhookClientConfig: 11 | # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, 12 | # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) 13 | caBundle: Cg== 14 | service: 15 | namespace: system 16 | name: webhook-service 17 | path: /convert 18 | -------------------------------------------------------------------------------- /config/default/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # Adds namespace to all resources. 2 | namespace: csi-baremetal-operator-system 3 | 4 | # Value of this field is prepended to the 5 | # names of all resources, e.g. a deployment named 6 | # "wordpress" becomes "alices-wordpress". 7 | # Note that it should also match with the prefix (text before '-') of the namespace 8 | # field above. 9 | namePrefix: csi-baremetal-operator- 10 | 11 | # Labels to add to all resources and selectors. 12 | #commonLabels: 13 | # someName: someValue 14 | 15 | bases: 16 | - ../crd 17 | - ../rbac 18 | - ../manager 19 | # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in 20 | # crd/kustomization.yaml 21 | #- ../webhook 22 | # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required. 23 | #- ../certmanager 24 | # [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. 25 | #- ../prometheus 26 | 27 | patchesStrategicMerge: 28 | # Protect the /metrics endpoint by putting it behind auth. 29 | # If you want your controller-manager to expose the /metrics 30 | # endpoint w/o any authn/z, please comment the following line. 31 | - manager_auth_proxy_patch.yaml 32 | 33 | # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in 34 | # crd/kustomization.yaml 35 | #- manager_webhook_patch.yaml 36 | 37 | # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 38 | # Uncomment 'CERTMANAGER' sections in crd/kustomization.yaml to enable the CA injection in the admission webhooks. 39 | # 'CERTMANAGER' needs to be enabled to use ca injection 40 | #- webhookcainjection_patch.yaml 41 | 42 | # the following config is for teaching kustomize how to do var substitution 43 | vars: 44 | # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix. 45 | #- name: CERTIFICATE_NAMESPACE # namespace of the certificate CR 46 | # objref: 47 | # kind: Certificate 48 | # group: cert-manager.io 49 | # version: v1alpha2 50 | # name: serving-cert # this name should match the one in certificate.yaml 51 | # fieldref: 52 | # fieldpath: metadata.namespace 53 | #- name: CERTIFICATE_NAME 54 | # objref: 55 | # kind: Certificate 56 | # group: cert-manager.io 57 | # version: v1alpha2 58 | # name: serving-cert # this name should match the one in certificate.yaml 59 | #- name: SERVICE_NAMESPACE # namespace of the service 60 | # objref: 61 | # kind: Service 62 | # version: v1 63 | # name: webhook-service 64 | # fieldref: 65 | # fieldpath: metadata.namespace 66 | #- name: SERVICE_NAME 67 | # objref: 68 | # kind: Service 69 | # version: v1 70 | # name: webhook-service 71 | -------------------------------------------------------------------------------- /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: controller-manager 7 | namespace: system 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 | - "--enable-leader-election" 26 | -------------------------------------------------------------------------------- /config/default/manager_webhook_patch.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: controller-manager 5 | namespace: system 6 | spec: 7 | template: 8 | spec: 9 | containers: 10 | - name: manager 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/v1beta1 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 | apiVersion: admissionregistration.k8s.io/v1beta1 11 | kind: ValidatingWebhookConfiguration 12 | metadata: 13 | name: validating-webhook-configuration 14 | annotations: 15 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 16 | -------------------------------------------------------------------------------- /config/manager/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - manager.yaml 3 | -------------------------------------------------------------------------------- /config/manager/manager.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | labels: 5 | control-plane: controller-manager 6 | name: system 7 | --- 8 | apiVersion: apps/v1 9 | kind: Deployment 10 | metadata: 11 | name: controller-manager 12 | namespace: system 13 | labels: 14 | control-plane: controller-manager 15 | spec: 16 | selector: 17 | matchLabels: 18 | control-plane: controller-manager 19 | replicas: 1 20 | template: 21 | metadata: 22 | labels: 23 | control-plane: controller-manager 24 | spec: 25 | containers: 26 | - command: 27 | - /manager 28 | args: 29 | - --enable-leader-election 30 | image: controller:latest 31 | name: manager 32 | resources: 33 | limits: 34 | cpu: 100m 35 | memory: 30Mi 36 | requests: 37 | cpu: 100m 38 | memory: 20Mi 39 | terminationGracePeriodSeconds: 10 40 | -------------------------------------------------------------------------------- /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: system 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/v1 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: system 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: system 8 | spec: 9 | ports: 10 | - name: https 11 | port: 8443 12 | targetPort: https 13 | selector: 14 | control-plane: controller-manager 15 | -------------------------------------------------------------------------------- /config/rbac/deployment_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit deployments. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: deployment-editor-role 6 | rules: 7 | - apiGroups: 8 | - csi-baremetal.dell.com 9 | resources: 10 | - deployments 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - csi-baremetal.dell.com 21 | resources: 22 | - deployments/status 23 | verbs: 24 | - get 25 | -------------------------------------------------------------------------------- /config/rbac/deployment_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view deployments. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: deployment-viewer-role 6 | rules: 7 | - apiGroups: 8 | - csi-baremetal.dell.com 9 | resources: 10 | - deployments 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - apiGroups: 16 | - csi-baremetal.dell.com 17 | resources: 18 | - deployments/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: 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 | -------------------------------------------------------------------------------- /config/rbac/leader_election_role_binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | name: leader-election-rolebinding 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: Role 8 | name: leader-election-role 9 | subjects: 10 | - kind: ServiceAccount 11 | name: default 12 | namespace: system 13 | -------------------------------------------------------------------------------- /config/rbac/role.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: rbac.authorization.k8s.io/v1 4 | kind: ClusterRole 5 | metadata: 6 | creationTimestamp: null 7 | name: manager-role 8 | rules: 9 | - apiGroups: 10 | - csi-baremetal.dell.com 11 | resources: 12 | - deployments 13 | verbs: 14 | - create 15 | - delete 16 | - get 17 | - list 18 | - patch 19 | - update 20 | - watch 21 | - apiGroups: 22 | - csi-baremetal.dell.com 23 | resources: 24 | - deployments/status 25 | verbs: 26 | - get 27 | - patch 28 | - update 29 | -------------------------------------------------------------------------------- /config/rbac/role_binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: manager-rolebinding 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: ClusterRole 8 | name: manager-role 9 | subjects: 10 | - kind: ServiceAccount 11 | name: default 12 | namespace: system 13 | -------------------------------------------------------------------------------- /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: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dell/csi-baremetal-operator/421fd0925b8e498adb97f7790180cfedae94a27e/config/webhook/manifests.yaml -------------------------------------------------------------------------------- /config/webhook/service.yaml: -------------------------------------------------------------------------------- 1 | 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: webhook-service 6 | namespace: system 7 | spec: 8 | ports: 9 | - port: 443 10 | targetPort: 9443 11 | selector: 12 | control-plane: controller-manager 13 | -------------------------------------------------------------------------------- /deploy/configmap/fluent-bit-config-map.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | namespace: default 5 | name: csi-baremetal-logs-config 6 | # labels: 7 | # helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} 8 | data: 9 | fluent-bit.conf: | 10 | [SERVICE] 11 | Flush 5 12 | Log_Level info 13 | Daemon off 14 | Parsers_File fluent-parsers.conf 15 | HTTP_Server On 16 | HTTP_Listen 0.0.0.0 17 | HTTP_Port 2020 18 | [INPUT] 19 | Name tail 20 | Path /var/log/csi.log 21 | DB /var/log/flb.db 22 | Path_Key filename 23 | Parser csi-logs 24 | Mem_Buf_Limit 5MB 25 | Skip_Long_Lines Off 26 | Refresh_Interval 5 27 | Tag csi-baremetal 28 | [INPUT] 29 | Name tail 30 | Path /var/log/drivemgr.log 31 | DB /var/log/flb.db 32 | Path_Key filename 33 | Parser csi-logs 34 | Mem_Buf_Limit 5MB 35 | Skip_Long_Lines Off 36 | Refresh_Interval 5 37 | Tag kubernetes_cluster-csi-baremetal 38 | [FILTER] 39 | Name record_modifier 40 | Match * 41 | Record pod_name ${POD_NAME} 42 | Record node_name ${NODE_NAME} 43 | Record namespace ${NAMESPACE} 44 | [OUTPUT] 45 | Name es 46 | Match * 47 | tls Of 48 | tls On 49 | HTTP_User 50 | HTTP_Passwd 51 | tls.verify Off 52 | Type logEvent 53 | Host 54 | Port 55 | Logstash_Format on 56 | Retry_Limit False 57 | Logstash_Prefix kubernetes_cluster-csi-baremetal 58 | fluent-parsers.conf: | 59 | [PARSER] 60 | Name csi-logs 61 | Format json 62 | Time_Key time 63 | Time_Format %Y-%m-%dT%H:%M:%S %z -------------------------------------------------------------------------------- /deploy/configmap/loopbackmgr-config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | namespace: default 5 | name: loopback-config 6 | labels: 7 | app: csi-baremetal-node 8 | data: 9 | config.yaml: |- 10 | defaultDrivePerNodeCount: 3 11 | defaultDriveSize: 302Mi 12 | 13 | -------------------------------------------------------------------------------- /deploy/configmap/patcher-configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: schedulerpatcher-config 5 | data: 6 | config.yaml: | 7 | apiVersion: kubescheduler.config.k8s.io/v1alpha1 8 | kind: KubeSchedulerConfiguration 9 | schedulerName: default-scheduler 10 | algorithmSource: 11 | policy: 12 | file: 13 | path: /etc/kubernetes/scheduler/policy.yaml 14 | leaderElection: 15 | leaderElect: true 16 | clientConnection: 17 | kubeconfig: /etc/kubernetes/scheduler.conf 18 | policy.yaml: | 19 | apiVersion: v1 20 | kind: Policy 21 | extenders: 22 | - urlPrefix: "http://127.0.0.1:8889" 23 | filterVerb: filter 24 | prioritizeVerb: prioritize 25 | weight: 1 26 | #bindVerb: bind 27 | enableHttps: false 28 | nodeCacheCapable: false 29 | ignorable: true 30 | # 15 seconds 31 | httpTimeout: 15000000000 32 | -------------------------------------------------------------------------------- /deploy/csidriver/csidriver.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: storage.k8s.io/v1 2 | kind: CSIDriver 3 | metadata: 4 | name: csi-baremetal 5 | spec: 6 | attachRequired: false 7 | # pass pod info to NodePublishRequest 8 | podInfoOnMount: true 9 | volumeLifecycleModes: 10 | - Persistent 11 | - Ephemeral 12 | -------------------------------------------------------------------------------- /deploy/monitoring/csi-pod-monitor.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.coreos.com/v1 2 | kind: PodMonitor 3 | metadata: 4 | labels: 5 | k8s-app: prometheus-csi-monitor 6 | name: prometheus-csi-monitor 7 | namespace: default 8 | spec: 9 | podMetricsEndpoints: [ 10 | path: /metrics, 11 | port: "8787", 12 | interval: "15", 13 | scrapeTimeout: "300" 14 | ] 15 | selector: 16 | matchLabels: 17 | app: csi-baremetal 18 | app.kubernetes.io/name: csi-baremetal 19 | namespaceSelector: 20 | matchNames: [default] 21 | -------------------------------------------------------------------------------- /deploy/monitoring/monitoring-configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: cluster-monitoring-config 5 | namespace: openshift-monitoring 6 | data: 7 | config.yaml: | 8 | enableUserWorkload: true 9 | -------------------------------------------------------------------------------- /deploy/rbac/csibm-rbac.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: csi-operator-sa 5 | namespace: default 6 | --- 7 | kind: ClusterRole 8 | apiVersion: rbac.authorization.k8s.io/v1 9 | metadata: 10 | name: csi-operator-cr 11 | rules: 12 | - apiGroups: [""] 13 | resources: ["nodes"] 14 | verbs: ["get", "list", "watch", "update"] 15 | - apiGroups: ["csi-baremetal.dell.com"] 16 | resources: ["nodes"] 17 | verbs: ["watch", "get", "list", "create", "delete", "update"] 18 | --- 19 | kind: ClusterRoleBinding 20 | apiVersion: rbac.authorization.k8s.io/v1 21 | metadata: 22 | name: csi-operator-rb 23 | subjects: 24 | - kind: ServiceAccount 25 | name: csi-operator-sa 26 | namespace: default 27 | roleRef: 28 | kind: ClusterRole 29 | name: csi-operator-cr 30 | apiGroup: rbac.authorization.k8s.io 31 | -------------------------------------------------------------------------------- /deploy/rbac/node-rbac.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: csi-node-sa 6 | namespace: default 7 | 8 | 9 | --- 10 | kind: ClusterRole 11 | apiVersion: rbac.authorization.k8s.io/v1 12 | metadata: 13 | name: driver-registrar-runner 14 | rules: 15 | - apiGroups: [""] 16 | resources: ["persistentvolumes"] 17 | verbs: ["get", "list", "watch", "update"] 18 | - apiGroups: [""] 19 | resources: ["nodes"] 20 | verbs: ["get", "list", "watch"] 21 | - apiGroups: ["csi.storage.k8s.io"] 22 | resources: ["csinodeinfos"] 23 | verbs: ["get", "list", "watch"] 24 | - apiGroups: ["storage.k8s.io"] 25 | resources: ["volumeattachments"] 26 | verbs: ["get", "list", "watch", "update"] 27 | - apiGroups: [""] 28 | resources: ["events"] 29 | verbs: ["get", "list", "watch", "create", "update", "patch"] 30 | 31 | --- 32 | kind: ClusterRoleBinding 33 | apiVersion: rbac.authorization.k8s.io/v1 34 | metadata: 35 | name: csi-driver-registrar-role 36 | subjects: 37 | - kind: ServiceAccount 38 | name: csi-node-sa 39 | namespace: default 40 | roleRef: 41 | kind: ClusterRole 42 | name: driver-registrar-runner 43 | apiGroup: rbac.authorization.k8s.io 44 | 45 | --- 46 | apiVersion: rbac.authorization.k8s.io/v1 47 | kind: ClusterRole 48 | metadata: 49 | name: node 50 | rules: 51 | - apiGroups: ["csi-baremetal.dell.com"] 52 | resources: ["*"] 53 | verbs: ["*"] 54 | 55 | --- 56 | apiVersion: rbac.authorization.k8s.io/v1 57 | kind: ClusterRoleBinding 58 | metadata: 59 | name: node-role 60 | subjects: 61 | - kind: ServiceAccount 62 | name: csi-node-sa 63 | namespace: default 64 | roleRef: 65 | apiGroup: rbac.authorization.k8s.io 66 | kind: ClusterRole 67 | name: node 68 | 69 | 70 | --- 71 | kind: ClusterRoleBinding 72 | apiVersion: rbac.authorization.k8s.io/v1 73 | metadata: 74 | name: controller-crd-node-role 75 | subjects: 76 | - kind: ServiceAccount 77 | name: csi-node-sa 78 | namespace: default 79 | roleRef: 80 | kind: ClusterRole 81 | name: controller 82 | apiGroup: rbac.authorization.k8s.io 83 | -------------------------------------------------------------------------------- /deploy/rbac/rbac.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | namespace: default 6 | name: csi-baremetal-extender-sa 7 | --- 8 | apiVersion: rbac.authorization.k8s.io/v1 9 | kind: ClusterRole 10 | metadata: 11 | name: csi-baremetal-extender-cr 12 | rules: 13 | - apiGroups: ["csi-baremetal.dell.com"] 14 | resources: ["volumes"] 15 | verbs: ["get", "list", "watch"] 16 | - apiGroups: ["csi-baremetal.dell.com"] 17 | resources: ["availablecapacities"] 18 | verbs: ["get", "list"] 19 | - apiGroups: ["csi-baremetal.dell.com"] 20 | resources: ["availablecapacityreservations"] 21 | verbs: ["get", "list", "create"] 22 | - apiGroups: [""] 23 | resources: ["persistentvolumeclaims"] 24 | verbs: ["get", "list", "watch"] 25 | - apiGroups: [""] 26 | resources: ["events"] 27 | verbs: ["get", "list", "watch"] 28 | - apiGroups: ["storage.k8s.io"] 29 | resources: ["storageclasses"] 30 | verbs: ["get", "list", "watch"] 31 | --- 32 | kind: ClusterRoleBinding 33 | apiVersion: rbac.authorization.k8s.io/v1 34 | metadata: 35 | name: csi-baremetal-extender-rb 36 | roleRef: 37 | apiGroup: rbac.authorization.k8s.io 38 | kind: ClusterRole 39 | name: csi-baremetal-extender-cr 40 | subjects: 41 | - kind: ServiceAccount 42 | namespace: default 43 | name: csi-baremetal-extender-sa 44 | -------------------------------------------------------------------------------- /deploy/storageclass/default-sc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: storage.k8s.io/v1 2 | kind: StorageClass 3 | metadata: 4 | name: csi-baremetal-sc 5 | annotations: 6 | storageclass.kubernetes.io/is-default-class: "true" 7 | provisioner: csi-baremetal # CSI driver name 8 | reclaimPolicy: Delete 9 | volumeBindingMode: WaitForFirstConsumer 10 | parameters: 11 | storageType: ANY # With ANY storage type CSI allocates volumes on top of ANY physical drive (non LVG) 12 | fsType: xfs 13 | -------------------------------------------------------------------------------- /deploy/storageclass/hdd-sc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: storage.k8s.io/v1 2 | kind: StorageClass 3 | metadata: 4 | name: csi-baremetal-sc-hdd 5 | provisioner: csi-baremetal # CSI driver name 6 | reclaimPolicy: Delete 7 | volumeBindingMode: WaitForFirstConsumer 8 | parameters: 9 | storageType: HDD 10 | fsType: xfs 11 | -------------------------------------------------------------------------------- /deploy/storageclass/hddlvg-sc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: storage.k8s.io/v1 2 | kind: StorageClass 3 | metadata: 4 | name: csi-baremetal-sc-hddlvg 5 | provisioner: csi-baremetal # CSI driver name 6 | reclaimPolicy: Delete 7 | volumeBindingMode: WaitForFirstConsumer 8 | allowVolumeExpansion: true 9 | parameters: 10 | storageType: HDDLVG 11 | fsType: xfs 12 | -------------------------------------------------------------------------------- /deploy/storageclass/nvme-sc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: storage.k8s.io/v1 2 | kind: StorageClass 3 | metadata: 4 | name: csi-baremetal-sc-nvme 5 | provisioner: csi-baremetal # CSI driver name 6 | reclaimPolicy: Delete 7 | volumeBindingMode: WaitForFirstConsumer 8 | parameters: 9 | storageType: NVME 10 | fsType: xfs 11 | -------------------------------------------------------------------------------- /deploy/storageclass/ssd-sc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: storage.k8s.io/v1 2 | kind: StorageClass 3 | metadata: 4 | name: csi-baremetal-sc-ssd 5 | provisioner: csi-baremetal # CSI driver name 6 | reclaimPolicy: Delete 7 | volumeBindingMode: WaitForFirstConsumer 8 | parameters: 9 | storageType: SSD 10 | fsType: xfs 11 | -------------------------------------------------------------------------------- /deploy/storageclass/ssdlvg-sc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: storage.k8s.io/v1 2 | kind: StorageClass 3 | metadata: 4 | name: csi-baremetal-sc-ssdlvg 5 | provisioner: csi-baremetal # CSI driver name 6 | reclaimPolicy: Delete 7 | volumeBindingMode: WaitForFirstConsumer 8 | allowVolumeExpansion: true 9 | parameters: 10 | storageType: SSDLVG 11 | fsType: xfs 12 | -------------------------------------------------------------------------------- /deploy/storageclass/syslvg-sc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: storage.k8s.io/v1 2 | kind: StorageClass 3 | metadata: 4 | name: csi-baremetal-sc-syslvg 5 | provisioner: csi-baremetal # CSI driver name 6 | reclaimPolicy: Delete 7 | volumeBindingMode: WaitForFirstConsumer 8 | allowVolumeExpansion: true 9 | parameters: 10 | storageType: SYSLVG 11 | fsType: xfs 12 | -------------------------------------------------------------------------------- /docs/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # file is used to notify teams or individuals about 2 | # changes to directories or files of interest. 3 | # 4 | # See https://help.github.com/articles/about-codeowners/ 5 | # for more info about the CODEOWNERS file. 6 | 7 | * @dell/csi-baremetal 8 | -------------------------------------------------------------------------------- /docs/MIGRATION_BETWEEN_NAMESPACES.md: -------------------------------------------------------------------------------- 1 | Manual CSI migration into another namespace 2 | --------------------- 3 | It may happen that CSI charts (including pods and configmaps) should be moved into another default or non-default namespace. 4 | `helm upgrade` is not suitable in this case due to kubernetes objects fields restrictions. 5 | So we need to delete and install CSI charts, which is described in the steps below. 6 | 7 | 1. Delete CSI Operator and CSI Deployment charts without removing any CRs and CRDs 8 | ```yaml 9 | helm delete csi-baremetal 10 | helm delete csi-baremetal-operator 11 | ``` 12 | 2. Reinstall CSI Operator and CSI Deployment charts into another namespace 13 | ```yaml 14 | helm install csi-baremetal-operator -n $NAMESPACE 15 | helm install csi-baremetal -n $NAMESPACE 16 | ``` 17 | 3. Wait for all pods to be ready 18 | ```yaml 19 | watch kubectl get po -n $NAMESPACE -l app=csi-baremetal 20 | ``` 21 | 4. Remove unrelated resources 22 | ```yaml 23 | kubectl get volumeattachments | grep csi-baremetal | awk '{print $1}' | xargs kubectl delete volumeattachments 24 | ``` 25 | -------------------------------------------------------------------------------- /docs/MONITORING_ON_OPENSHIFT.md: -------------------------------------------------------------------------------- 1 | How to enable monitoring of CSI pods on OpenShift 2 | --------------------- 3 | Basic doc is [here](https://docs.openshift.com/container-platform/4.6/monitoring/configuring-the-monitoring-stack.html) 4 | 5 | Necessary cmds: 6 | ``` 7 | oc apply -f deploy/monitoring/monitoring-configmap.yaml 8 | oc apply -f deploy/monitoring/csi-pod-monitor.yaml 9 | ``` -------------------------------------------------------------------------------- /docs/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Purpose 2 | ### Issue dell/csi-baremetal# 3 | 4 | _Describe your changes_ 5 | 6 | ## PR checklist 7 | - [ ] Add link to the issue 8 | - [ ] Choose Project 9 | - [ ] Choose PR label 10 | - [ ] New unit tests added 11 | - [ ] Modified code has meaningful comments 12 | - [ ] All TODOs are linked with the issues 13 | - [ ] All comments are resolved 14 | 15 | ## Testing 16 | _Testing details_ 17 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/dell/csi-baremetal-operator 2 | 3 | go 1.21 4 | 5 | require ( 6 | github.com/Masterminds/semver v1.5.0 // indirect 7 | github.com/dell/csi-baremetal v1.6.2 8 | github.com/go-logr/logr v1.4.1 // indirect 9 | github.com/masterminds/semver v1.5.0 10 | github.com/openshift/api v0.0.0-20240326215622-ff84c2c73227 11 | github.com/openshift/secondary-scheduler-operator v0.0.0-20240308133249-89eae2bb67cb 12 | github.com/sirupsen/logrus v1.9.3 13 | github.com/stretchr/testify v1.9.0 14 | gopkg.in/yaml.v3 v3.0.1 15 | k8s.io/api v0.29.3 16 | k8s.io/apimachinery v0.29.3 17 | k8s.io/client-go v0.29.3 18 | k8s.io/utils v0.0.0-20240310230437-4693a0247e57 19 | sigs.k8s.io/controller-runtime v0.17.2 20 | sigs.k8s.io/controller-tools v0.11.2 21 | ) 22 | 23 | require ( 24 | github.com/beorn7/perks v1.0.1 // indirect 25 | github.com/cespare/xxhash/v2 v2.2.0 // indirect 26 | github.com/davecgh/go-spew v1.1.1 // indirect 27 | github.com/emicklei/go-restful/v3 v3.12.0 // indirect 28 | github.com/evanphx/json-patch v5.9.0+incompatible // indirect 29 | github.com/evanphx/json-patch/v5 v5.9.0 // indirect 30 | github.com/fatih/color v1.13.0 // indirect 31 | github.com/fsnotify/fsnotify v1.7.0 // indirect 32 | github.com/go-logr/zapr v1.3.0 // indirect 33 | github.com/go-openapi/jsonpointer v0.21.0 // indirect 34 | github.com/go-openapi/jsonreference v0.21.0 // indirect 35 | github.com/go-openapi/swag v0.23.0 // indirect 36 | github.com/gobuffalo/flect v0.3.0 // indirect 37 | github.com/gogo/protobuf v1.3.2 // indirect 38 | github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect 39 | github.com/golang/protobuf v1.5.4 // indirect 40 | github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect 41 | github.com/google/go-cmp v0.6.0 // indirect 42 | github.com/google/gofuzz v1.2.0 // indirect 43 | github.com/google/uuid v1.6.0 // indirect 44 | github.com/imdario/mergo v0.3.16 // indirect 45 | github.com/inconshreveable/mousetrap v1.1.0 // indirect 46 | github.com/josharian/intern v1.0.0 // indirect 47 | github.com/json-iterator/go v1.1.12 // indirect 48 | github.com/mailru/easyjson v0.7.7 // indirect 49 | github.com/mattn/go-colorable v0.1.9 // indirect 50 | github.com/mattn/go-isatty v0.0.16 // indirect 51 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 52 | github.com/modern-go/reflect2 v1.0.2 // indirect 53 | github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect 54 | github.com/pkg/errors v0.9.1 // indirect 55 | github.com/pmezard/go-difflib v1.0.0 // indirect 56 | github.com/prometheus/client_golang v1.19.0 // indirect 57 | github.com/prometheus/client_model v0.6.0 // indirect 58 | github.com/prometheus/common v0.51.1 // indirect 59 | github.com/prometheus/procfs v0.13.0 // indirect 60 | github.com/spf13/cobra v1.7.0 // indirect 61 | github.com/spf13/pflag v1.0.5 // indirect 62 | github.com/stretchr/objx v0.5.2 // indirect 63 | go.uber.org/multierr v1.11.0 // indirect 64 | go.uber.org/zap v1.27.0 // indirect 65 | golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 // indirect 66 | golang.org/x/mod v0.16.0 // indirect 67 | golang.org/x/net v0.22.0 // indirect 68 | golang.org/x/oauth2 v0.18.0 // indirect 69 | golang.org/x/sys v0.18.0 // indirect 70 | golang.org/x/term v0.18.0 // indirect 71 | golang.org/x/text v0.14.0 // indirect 72 | golang.org/x/time v0.5.0 // indirect 73 | golang.org/x/tools v0.19.0 // indirect 74 | gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect 75 | google.golang.org/appengine v1.6.8 // indirect 76 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240325203815-454cdb8f5daa // indirect 77 | google.golang.org/grpc v1.62.1 // indirect 78 | google.golang.org/protobuf v1.33.0 // indirect 79 | gopkg.in/inf.v0 v0.9.1 // indirect 80 | gopkg.in/yaml.v2 v2.4.0 // indirect 81 | k8s.io/apiextensions-apiserver v0.29.3 // indirect 82 | k8s.io/component-base v0.29.3 // indirect 83 | k8s.io/klog/v2 v2.120.1 // indirect 84 | k8s.io/kube-openapi v0.0.0-20240322212309-b815d8309940 // indirect 85 | sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect 86 | sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect 87 | sigs.k8s.io/yaml v1.4.0 // indirect 88 | ) 89 | -------------------------------------------------------------------------------- /hack/boilerplate.go.txt: -------------------------------------------------------------------------------- 1 | /* 2 | 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 | */ -------------------------------------------------------------------------------- /hook/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright © 2022 Dell Inc. or its subsidiaries. All Rights Reserved. 3 | # 4 | # This software contains the intellectual property of Dell Inc. 5 | # or is licensed to Dell Inc. from third parties. Use of this software 6 | # and the intellectual property contained therein is expressly limited to the 7 | # terms and conditions of the License Agreement under which it is provided by or 8 | # on behalf of Dell Inc. or its subsidiaries. 9 | 10 | # Dockerfile for csi-baremetal-pre-upgrade-crds 11 | ARG KUBECTL_IMAGE 12 | FROM $KUBECTL_IMAGE 13 | 14 | COPY charts/csi-baremetal-operator/crds /crds 15 | 16 | USER 1000 17 | 18 | ENTRYPOINT ["/bin/sh", "-c"] 19 | -------------------------------------------------------------------------------- /pkg/acrvalidator/acr_validator.go: -------------------------------------------------------------------------------- 1 | package acrvalidator 2 | 3 | import ( 4 | "context" 5 | "strings" 6 | "time" 7 | 8 | "github.com/sirupsen/logrus" 9 | corev1 "k8s.io/api/core/v1" 10 | k8serrors "k8s.io/apimachinery/pkg/api/errors" 11 | "sigs.k8s.io/controller-runtime/pkg/client" 12 | 13 | acrcrd "github.com/dell/csi-baremetal/api/v1/acreservationcrd" 14 | ) 15 | 16 | const ( 17 | ctxTimeout = 30 * time.Second 18 | validationTimeout = 60 * time.Second 19 | ) 20 | 21 | // acrvalidator package implements a watcher, which has to check 22 | // all existing ACRs and remove ones, if they are outdated 23 | // (pods for these ACRs were removed). Stacked volumes may 24 | // lead to races, if they are in RESERVED state (block other 25 | // reservations) or new created pods have the same name. 26 | // It's the workaround until we use scheduler-extender 27 | 28 | // ACRValidator is the watcher to remove outdated ACRs 29 | type ACRValidator struct { 30 | Client client.Client 31 | Log *logrus.Entry 32 | } 33 | 34 | // LauncACRValidation creates an instance of ACRValidator and 35 | // start the infinite loop to validate ACRs by timeout 36 | func LauncACRValidation(client client.Client, log *logrus.Entry) { 37 | validator := &ACRValidator{ 38 | Client: client, 39 | Log: log, 40 | } 41 | 42 | go func() { 43 | for { 44 | time.Sleep(validationTimeout) 45 | validator.validateACRs() 46 | } 47 | }() 48 | } 49 | 50 | func (v *ACRValidator) validateACRs() { 51 | ctx, cancelFn := context.WithTimeout(context.Background(), ctxTimeout) 52 | defer cancelFn() 53 | 54 | acrs := &acrcrd.AvailableCapacityReservationList{} 55 | err := v.Client.List(ctx, acrs) 56 | if err != nil { 57 | v.Log.Errorf("failed to get ACR List: %s", err.Error()) 58 | return 59 | } 60 | 61 | for i, acr := range acrs.Items { 62 | if v.needToRemoveACR(ctx, &acrs.Items[i]) { 63 | v.Log.Infof("Try to delete ACR %s", acr.GetName()) 64 | err := v.Client.Delete(ctx, &acrs.Items[i]) 65 | if err != nil { 66 | v.Log.Errorf("failed to delete ACR %s: %s", acr.GetName(), err.Error()) 67 | } else { 68 | v.Log.Infof("ACR %s was successfully deleted", acr.GetName()) 69 | } 70 | } 71 | } 72 | } 73 | 74 | func (v *ACRValidator) needToRemoveACR(ctx context.Context, acr *acrcrd.AvailableCapacityReservation) bool { 75 | ns, podName := getPodName(acr) 76 | 77 | pod := &corev1.Pod{} 78 | err := v.Client.Get(ctx, client.ObjectKey{Name: podName, Namespace: ns}, pod) 79 | if err != nil && !k8serrors.IsNotFound(err) { 80 | v.Log.Errorf("failed to get pod %s in %s namespace: %s", podName, ns, err.Error()) 81 | return false 82 | } 83 | 84 | // Check if pod was deleted 85 | if k8serrors.IsNotFound(err) { 86 | v.Log.Warnf("ACR %s is no longer actual. Pod %s in %s ns was removed", acr.GetName(), podName, ns) 87 | return true 88 | } 89 | 90 | // Check if pod is Running 91 | if pod.Status.Phase == corev1.PodRunning { 92 | v.Log.Warnf("ACR %s is no longer actual. Pod %s in %s ns is Running", acr.GetName(), podName, ns) 93 | return true 94 | } 95 | 96 | return false 97 | } 98 | 99 | // getPodName returns namespace and pod names for passed acr 100 | // must be synced with https://github.com/dell/csi-baremetal/blob/4c0c38da3cdb57a214e63c8ef1373bff8841db49/pkg/scheduler/extender/extender.go#L356 101 | func getPodName(acr *acrcrd.AvailableCapacityReservation) (string, string) { 102 | namespace := acr.Spec.Namespace 103 | pod := strings.Replace(acr.GetName(), namespace+"-", "", 1) 104 | 105 | return namespace, pod 106 | } 107 | -------------------------------------------------------------------------------- /pkg/acrvalidator/acr_validator_test.go: -------------------------------------------------------------------------------- 1 | package acrvalidator 2 | 3 | import ( 4 | "context" 5 | "github.com/sirupsen/logrus" 6 | "testing" 7 | 8 | "github.com/stretchr/testify/assert" 9 | corev1 "k8s.io/api/core/v1" 10 | k8serrors "k8s.io/apimachinery/pkg/api/errors" 11 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 12 | "sigs.k8s.io/controller-runtime/pkg/client" 13 | "sigs.k8s.io/controller-runtime/pkg/client/fake" 14 | 15 | "github.com/dell/csi-baremetal-operator/pkg/common" 16 | 17 | api "github.com/dell/csi-baremetal/api/generated/v1" 18 | acrcrd "github.com/dell/csi-baremetal/api/v1/acreservationcrd" 19 | ) 20 | 21 | const ( 22 | testNS = "ns" 23 | ) 24 | 25 | var ( 26 | ctx = context.Background() 27 | ) 28 | 29 | func Test_validateACRs(t *testing.T) { 30 | t.Run("Should not delete ACR if pod exists", func(t *testing.T) { 31 | var ( 32 | pod = corev1.Pod{ 33 | ObjectMeta: metav1.ObjectMeta{ 34 | Name: "pod1", 35 | Namespace: testNS, 36 | }, 37 | Status: corev1.PodStatus{ 38 | Phase: corev1.PodPending, 39 | }, 40 | } 41 | acr = acrcrd.AvailableCapacityReservation{ 42 | ObjectMeta: metav1.ObjectMeta{ 43 | Name: getReservationName(&pod), 44 | }, 45 | Spec: api.AvailableCapacityReservation{ 46 | Namespace: testNS, 47 | }, 48 | } 49 | updatedPod = corev1.Pod{} 50 | updatedACR = acrcrd.AvailableCapacityReservation{} 51 | ) 52 | 53 | cv := setupACRValidator(&pod, &acr) 54 | cv.validateACRs() 55 | 56 | err := cv.Client.Get(ctx, client.ObjectKey{Name: pod.Name, Namespace: pod.Namespace}, &updatedPod) 57 | assert.Nil(t, err) 58 | assert.NotNil(t, updatedPod) 59 | 60 | err = cv.Client.Get(ctx, client.ObjectKey{Name: acr.Name}, &updatedACR) 61 | assert.Nil(t, err) 62 | assert.NotNil(t, updatedACR) 63 | }) 64 | 65 | t.Run("Should delete ACR if pod ready", func(t *testing.T) { 66 | var ( 67 | pod = corev1.Pod{ 68 | ObjectMeta: metav1.ObjectMeta{ 69 | Name: "pod1", 70 | Namespace: testNS, 71 | }, 72 | Status: corev1.PodStatus{ 73 | Phase: corev1.PodRunning, 74 | }, 75 | } 76 | acr = acrcrd.AvailableCapacityReservation{ 77 | ObjectMeta: metav1.ObjectMeta{ 78 | Name: getReservationName(&pod), 79 | }, 80 | Spec: api.AvailableCapacityReservation{ 81 | Namespace: testNS, 82 | }, 83 | } 84 | updatedPod = corev1.Pod{} 85 | updatedACR = acrcrd.AvailableCapacityReservation{} 86 | ) 87 | 88 | cv := setupACRValidator(&pod, &acr) 89 | cv.validateACRs() 90 | 91 | err := cv.Client.Get(ctx, client.ObjectKey{Name: pod.Name, Namespace: pod.Namespace}, &updatedPod) 92 | assert.Nil(t, err) 93 | assert.NotNil(t, updatedPod) 94 | 95 | err = cv.Client.Get(ctx, client.ObjectKey{Name: acr.Name, Namespace: ""}, &updatedACR) 96 | assert.NotNil(t, err) 97 | assert.True(t, k8serrors.IsNotFound(err)) 98 | }) 99 | 100 | t.Run("Should delete ACR if pod removed", func(t *testing.T) { 101 | var ( 102 | pod = corev1.Pod{ 103 | ObjectMeta: metav1.ObjectMeta{ 104 | Name: "pod1", 105 | Namespace: testNS, 106 | }, 107 | } 108 | acr = acrcrd.AvailableCapacityReservation{ 109 | ObjectMeta: metav1.ObjectMeta{ 110 | Name: getReservationName(&pod), 111 | }, 112 | Spec: api.AvailableCapacityReservation{ 113 | Namespace: testNS, 114 | }, 115 | } 116 | updatedACR = acrcrd.AvailableCapacityReservation{} 117 | ) 118 | 119 | cv := setupACRValidator(&acr) 120 | cv.validateACRs() 121 | 122 | err := cv.Client.Get(ctx, client.ObjectKey{Name: acr.Name, Namespace: ""}, &updatedACR) 123 | assert.NotNil(t, err) 124 | assert.True(t, k8serrors.IsNotFound(err)) 125 | }) 126 | } 127 | 128 | func setupACRValidator(objects ...client.Object) *ACRValidator { 129 | scheme, _ := common.PrepareScheme() 130 | builder := fake.ClientBuilder{} 131 | builderWithScheme := builder.WithScheme(scheme) 132 | client := builderWithScheme.WithObjects(objects...).Build() 133 | 134 | return &ACRValidator{ 135 | Client: client, 136 | Log: logrus.New().WithField("component", "ACRValidatorTest"), 137 | } 138 | } 139 | 140 | func getReservationName(pod *corev1.Pod) string { 141 | namespace := pod.Namespace 142 | if namespace == "" { 143 | namespace = "default" 144 | } 145 | 146 | return namespace + "-" + pod.Name 147 | } 148 | -------------------------------------------------------------------------------- /pkg/common/common_test.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/dell/csi-baremetal-operator/api/v1/components" 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | func Test_MatchLogLevel(t *testing.T) { 11 | tests := []struct { 12 | level components.Level 13 | expected string 14 | }{ 15 | { 16 | level: components.InfoLevel, 17 | expected: "info", 18 | }, 19 | { 20 | level: components.DebugLevel, 21 | expected: "debug", 22 | }, 23 | { 24 | level: components.TraceLevel, 25 | expected: "trace", 26 | }, 27 | { 28 | level: "unknown", 29 | expected: "info", 30 | }, 31 | } 32 | 33 | for _, tt := range tests { 34 | t.Run("Check log level "+string(tt.level), func(t *testing.T) { 35 | assert.Equal(t, string(tt.expected), MatchLogLevel(tt.level)) 36 | }) 37 | } 38 | } 39 | 40 | func Test_MatchFormat(t *testing.T) { 41 | tests := []struct { 42 | format components.Format 43 | expectedFormat string 44 | }{ 45 | { 46 | format: components.JSONFormat, 47 | expectedFormat: "json", 48 | }, 49 | { 50 | format: components.TextFormat, 51 | expectedFormat: "text", 52 | }, 53 | { 54 | format: "unknown", 55 | expectedFormat: "text", 56 | }, 57 | } 58 | 59 | for _, tt := range tests { 60 | t.Run("Check formats "+string(tt.format), func(t *testing.T) { 61 | assert.Equal(t, string(tt.expectedFormat), MatchLogFormat(tt.format)) 62 | }) 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /pkg/constant/const.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2021 Dell Inc. or its subsidiaries. All Rights Reserved. 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 ( 20 | corev1 "k8s.io/api/core/v1" 21 | ) 22 | 23 | const ( 24 | // CSIName - default prefix 25 | CSIName = "csi-baremetal" 26 | // ComponentName - is the name of component 27 | ComponentName = CSIName + "-operator" 28 | 29 | // PrometheusPort - default prometeus port 30 | PrometheusPort = 8787 31 | // LivenessPort - default liveness port 32 | LivenessPort = "liveness-port" 33 | 34 | // TerminationGracePeriodSeconds - default termination timeout 35 | TerminationGracePeriodSeconds = 10 36 | 37 | // LogsVolume - default volume for logs 38 | LogsVolume = "logs" 39 | // CSISocketDirVolume - default volume of CSI socket 40 | CSISocketDirVolume = "csi-socket-dir" 41 | 42 | // TerminationMessagePath - default path for saving termination message 43 | TerminationMessagePath = "/var/log/termination-log" 44 | // TerminationMessagePolicy - default policy 45 | TerminationMessagePolicy = corev1.TerminationMessageReadFile 46 | 47 | // ProvisionerName - name of csi-provisioner sidecar 48 | ProvisionerName = "csi-provisioner" 49 | // ResizerName - name of csi-resizer sidecar 50 | ResizerName = "csi-resizer" 51 | // DriverRegistrarName - name of csi-node-driver-registrar sidecar 52 | DriverRegistrarName = "csi-node-driver-registrar" 53 | // LivenessProbeName - name of livenessprobe sidecar 54 | LivenessProbeName = "livenessprobe" 55 | 56 | // AppLabelKey matches CSI CRs with csi-baremetal app 57 | AppLabelKey = "app.kubernetes.io/name" 58 | // AppLabelShortKey matches CSI CRs with csi-baremetal app 59 | AppLabelShortKey = "app" 60 | // ComponentLabelKey matches CSI CRs with csi-baremetal component 61 | ComponentLabelKey = "app.kubernetes.io/component" 62 | // ComponentLabelShortKey matches CSI CRs with csi-baremetal component 63 | ComponentLabelShortKey = "component" 64 | // AppLabelValue matches CSI CRs with csi-baremetal app 65 | AppLabelValue = CSIName 66 | 67 | // SelectorKey is a key for Deployments/Daemonsets selector 68 | SelectorKey = "name" 69 | // RsysLabelKey are used for directory layout in rsyslog 70 | RsysLabelKey = "app.kubernetes.io/instance" 71 | // DefaultNamespace is the default namespace 72 | DefaultNamespace = "default" 73 | // LogLevelSlogan parameter definition 74 | LogLevelSlogan = "--loglevel=" 75 | ) 76 | 77 | var ( 78 | // CrashVolume - the volume for crush dumps 79 | CrashVolume = corev1.Volume{ 80 | Name: "crash-dump", 81 | VolumeSource: corev1.VolumeSource{ 82 | EmptyDir: &corev1.EmptyDirVolumeSource{}, 83 | }} 84 | 85 | // CrashMountVolume - the mount point for CrashVolume 86 | CrashMountVolume = corev1.VolumeMount{ 87 | Name: "crash-dump", MountPath: "/crash-dump", 88 | } 89 | ) 90 | -------------------------------------------------------------------------------- /pkg/constant/platforms.go: -------------------------------------------------------------------------------- 1 | package constant 2 | 3 | const ( 4 | // PlatformVanilla - vanilla platform key 5 | PlatformVanilla = "vanilla" 6 | // PlatformRKE - RKE platform key 7 | PlatformRKE = "rke" 8 | // PlatformOpenShift - openshift platform key 9 | PlatformOpenShift = "openshift" 10 | ) 11 | -------------------------------------------------------------------------------- /pkg/controller_test.go: -------------------------------------------------------------------------------- 1 | package pkg 2 | 3 | 4 | import ( 5 | "context" 6 | "testing" 7 | 8 | "github.com/sirupsen/logrus" 9 | "github.com/stretchr/testify/assert" 10 | "k8s.io/client-go/kubernetes" 11 | 12 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 13 | v1 "github.com/dell/csi-baremetal-operator/api/v1" 14 | "github.com/dell/csi-baremetal-operator/api/v1/components" 15 | "github.com/dell/csi-baremetal-operator/pkg/common" 16 | "github.com/dell/csi-baremetal-operator/pkg/constant" 17 | ) 18 | 19 | var ( 20 | logControllerEntry = logrus.WithField("Test name", "NodeTest") 21 | testControllerDeployment = v1.Deployment{ 22 | ObjectMeta: metav1.ObjectMeta{ 23 | Name: "test-deployment", 24 | Namespace: "test-csi", 25 | }, 26 | Spec: components.DeploymentSpec{ 27 | Driver: &components.Driver{ 28 | Controller: &components.Controller{ 29 | Sidecars: map[string]*components.Sidecar{ 30 | "csi-provisioner": { 31 | Image: &components.Image{ 32 | Name: "provisioner", 33 | }, 34 | Args: &components.Args{ 35 | Timeout: "60", 36 | RetryIntervalStart: "20", 37 | RetryIntervalMax: "30", 38 | WorkerThreads: 1, 39 | }, 40 | }, 41 | "csi-resizer": { 42 | Image: &components.Image{ 43 | Name: "resizer", 44 | }, 45 | Args: &components.Args{ 46 | Timeout: "60", 47 | RetryIntervalStart: "20", 48 | RetryIntervalMax: "30", 49 | WorkerThreads: 1, 50 | }, 51 | }, 52 | "livenessprobe": { 53 | Image: &components.Image{ 54 | Name: "livenessprobe", 55 | }, 56 | Args: &components.Args{ 57 | Timeout: "60", 58 | RetryIntervalStart: "20", 59 | RetryIntervalMax: "30", 60 | WorkerThreads: 1, 61 | }, 62 | }, 63 | }, 64 | Image: &components.Image{ 65 | Name: "test", 66 | }, 67 | Log: &components.Log{ 68 | Level: "debug", 69 | }, 70 | }, 71 | }, 72 | Platform: constant.PlatformOpenShift, 73 | GlobalRegistry: "asdrepo.isus.emc.com:9042", 74 | RegistrySecret: "test-registry-secret", 75 | }, 76 | } 77 | 78 | ) 79 | 80 | func Test_Update_Controller(t *testing.T) { 81 | t.Run("Update", func(t *testing.T) { 82 | var ( 83 | ctx = context.Background() 84 | deployment = testControllerDeployment.DeepCopy() 85 | ) 86 | scheme, _ := common.PrepareScheme() 87 | controller := prepareController(prepareNodeClientSet()) 88 | err := controller.Update(ctx, deployment, scheme) 89 | assert.Nil(t, err) 90 | }) 91 | } 92 | 93 | func prepareController(clientSet kubernetes.Interface) *Controller { 94 | return &Controller{ 95 | Clientset: clientSet, 96 | Entry: logControllerEntry, 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /pkg/feature/security_verifier/error.go: -------------------------------------------------------------------------------- 1 | package securityverifier 2 | 3 | import "fmt" 4 | 5 | // Error is a custom security verifier error type 6 | type Error interface { 7 | error 8 | OrigError() error 9 | } 10 | 11 | type verifierError struct { 12 | message string 13 | } 14 | 15 | func (r *verifierError) OrigError() error { 16 | return fmt.Errorf(r.message) 17 | } 18 | 19 | func (r *verifierError) Error() string { 20 | return fmt.Sprintf("failed to verify: %s", r.message) 21 | } 22 | 23 | // NewVerifierError is a constructor for security verifier error 24 | func NewVerifierError(message string) Error { 25 | return &verifierError{ 26 | message: message, 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /pkg/feature/security_verifier/interface.go: -------------------------------------------------------------------------------- 1 | package securityverifier 2 | 3 | import ( 4 | "context" 5 | 6 | csibaremetalv1 "github.com/dell/csi-baremetal-operator/api/v1" 7 | "github.com/dell/csi-baremetal-operator/pkg/feature/security_verifier/models" 8 | ) 9 | 10 | // SecurityVerifier is an interface, describing security verifiers 11 | type SecurityVerifier interface { 12 | Verify(ctx context.Context, csi *csibaremetalv1.Deployment, component models.Component) error 13 | HandleError(ctx context.Context, csi *csibaremetalv1.Deployment, serviceAccount string, err error) error 14 | } 15 | -------------------------------------------------------------------------------- /pkg/feature/security_verifier/models/components.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | // Component is a component name, for which security verification will be applied 4 | type Component string 5 | 6 | var ( 7 | // Node represents the node component 8 | Node Component = "Node" 9 | // Scheduler represents the scheduler extender component 10 | Scheduler Component = "Scheduler" 11 | ) 12 | -------------------------------------------------------------------------------- /pkg/feature/security_verifier/pod_security_policy.go: -------------------------------------------------------------------------------- 1 | package securityverifier 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "fmt" 7 | 8 | "github.com/dell/csi-baremetal/pkg/eventing" 9 | "github.com/dell/csi-baremetal/pkg/events" 10 | "github.com/sirupsen/logrus" 11 | rbacv1 "k8s.io/api/rbac/v1" 12 | 13 | csibaremetalv1 "github.com/dell/csi-baremetal-operator/api/v1" 14 | verifierModels "github.com/dell/csi-baremetal-operator/pkg/feature/security_verifier/models" 15 | "github.com/dell/csi-baremetal-operator/pkg/validator" 16 | validatorModels "github.com/dell/csi-baremetal-operator/pkg/validator/models" 17 | "github.com/dell/csi-baremetal-operator/pkg/validator/rbac" 18 | rbacModels "github.com/dell/csi-baremetal-operator/pkg/validator/rbac/models" 19 | ) 20 | 21 | type podSecurityPolicyVerifier struct { 22 | validator validator.Validator 23 | eventRecorder events.EventRecorder 24 | matchPolicyTemplate rbacv1.PolicyRule 25 | log *logrus.Entry 26 | } 27 | 28 | func (v *podSecurityPolicyVerifier) Verify(ctx context.Context, csi *csibaremetalv1.Deployment, component verifierModels.Component) error { 29 | var serviceAccount string 30 | var policyRule = v.matchPolicyTemplate 31 | switch component { 32 | case verifierModels.Node: 33 | policyRule.ResourceNames = []string{csi.Spec.Driver.Node.PodSecurityPolicy.ResourceName} 34 | serviceAccount = csi.Spec.Driver.Node.ServiceAccount 35 | case verifierModels.Scheduler: 36 | policyRule.ResourceNames = []string{csi.Spec.Scheduler.PodSecurityPolicy.ResourceName} 37 | serviceAccount = csi.Spec.Scheduler.ServiceAccount 38 | default: 39 | return fmt.Errorf("unknown component was passed") 40 | } 41 | 42 | return v.validator.ValidateRBAC(ctx, &validatorModels.RBACRules{ 43 | Data: &rbacModels.ServiceAccountIsRoleBoundData{ 44 | ServiceAccountName: serviceAccount, 45 | Namespace: csi.Namespace, 46 | Role: &rbacv1.Role{ 47 | Rules: []rbacv1.PolicyRule{policyRule}, 48 | }, 49 | }, 50 | Type: validatorModels.ServiceAccountIsRoleBound, 51 | }) 52 | } 53 | 54 | func (v *podSecurityPolicyVerifier) HandleError(_ context.Context, csi *csibaremetalv1.Deployment, serviceAccount string, err error) error { 55 | var rbacError rbac.Error 56 | if errors.As(err, &rbacError) { 57 | v.eventRecorder.Eventf(csi, eventing.WarningType, "PodSecurityPolicyVerificationFailed", 58 | "ServiceAccount %s has insufficient pod security policies, should have privileged", 59 | serviceAccount) 60 | v.log.Warning(rbacError, "Service account has insufficient pod security policies, should have privileged") 61 | return NewVerifierError("Service account has insufficient pod security policies, should have privileged") 62 | } 63 | v.log.Error(err, "Error occurred while validating service account pod security policies bindings") 64 | return err 65 | } 66 | 67 | // NewPodSecurityPolicyVerifier is a constructor for pod security policies verifier 68 | func NewPodSecurityPolicyVerifier( 69 | validator validator.Validator, 70 | eventRecorder events.EventRecorder, 71 | matchPolicyTemplate rbacv1.PolicyRule, 72 | log *logrus.Entry, 73 | ) SecurityVerifier { 74 | return &podSecurityPolicyVerifier{ 75 | validator: validator, 76 | eventRecorder: eventRecorder, 77 | matchPolicyTemplate: matchPolicyTemplate, 78 | log: log, 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /pkg/feature/security_verifier/security_context_constraints.go: -------------------------------------------------------------------------------- 1 | package securityverifier 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "fmt" 7 | 8 | "github.com/dell/csi-baremetal/pkg/eventing" 9 | "github.com/dell/csi-baremetal/pkg/events" 10 | "github.com/sirupsen/logrus" 11 | rbacv1 "k8s.io/api/rbac/v1" 12 | 13 | csibaremetalv1 "github.com/dell/csi-baremetal-operator/api/v1" 14 | verifierModels "github.com/dell/csi-baremetal-operator/pkg/feature/security_verifier/models" 15 | "github.com/dell/csi-baremetal-operator/pkg/validator" 16 | validatorModels "github.com/dell/csi-baremetal-operator/pkg/validator/models" 17 | "github.com/dell/csi-baremetal-operator/pkg/validator/rbac" 18 | rbacModels "github.com/dell/csi-baremetal-operator/pkg/validator/rbac/models" 19 | ) 20 | 21 | type securityContextConstraintsVerifier struct { 22 | validator validator.Validator 23 | eventRecorder events.EventRecorder 24 | matchPolicies []rbacv1.PolicyRule 25 | log *logrus.Entry 26 | } 27 | 28 | func (v *securityContextConstraintsVerifier) Verify(ctx context.Context, csi *csibaremetalv1.Deployment, component verifierModels.Component) error { 29 | var serviceAccount string 30 | switch component { 31 | case verifierModels.Node: 32 | serviceAccount = csi.Spec.Driver.Node.ServiceAccount 33 | case verifierModels.Scheduler: 34 | serviceAccount = csi.Spec.Scheduler.ServiceAccount 35 | default: 36 | return fmt.Errorf("unknown component was passed") 37 | } 38 | 39 | return v.validator.ValidateRBAC(ctx, &validatorModels.RBACRules{ 40 | Data: &rbacModels.ServiceAccountIsRoleBoundData{ 41 | ServiceAccountName: serviceAccount, 42 | Namespace: csi.Namespace, 43 | Role: &rbacv1.Role{ 44 | Rules: v.matchPolicies, 45 | }, 46 | }, 47 | Type: validatorModels.ServiceAccountIsRoleBound, 48 | }) 49 | } 50 | 51 | func (v *securityContextConstraintsVerifier) HandleError(_ context.Context, csi *csibaremetalv1.Deployment, serviceAccount string, err error) error { 52 | var rbacError rbac.Error 53 | if errors.As(err, &rbacError) { 54 | v.eventRecorder.Eventf(csi, eventing.WarningType, "SecurityContextConstraintsVerificationFailed", 55 | "ServiceAccount %s has insufficient securityContextConstraints, should have privileged", 56 | serviceAccount) 57 | v.log.Warning(rbacError, "Service account has insufficient securityContextConstraints, should have privileged") 58 | return NewVerifierError("Service account has insufficient securityContextConstraints, should have privileged") 59 | } 60 | v.log.Error(err, "Error occurred while validating service account security context bindings") 61 | return err 62 | } 63 | 64 | // NewSecurityContextConstraintsVerifier is a constructor for security context constraints verifier 65 | func NewSecurityContextConstraintsVerifier( 66 | validator validator.Validator, 67 | eventRecorder events.EventRecorder, 68 | matchPolicies []rbacv1.PolicyRule, 69 | log *logrus.Entry, 70 | ) SecurityVerifier { 71 | return &securityContextConstraintsVerifier{ 72 | validator: validator, 73 | eventRecorder: eventRecorder, 74 | matchPolicies: matchPolicies, 75 | log: log, 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /pkg/imports/imports.go: -------------------------------------------------------------------------------- 1 | //go:build imports 2 | // +build imports 3 | 4 | /* 5 | Copyright © 2022 Dell Inc. or its subsidiaries. All Rights Reserved. 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | http://www.apache.org/licenses/LICENSE-2.0 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 imports contains extra dependencies to keep it in go.mod 18 | package imports 19 | 20 | import ( 21 | // import controller-tools for controller-gen binary 22 | // allows to generate CRD from Go structs 23 | _ "sigs.k8s.io/controller-tools/cmd/controller-gen" 24 | ) 25 | -------------------------------------------------------------------------------- /pkg/node/parser.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2021 Dell Inc. or its subsidiaries. All Rights Reserved. 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 node 18 | 19 | import ( 20 | "errors" 21 | "regexp" 22 | "strings" 23 | 24 | "github.com/masterminds/semver" 25 | corev1 "k8s.io/api/core/v1" 26 | ) 27 | 28 | // GetOSNameAndVersion receives string with the OS information in th following format: 29 | // " ". For example, "Ubuntu 18.04.4 LTS" 30 | // returns os name with the lower case and major and minor version. For example, "ubuntu", "18.04" 31 | func GetOSNameAndVersion(osInfo string) (name, version string, err error) { 32 | // check input parameter 33 | if len(osInfo) == 0 { 34 | return "", "", errors.New("errorEmptyParameter") 35 | } 36 | 37 | // extract OS name 38 | name = regexp.MustCompile(`^[A-Za-z]+`).FindString(osInfo) 39 | if len(name) == 0 { 40 | return "", "", errors.New("errorEmptyParameter") 41 | } 42 | 43 | // extract OS version 44 | version = regexp.MustCompile(`[0-9]+\.[0-9]+`).FindString(osInfo) 45 | if len(version) == 0 { 46 | return "", "", errors.New("errorEmptyParameter") 47 | } 48 | 49 | return strings.ToLower(name), version, nil 50 | } 51 | 52 | // GetKernelVersion receives string with the kernel version information in the following format: 53 | // "X.Y.Z--". For example, "5.4.0-66-generic" 54 | // returns kernel version - major and minor. For example, "5.4" 55 | func GetKernelVersion(kernelVersion string) (version *semver.Version, err error) { 56 | if len(kernelVersion) == 0 { 57 | return nil, errors.New("errorEmptyParameter") 58 | } 59 | 60 | // extract kernel version - x.y.z 61 | versionStr := regexp.MustCompile(`^[0-9]+\.[0-9]+`).FindString(kernelVersion) 62 | return semver.NewVersion(versionStr) 63 | } 64 | 65 | // GetNodeKernelVersion returns kernel version of Node 66 | func GetNodeKernelVersion(node *corev1.Node) (version *semver.Version, err error) { 67 | return GetKernelVersion(node.Status.NodeInfo.KernelVersion) 68 | } 69 | -------------------------------------------------------------------------------- /pkg/node/parser_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2021 Dell Inc. or its subsidiaries. All Rights Reserved. 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 node 18 | 19 | import ( 20 | "testing" 21 | 22 | "github.com/stretchr/testify/assert" 23 | ) 24 | 25 | func TestGetOSNameAndVersion(t *testing.T) { 26 | name, version, err := GetOSNameAndVersion("") 27 | assert.NotNil(t, err) 28 | assert.Equal(t, name, "") 29 | assert.Equal(t, version, "") 30 | 31 | name, version, err = GetOSNameAndVersion("Wrong OS") 32 | assert.NotNil(t, err) 33 | assert.Equal(t, name, "") 34 | assert.Equal(t, version, "") 35 | 36 | name, version, err = GetOSNameAndVersion("12.04") 37 | assert.NotNil(t, err) 38 | assert.Equal(t, name, "") 39 | assert.Equal(t, version, "") 40 | 41 | name, version, err = GetOSNameAndVersion("Ubuntu 18.04.4 LTS") 42 | assert.Equal(t, err, nil) 43 | assert.Equal(t, name, "ubuntu") 44 | assert.Equal(t, version, "18.04") 45 | 46 | name, version, err = GetOSNameAndVersion("Ubuntu 19.10") 47 | assert.Equal(t, err, nil) 48 | assert.Equal(t, name, "ubuntu") 49 | assert.Equal(t, version, "19.10") 50 | 51 | // OpenShift has the following output for OS Image 52 | name, version, err = GetOSNameAndVersion("Red Hat Enterprise Linux CoreOS 46.82.202101301821-0 (Ootpa)") 53 | assert.Equal(t, err, nil) 54 | assert.Equal(t, name, "red") 55 | assert.Equal(t, version, "46.82") 56 | } 57 | 58 | func TestGetKernelVersion(t *testing.T) { 59 | _, err := GetKernelVersion("") 60 | assert.NotNil(t, err) 61 | 62 | _, err = GetKernelVersion("bla-bla") 63 | assert.NotNil(t, err) 64 | 65 | // ubuntu 19 66 | testSupportedKernel := "5.4" 67 | testSupportedKernelVersion, err := GetKernelVersion(testSupportedKernel) 68 | assert.Equal(t, err, nil) 69 | 70 | // ubuntu 19 71 | newKernel1 := "5.4.0-66-generic" 72 | newKernel1Version, err := GetKernelVersion(newKernel1) 73 | assert.Equal(t, err, nil) 74 | // ubuntu 21 75 | newKernel2 := "5.12.13-051213-generic" 76 | newKernel2Version, err := GetKernelVersion(newKernel2) 77 | assert.Equal(t, err, nil) 78 | 79 | // ubuntu 18 80 | oldKernel1 := "4.15.0-76-generic" 81 | oldKernel1Version, err := GetKernelVersion(oldKernel1) 82 | assert.Equal(t, err, nil) 83 | // rhel coreos 4.6 84 | oldKernel2 := "4.18.0-193.41.1.el8_2.x86_64" 85 | oldKernel2Version, err := GetKernelVersion(oldKernel2) 86 | assert.Equal(t, err, nil) 87 | 88 | assert.True(t, greaterOrEqual(testSupportedKernelVersion, testSupportedKernelVersion)) 89 | assert.True(t, greaterOrEqual(newKernel1Version, testSupportedKernelVersion)) 90 | assert.True(t, greaterOrEqual(newKernel2Version, testSupportedKernelVersion)) 91 | 92 | assert.False(t, greaterOrEqual(oldKernel1Version, testSupportedKernelVersion)) 93 | assert.False(t, greaterOrEqual(oldKernel2Version, testSupportedKernelVersion)) 94 | } 95 | -------------------------------------------------------------------------------- /pkg/node/platform_description.go: -------------------------------------------------------------------------------- 1 | package node 2 | 3 | import ( 4 | "github.com/dell/csi-baremetal-operator/api/v1/components" 5 | "github.com/masterminds/semver" 6 | ) 7 | 8 | const ( 9 | supportedKernel = "5.4" 10 | defaultPlatform = "default" 11 | ) 12 | 13 | var supportedKernelVersion = semver.MustParse(supportedKernel) 14 | 15 | // PlatformDescription contains info to deploy specific node daemonsets 16 | // tag - the prefix for daemonset and image: csi-baremetal-node- 17 | // labeltag - label for node selctor 18 | // checkVersion - func to match related version 19 | type PlatformDescription struct { 20 | tag string 21 | labeltag string 22 | checkVersion 23 | } 24 | 25 | type checkVersion func(version *semver.Version) bool 26 | 27 | var ( 28 | platforms = map[string]*PlatformDescription{ 29 | "default": { 30 | tag: "", 31 | labeltag: defaultPlatform, 32 | // default checkVersion returns false everytime to detect only specific platforms 33 | checkVersion: func(version *semver.Version) bool { return false }, 34 | }, 35 | "kernel-5.4": { 36 | tag: "kernel-5.4", 37 | labeltag: "kernel-5.4", 38 | checkVersion: func(version *semver.Version) bool { return greaterOrEqual(version, supportedKernelVersion) }, 39 | }, 40 | } 41 | ) 42 | 43 | // DaemonsetName constructs name of daemonset based on tag 44 | func (pd *PlatformDescription) DaemonsetName(baseName string) string { 45 | return createNameWithTag(baseName, pd.tag) 46 | } 47 | 48 | // NodeImage constructs name of image based on tag and updates Image 49 | func (pd *PlatformDescription) NodeImage(baseImage *components.Image) *components.Image { 50 | var taggedImage = components.Image{} 51 | 52 | taggedImage.Tag = baseImage.Tag 53 | taggedImage.Name = createNameWithTag(baseImage.Name, pd.tag) 54 | 55 | return &taggedImage 56 | } 57 | 58 | // findPlatform calls checkVersion for all platforms in list, 59 | // returns first found platform-name or "default" if no one passed 60 | func findPlatform(kernelVersion *semver.Version) string { 61 | for key, value := range platforms { 62 | if value.checkVersion(kernelVersion) { 63 | return key 64 | } 65 | } 66 | 67 | return defaultPlatform 68 | } 69 | 70 | func createNameWithTag(name, tag string) string { 71 | if tag != "" { 72 | return name + "-" + tag 73 | } 74 | 75 | return name 76 | } 77 | 78 | // greaterOrEqual returns true if version >= supported 79 | func greaterOrEqual(version *semver.Version, supported *semver.Version) bool { 80 | return !version.LessThan(supported) 81 | } 82 | -------------------------------------------------------------------------------- /pkg/node_controller.go: -------------------------------------------------------------------------------- 1 | package pkg 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/sirupsen/logrus" 7 | v1 "k8s.io/api/apps/v1" 8 | corev1 "k8s.io/api/core/v1" 9 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 10 | "k8s.io/apimachinery/pkg/runtime" 11 | "k8s.io/client-go/kubernetes" 12 | "k8s.io/utils/ptr" 13 | "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" 14 | 15 | csibaremetalv1 "github.com/dell/csi-baremetal-operator/api/v1" 16 | "github.com/dell/csi-baremetal-operator/pkg/common" 17 | "github.com/dell/csi-baremetal-operator/pkg/constant" 18 | ) 19 | 20 | const ( 21 | nodeController = "node-controller" 22 | nodeControllerName = constant.CSIName + "-" + nodeController 23 | ncReplicasCount = 1 24 | 25 | nodeControllerServiceAccountName = "csi-node-controller-sa" 26 | ) 27 | 28 | // NodeController controls csi-baremetal-node-controller 29 | type NodeController struct { 30 | Clientset kubernetes.Interface 31 | *logrus.Entry 32 | } 33 | 34 | // Update updates csi-baremetal-node-controller or creates if not found 35 | func (nc *NodeController) Update(ctx context.Context, csi *csibaremetalv1.Deployment, scheme *runtime.Scheme) error { 36 | // create deployment 37 | expected := createNodeControllerDeployment(csi) 38 | if err := controllerutil.SetControllerReference(csi, expected, scheme); err != nil { 39 | return err 40 | } 41 | 42 | if err := common.UpdateDeployment(ctx, nc.Clientset, expected, nc.Entry); err != nil { 43 | return err 44 | } 45 | 46 | return nil 47 | } 48 | 49 | func createNodeControllerDeployment(csi *csibaremetalv1.Deployment) *v1.Deployment { 50 | return &v1.Deployment{ 51 | ObjectMeta: metav1.ObjectMeta{ 52 | Name: nodeControllerName, 53 | Namespace: csi.GetNamespace(), 54 | Labels: common.ConstructLabelAppMap(), 55 | }, 56 | Spec: v1.DeploymentSpec{ 57 | Replicas: ptr.To(int32(ncReplicasCount)), 58 | // selector 59 | Selector: &metav1.LabelSelector{ 60 | MatchLabels: common.ConstructSelectorMap(nodeControllerName), 61 | }, 62 | // template 63 | Template: corev1.PodTemplateSpec{ 64 | ObjectMeta: metav1.ObjectMeta{ 65 | // labels 66 | Labels: common.ConstructLabelMap(nodeControllerName, nodeController), 67 | }, 68 | Spec: corev1.PodSpec{ 69 | Containers: createNodeControllerContainers(csi), 70 | RestartPolicy: corev1.RestartPolicyAlways, 71 | DNSPolicy: corev1.DNSClusterFirst, 72 | TerminationGracePeriodSeconds: ptr.To(int64(constant.TerminationGracePeriodSeconds)), 73 | ServiceAccountName: nodeControllerServiceAccountName, 74 | DeprecatedServiceAccount: nodeControllerServiceAccountName, 75 | ImagePullSecrets: common.MakeImagePullSecrets(csi.Spec.RegistrySecret), 76 | SecurityContext: &corev1.PodSecurityContext{}, 77 | SchedulerName: corev1.DefaultSchedulerName, 78 | Volumes: []corev1.Volume{constant.CrashVolume}, 79 | }, 80 | }, 81 | }, 82 | } 83 | } 84 | 85 | func createNodeControllerContainers(csi *csibaremetalv1.Deployment) []corev1.Container { 86 | var ( 87 | image = csi.Spec.NodeController.Image 88 | log = csi.Spec.NodeController.Log 89 | resources = csi.Spec.NodeController.Resources 90 | ns = csi.Spec.NodeSelector 91 | ) 92 | 93 | args := []string{ 94 | "--namespace=$(NAMESPACE)", 95 | constant.LogLevelSlogan + common.MatchLogLevel(log.Level), 96 | "--logformat=" + common.MatchLogFormat(log.Format), 97 | } 98 | if ns != nil { 99 | args = append(args, "--nodeselector="+ns.Key+":"+ns.Value) 100 | } 101 | return []corev1.Container{ 102 | { 103 | Name: nodeController, 104 | Image: common.ConstructFullImageName(image, csi.Spec.GlobalRegistry), 105 | ImagePullPolicy: corev1.PullPolicy(csi.Spec.PullPolicy), 106 | Args: args, 107 | Env: []corev1.EnvVar{ 108 | {Name: "NAMESPACE", ValueFrom: &corev1.EnvVarSource{ 109 | FieldRef: &corev1.ObjectFieldSelector{APIVersion: "v1", FieldPath: "metadata.namespace"}, 110 | }}, 111 | }, 112 | TerminationMessagePath: constant.TerminationMessagePath, 113 | TerminationMessagePolicy: constant.TerminationMessagePolicy, 114 | VolumeMounts: []corev1.VolumeMount{constant.CrashMountVolume}, 115 | Resources: common.ConstructResourceRequirements(resources), 116 | }, 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /pkg/node_controller_test.go: -------------------------------------------------------------------------------- 1 | package pkg 2 | 3 | 4 | import ( 5 | "context" 6 | "testing" 7 | 8 | "github.com/sirupsen/logrus" 9 | "github.com/stretchr/testify/assert" 10 | "k8s.io/apimachinery/pkg/runtime" 11 | "k8s.io/client-go/kubernetes" 12 | "k8s.io/client-go/kubernetes/fake" 13 | 14 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 15 | v1 "github.com/dell/csi-baremetal-operator/api/v1" 16 | "github.com/dell/csi-baremetal-operator/api/v1/components" 17 | "github.com/dell/csi-baremetal-operator/pkg/common" 18 | "github.com/dell/csi-baremetal-operator/pkg/constant" 19 | ) 20 | 21 | var ( 22 | logEntry = logrus.WithField("Test name", "NodeTest") 23 | testDeployment = v1.Deployment{ 24 | ObjectMeta: metav1.ObjectMeta{ 25 | Name: "test-deployment", 26 | Namespace: "test-csi", 27 | }, 28 | Spec: components.DeploymentSpec{ 29 | Driver: &components.Driver{ 30 | Node: &components.Node{ 31 | ServiceAccount: "csi-node-sa", 32 | PodSecurityPolicy: &components.PodSecurityPolicy{ 33 | Enable: true, 34 | ResourceName: "privileged", 35 | }, 36 | }, 37 | }, 38 | Platform: constant.PlatformOpenShift, 39 | GlobalRegistry: "asdrepo.isus.emc.com:9042", 40 | RegistrySecret: "test-registry-secret", 41 | NodeController: &components.NodeController{ 42 | Enable: true, 43 | Log: &components.Log{ 44 | Level: "debug", 45 | }, 46 | Image: &components.Image{ 47 | Name: "test", 48 | }, 49 | }, 50 | }, 51 | } 52 | ) 53 | func Test_Update_Node_Controller(t *testing.T) { 54 | t.Run("Update", func(t *testing.T) { 55 | var ( 56 | ctx = context.Background() 57 | deployment = testDeployment.DeepCopy() 58 | ) 59 | scheme, _ := common.PrepareScheme() 60 | node := prepareNode(prepareNodeClientSet()) 61 | err := node.Update(ctx, deployment, scheme) 62 | assert.Nil(t, err) 63 | }) 64 | } 65 | 66 | func prepareNode(clientSet kubernetes.Interface) *NodeController { 67 | return &NodeController{ 68 | Clientset: clientSet, 69 | Entry: logEntry, 70 | } 71 | } 72 | 73 | func prepareNodeClientSet(objects ...runtime.Object) kubernetes.Interface { 74 | return fake.NewSimpleClientset(objects...) 75 | } 76 | -------------------------------------------------------------------------------- /pkg/nodeoperations/delete_objects.go: -------------------------------------------------------------------------------- 1 | package nodeoperations 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "strings" 7 | 8 | "sigs.k8s.io/controller-runtime/pkg/client" 9 | 10 | accrd "github.com/dell/csi-baremetal/api/v1/availablecapacitycrd" 11 | "github.com/dell/csi-baremetal/api/v1/drivecrd" 12 | "github.com/dell/csi-baremetal/api/v1/lvgcrd" 13 | "github.com/dell/csi-baremetal/api/v1/nodecrd" 14 | "github.com/dell/csi-baremetal/api/v1/volumecrd" 15 | ) 16 | 17 | func (c *Controller) deleteCSIResources(ctx context.Context, csibmnode *nodecrd.Node) error { 18 | var ( 19 | errors []string 20 | nodeID = csibmnode.Spec.UUID 21 | ) 22 | 23 | if err := c.deleteDrives(ctx, nodeID); err != nil { 24 | errors = append(errors, err.Error()) 25 | } 26 | if err := c.deleteACs(ctx, nodeID); err != nil { 27 | errors = append(errors, err.Error()) 28 | } 29 | if err := c.deleteLVGs(ctx, nodeID); err != nil { 30 | errors = append(errors, err.Error()) 31 | } 32 | if err := c.deleteVolumes(ctx, nodeID); err != nil { 33 | errors = append(errors, err.Error()) 34 | } 35 | 36 | // we don't clean csibmnode after getting some errors to retry on next reconcile 37 | if len(errors) != 0 { 38 | return fmt.Errorf(strings.Join(errors, "\n")) 39 | } 40 | 41 | if err := c.deleteObject(ctx, csibmnode, "csibmnode", false); err != nil { 42 | return err 43 | } 44 | 45 | return nil 46 | } 47 | 48 | func (c *Controller) deleteDrives(ctx context.Context, nodeID string) error { 49 | // Field selectors for CRDs' spec is not supported https://github.com/kubernetes/kubernetes/issues/53459 50 | // fieldSelector := fields.SelectorFromSet(map[string]string{"spec.NodeId": nodeID}) 51 | 52 | drives := &drivecrd.DriveList{} 53 | err := c.client.List(ctx, drives) 54 | if err != nil { 55 | return err 56 | } 57 | 58 | var errors []string 59 | 60 | for i, drive := range drives.Items { 61 | if drive.Spec.NodeId == nodeID { 62 | if err = c.deleteObject(ctx, &drives.Items[i], "drive", false); err != nil { 63 | errors = append(errors, err.Error()) 64 | } 65 | } 66 | } 67 | 68 | if len(errors) != 0 { 69 | return fmt.Errorf(strings.Join(errors, "\n")) 70 | } 71 | 72 | return nil 73 | } 74 | 75 | func (c *Controller) deleteACs(ctx context.Context, nodeID string) error { 76 | acs := &accrd.AvailableCapacityList{} 77 | err := c.client.List(ctx, acs) 78 | if err != nil { 79 | return err 80 | } 81 | 82 | var errors []string 83 | 84 | for i, ac := range acs.Items { 85 | if ac.Spec.NodeId == nodeID { 86 | if err = c.deleteObject(ctx, &acs.Items[i], "ac", false); err != nil { 87 | errors = append(errors, err.Error()) 88 | } 89 | } 90 | } 91 | 92 | if len(errors) != 0 { 93 | return fmt.Errorf(strings.Join(errors, "\n")) 94 | } 95 | 96 | return nil 97 | } 98 | 99 | func (c *Controller) deleteLVGs(ctx context.Context, nodeID string) error { 100 | lvgs := &lvgcrd.LogicalVolumeGroupList{} 101 | err := c.client.List(ctx, lvgs) 102 | if err != nil { 103 | return err 104 | } 105 | 106 | var errors []string 107 | 108 | for i, lvg := range lvgs.Items { 109 | if lvg.Spec.Node == nodeID { 110 | if err = c.deleteObject(ctx, &lvgs.Items[i], "lvg", true); err != nil { 111 | errors = append(errors, err.Error()) 112 | } 113 | } 114 | } 115 | 116 | if len(errors) != 0 { 117 | return fmt.Errorf(strings.Join(errors, "\n")) 118 | } 119 | 120 | return nil 121 | } 122 | 123 | func (c *Controller) deleteVolumes(ctx context.Context, nodeID string) error { 124 | volumes := &volumecrd.VolumeList{} 125 | err := c.client.List(ctx, volumes) 126 | if err != nil { 127 | return err 128 | } 129 | 130 | var errors []string 131 | 132 | for i, volume := range volumes.Items { 133 | if volume.Spec.NodeId == nodeID { 134 | if err = c.deleteObject(ctx, &volumes.Items[i], "volume", true); err != nil { 135 | errors = append(errors, err.Error()) 136 | } 137 | } 138 | } 139 | 140 | if len(errors) != 0 { 141 | return fmt.Errorf(strings.Join(errors, "\n")) 142 | } 143 | 144 | return nil 145 | } 146 | 147 | func (c *Controller) deleteObject(ctx context.Context, obj client.Object, objType string, patchFinalizer bool) error { 148 | var errors []string 149 | 150 | if patchFinalizer { 151 | if len(obj.GetFinalizers()) != 0 { 152 | obj.SetFinalizers([]string{}) 153 | if err := c.client.Update(ctx, obj); err != nil { 154 | c.log.Error(err, fmt.Sprintf("Failed to update obj, type: %s, name: %s", objType, obj.GetName())) 155 | errors = append(errors, err.Error()) 156 | } 157 | 158 | if err := c.client.Get(ctx, client.ObjectKey{Name: obj.GetName(), Namespace: obj.GetNamespace()}, obj); err != nil { 159 | c.log.Error(err, fmt.Sprintf("Failed to get obj, type: %s, name: %s", objType, obj.GetName())) 160 | errors = append(errors, err.Error()) 161 | } 162 | } 163 | } 164 | 165 | // remove object 166 | if err := c.client.Delete(ctx, obj); err != nil { 167 | c.log.Error(err, fmt.Sprintf("Failed to delete obj, type: %s, name: %s", objType, obj.GetName())) 168 | errors = append(errors, err.Error()) 169 | } 170 | 171 | if len(errors) != 0 { 172 | return fmt.Errorf(strings.Join(errors, "\n")) 173 | } 174 | 175 | return nil 176 | } 177 | -------------------------------------------------------------------------------- /pkg/patcher/patcher_configuration.go: -------------------------------------------------------------------------------- 1 | package patcher 2 | 3 | import ( 4 | "fmt" 5 | "path" 6 | 7 | csibaremetalv1 "github.com/dell/csi-baremetal-operator/api/v1" 8 | "github.com/dell/csi-baremetal-operator/api/v1/components" 9 | "github.com/dell/csi-baremetal-operator/pkg/constant" 10 | ) 11 | 12 | const ( 13 | rke2ManifestsFolder = "/var/lib/rancher/rke2/agent/pod-manifests" 14 | vanillaManifestsFolder = "/etc/kubernetes/manifests" 15 | 16 | rke2Kubeconfig = "/var/lib/rancher/rke2/server/cred/scheduler.kubeconfig" 17 | vanillaKubeconfig = "/etc/kubernetes/scheduler.conf" 18 | 19 | schedulerFolder = "scheduler" 20 | 21 | policyFile = "policy.yaml" 22 | configFile = "config.yaml" 23 | config19File = "config-19.yaml" 24 | config23File = "config-23.yaml" 25 | config29File = "config-29.yaml" 26 | 27 | policyPath = schedulerFolder + "/" + policyFile 28 | configPath = schedulerFolder + "/" + configFile 29 | config19Path = schedulerFolder + "/" + config19File 30 | config23Path = schedulerFolder + "/" + config23File 31 | config29Path = schedulerFolder + "/" + config29File 32 | ) 33 | 34 | // newPatcherConfiguration creates patcherConfiguration 35 | func newPatcherConfiguration(csi *csibaremetalv1.Deployment) (*patcherConfiguration, error) { 36 | var config patcherConfiguration 37 | switch csi.Spec.Platform { 38 | case constant.PlatformVanilla: 39 | config = patcherConfiguration{ 40 | platform: constant.PlatformVanilla, 41 | targetConfig: path.Join(vanillaManifestsFolder, configPath), 42 | targetPolicy: path.Join(vanillaManifestsFolder, policyPath), 43 | targetConfig19: path.Join(vanillaManifestsFolder, config19Path), 44 | targetConfig23: path.Join(vanillaManifestsFolder, config23Path), 45 | targetConfig29: path.Join(vanillaManifestsFolder, config29Path), 46 | schedulerFolder: path.Join(vanillaManifestsFolder, schedulerFolder), 47 | manifestsFolder: vanillaManifestsFolder, 48 | kubeconfig: vanillaKubeconfig, 49 | } 50 | case constant.PlatformRKE: 51 | config = patcherConfiguration{ 52 | platform: constant.PlatformRKE, 53 | targetConfig: path.Join(rke2ManifestsFolder, configPath), 54 | targetPolicy: path.Join(rke2ManifestsFolder, policyPath), 55 | targetConfig19: path.Join(rke2ManifestsFolder, config19Path), 56 | targetConfig23: path.Join(rke2ManifestsFolder, config23Path), 57 | targetConfig29: path.Join(rke2ManifestsFolder, config29Path), 58 | schedulerFolder: path.Join(rke2ManifestsFolder, schedulerFolder), 59 | manifestsFolder: rke2ManifestsFolder, 60 | kubeconfig: rke2Kubeconfig, 61 | } 62 | default: 63 | return nil, fmt.Errorf("%s platform is not supported platform for the patcher", csi.Spec.Platform) 64 | } 65 | config.image = csi.Spec.Scheduler.Patcher.Image 66 | config.interval = csi.Spec.Scheduler.Patcher.Interval 67 | config.restoreOnShutdown = csi.Spec.Scheduler.Patcher.RestoreOnShutdown 68 | config.configMapName = csi.Spec.Scheduler.Patcher.ConfigMapName 69 | config.ns = csi.GetNamespace() 70 | config.globalRegistry = csi.Spec.GlobalRegistry 71 | config.registrySecret = csi.Spec.RegistrySecret 72 | config.pullPolicy = csi.Spec.PullPolicy 73 | config.loglevel = csi.Spec.Scheduler.Log.Level 74 | config.configFolder = configurationPath 75 | config.resources = csi.Spec.Scheduler.Patcher.Resources 76 | config.securityContext = csi.Spec.Scheduler.SecurityContext 77 | config.serviceAccount = csi.Spec.Scheduler.ServiceAccount 78 | return &config, nil 79 | } 80 | 81 | type patcherConfiguration struct { 82 | ns string 83 | image *components.Image 84 | globalRegistry string 85 | registrySecret string 86 | pullPolicy string 87 | loglevel components.Level 88 | interval int 89 | restoreOnShutdown bool 90 | resources *components.ResourceRequirements 91 | securityContext *components.SecurityContext 92 | 93 | platform string 94 | targetConfig string 95 | targetPolicy string 96 | targetConfig19 string 97 | targetConfig23 string 98 | targetConfig29 string 99 | schedulerFolder string 100 | manifestsFolder string 101 | configMapName string 102 | configFolder string 103 | kubeconfig string 104 | serviceAccount string 105 | } 106 | -------------------------------------------------------------------------------- /pkg/patcher/scheduler_patcher.go: -------------------------------------------------------------------------------- 1 | package patcher 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net/http" 7 | "strconv" 8 | 9 | "github.com/sirupsen/logrus" 10 | "k8s.io/apimachinery/pkg/runtime" 11 | "k8s.io/client-go/kubernetes" 12 | "sigs.k8s.io/controller-runtime/pkg/client" 13 | 14 | csibaremetalv1 "github.com/dell/csi-baremetal-operator/api/v1" 15 | "github.com/dell/csi-baremetal-operator/pkg/constant" 16 | securityverifier "github.com/dell/csi-baremetal-operator/pkg/feature/security_verifier" 17 | ) 18 | 19 | // SchedulerPatcher performs pacthing procedure depends on platform 20 | type SchedulerPatcher struct { 21 | Clientset kubernetes.Interface 22 | Log *logrus.Entry 23 | Client client.Client 24 | PodSecurityPolicyVerifier securityverifier.SecurityVerifier 25 | // will only set on Openshift 26 | KubernetesVersion string 27 | // whether use secondary scheduler on Openshift 28 | UseOpenshiftSecondaryScheduler bool 29 | // SelectedSchedulerExtenderIP used for openshift secondary scheduler extender config if applicable 30 | SelectedSchedulerExtenderIP string 31 | // The suffix pattern used to check whether the scheduler extender workable on Openshift with 2nd scheduler 32 | ExtenderPatternChecked string 33 | // HTTPClient used for openshift secondary scheduler extender config if applicable 34 | HTTPClient *http.Client 35 | } 36 | 37 | func (p *SchedulerPatcher) useOpenshiftSecondaryScheduler(platform string) (bool, error) { 38 | if platform == constant.PlatformOpenShift && p.KubernetesVersion == "" { 39 | if k8sVersionInfo, err := p.Clientset.Discovery().ServerVersion(); err == nil { 40 | var ( 41 | k8sMajorVersion int 42 | k8sMinorVersion int 43 | ) 44 | k8sMajorVersion, err = strconv.Atoi(k8sVersionInfo.Major) 45 | if err != nil { 46 | return false, err 47 | } 48 | k8sMinorVersion, err = strconv.Atoi(k8sVersionInfo.Minor) 49 | if err != nil { 50 | return false, err 51 | } 52 | p.KubernetesVersion = fmt.Sprintf("%d.%d", k8sMajorVersion, k8sMinorVersion) 53 | p.Log.Infof("Kubernetes version: %s", p.KubernetesVersion) 54 | // Will use Openshift Secondary Scheduler on k8s version >= 1.23, i.e. Openshift 4.10 55 | p.UseOpenshiftSecondaryScheduler = k8sMajorVersion >= 1 && k8sMinorVersion > 22 56 | } else { 57 | return false, err 58 | } 59 | } 60 | return p.UseOpenshiftSecondaryScheduler, nil 61 | } 62 | 63 | // Update updates or creates csi-baremetal-se-patcher on RKE and Vanilla 64 | // patches Kube-Scheduler on Openshift 65 | func (p *SchedulerPatcher) Update(ctx context.Context, csi *csibaremetalv1.Deployment, scheme *runtime.Scheme) error { 66 | if !IsPatchingEnabled(csi) { 67 | p.Log.Warn("Kubernetes scheduler configuration patching not enabled. Please update configuration manually") 68 | return nil 69 | } 70 | 71 | useOpenshiftSecondaryScheduler, err := p.useOpenshiftSecondaryScheduler(csi.Spec.Platform) 72 | if err != nil { 73 | return err 74 | } 75 | if useOpenshiftSecondaryScheduler { 76 | p.ExtenderPatternChecked = extenderFilterPattern 77 | } 78 | switch csi.Spec.Platform { 79 | case constant.PlatformOpenShift: 80 | err = p.patchOpenShift(ctx, csi, useOpenshiftSecondaryScheduler, scheme) 81 | case constant.PlatformVanilla, constant.PlatformRKE: 82 | err = p.updateVanilla(ctx, csi, scheme) 83 | } 84 | if err != nil { 85 | return err 86 | } 87 | 88 | return p.UpdateReadinessConfigMap(ctx, csi, scheme, useOpenshiftSecondaryScheduler) 89 | } 90 | 91 | // Uninstall unpatch Openshift Scheduler 92 | func (p *SchedulerPatcher) Uninstall(ctx context.Context, csi *csibaremetalv1.Deployment) error { 93 | if IsPatchingEnabled(csi) && csi.Spec.Platform == constant.PlatformOpenShift { 94 | return p.unPatchOpenShift(ctx) 95 | } 96 | return nil 97 | } 98 | -------------------------------------------------------------------------------- /pkg/patcher/scheduler_patcher_vanilla_test.go: -------------------------------------------------------------------------------- 1 | package patcher 2 | 3 | 4 | import ( 5 | "context" 6 | "testing" 7 | "strings" 8 | 9 | "github.com/dell/csi-baremetal/pkg/events/mocks" 10 | "github.com/sirupsen/logrus" 11 | "github.com/stretchr/testify/assert" 12 | "github.com/stretchr/testify/mock" 13 | 14 | rbacv1 "k8s.io/api/rbac/v1" 15 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 16 | v1 "github.com/dell/csi-baremetal-operator/api/v1" 17 | "github.com/dell/csi-baremetal-operator/api/v1/components" 18 | "github.com/dell/csi-baremetal-operator/pkg/common" 19 | "github.com/dell/csi-baremetal-operator/pkg/constant" 20 | ) 21 | 22 | var ( 23 | logEntryScheduler = logrus.WithField("Test name", "SchedulerExtenderTest") 24 | 25 | matchSecurityContextConstraintsPolicies = []rbacv1.PolicyRule{ 26 | { 27 | Verbs: []string{"use"}, 28 | APIGroups: []string{"security.openshift.io"}, 29 | Resources: []string{"securitycontextconstraints"}, 30 | ResourceNames: []string{"privileged"}, 31 | }, 32 | } 33 | 34 | matchPodSecurityPolicyPolicy = rbacv1.PolicyRule{ 35 | Verbs: []string{"use"}, 36 | APIGroups: []string{"policy"}, 37 | Resources: []string{"podsecuritypolicies"}, 38 | ResourceNames: []string{"privileged"}, 39 | } 40 | 41 | testRoleBinding = rbacv1.RoleBinding{ 42 | ObjectMeta: metav1.ObjectMeta{ 43 | Name: "test-rolebinding", 44 | Namespace: "test-csi", 45 | }, 46 | Subjects: []rbacv1.Subject{ 47 | { 48 | Kind: rbacv1.ServiceAccountKind, 49 | Name: "csi-node-sa", 50 | Namespace: "test-csi", 51 | }, 52 | }, 53 | RoleRef: rbacv1.RoleRef{ 54 | APIGroup: rbacv1.GroupName, 55 | Kind: "Role", 56 | Name: "test-role", 57 | }, 58 | } 59 | 60 | testRoleSecurityContextConstraints = rbacv1.Role{ 61 | ObjectMeta: metav1.ObjectMeta{ 62 | Name: "test-role", 63 | Namespace: "test-csi", 64 | }, 65 | Rules: matchSecurityContextConstraintsPolicies, 66 | } 67 | 68 | testRolePodSecurityPolicy = rbacv1.Role{ 69 | ObjectMeta: metav1.ObjectMeta{ 70 | Name: "test-role", 71 | Namespace: "test-csi", 72 | }, 73 | Rules: []rbacv1.PolicyRule{matchPodSecurityPolicyPolicy}, 74 | } 75 | 76 | testDeploymentScheduler = v1.Deployment{ 77 | ObjectMeta: metav1.ObjectMeta{ 78 | Name: "test-deployment", 79 | Namespace: "test-csi", 80 | }, 81 | Spec: components.DeploymentSpec{ 82 | Scheduler: &components.Scheduler{ 83 | PodSecurityPolicy: &components.PodSecurityPolicy{ 84 | Enable: true, 85 | ResourceName: "privileged", 86 | }, 87 | ServiceAccount: "csi-node-sa", 88 | Patcher: &components.Patcher{ 89 | Image: &components.Image{ 90 | Name: "test", 91 | }, 92 | ConfigMapName: "scheduler-conf", 93 | Interval: 10, 94 | RestoreOnShutdown: true, 95 | Enable: true, 96 | }, 97 | Log: &components.Log{ 98 | Level: "debug", 99 | }, 100 | Image: &components.Image{ 101 | Name: "test", 102 | }, 103 | }, 104 | Platform: constant.PlatformVanilla, 105 | GlobalRegistry: "asdrepo.isus.emc.com:9042", 106 | RegistrySecret: "test-registry-secret", 107 | NodeController: &components.NodeController{ 108 | Enable: true, 109 | Log: &components.Log{ 110 | Level: "debug", 111 | }, 112 | Image: &components.Image{ 113 | Name: "test", 114 | }, 115 | }, 116 | }, 117 | } 118 | ) 119 | 120 | func Test_Update_Retry_Scheduler_Patcher_Vanilla(t *testing.T) { 121 | t.Run("Update", func(t *testing.T) { 122 | var ( 123 | ctx = context.Background() 124 | deployment = testDeploymentScheduler.DeepCopy() 125 | roleBinding = testRoleBinding.DeepCopy() 126 | role = testRolePodSecurityPolicy.DeepCopy() 127 | ) 128 | scheme, _ := common.PrepareScheme() 129 | eventRecorder := new(mocks.EventRecorder) 130 | eventRecorder.On("Eventf", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return() 131 | schedulerPatcher := prepareSchedulerPatcher(eventRecorder, prepareNodeClientSet(), prepareValidatorClient(scheme, roleBinding, role)) 132 | err := schedulerPatcher.updateVanilla(ctx, deployment, scheme) 133 | assert.Nil(t, err) 134 | err = schedulerPatcher.retryPatchVanilla(ctx, deployment, scheme) 135 | assert.Nil(t, err) 136 | }) 137 | } 138 | 139 | func Test_Retry_Patch_Vanilla_Error(t *testing.T) { 140 | t.Run("Retry", func(t *testing.T) { 141 | var ( 142 | ctx = context.Background() 143 | deployment = testDeploymentScheduler.DeepCopy() 144 | roleBinding = testRoleBinding.DeepCopy() 145 | role = testRolePodSecurityPolicy.DeepCopy() 146 | ) 147 | scheme, _ := common.PrepareScheme() 148 | eventRecorder := new(mocks.EventRecorder) 149 | eventRecorder.On("Eventf", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return() 150 | schedulerPatcher := prepareSchedulerPatcher(eventRecorder, prepareNodeClientSet(), prepareValidatorClient(scheme, roleBinding, role)) 151 | err := schedulerPatcher.retryPatchVanilla(ctx, deployment, scheme) 152 | assert.NotNil(t, err) 153 | assert.True(t, strings.HasSuffix(err.Error(), "not found")) 154 | }) 155 | } -------------------------------------------------------------------------------- /pkg/validator/interfaces.go: -------------------------------------------------------------------------------- 1 | package validator 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/dell/csi-baremetal-operator/pkg/validator/rbac/models" 7 | ) 8 | 9 | // rbacValidator is a private interface for rbac validator 10 | type rbacValidator interface { 11 | ValidateServiceAccountIsBound(ctx context.Context, rules *models.ServiceAccountIsRoleBoundData) error 12 | } 13 | -------------------------------------------------------------------------------- /pkg/validator/models/rbac.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | // Rule is a type of validation 4 | type Rule string 5 | 6 | // ServiceAccountIsRoleBound is a type for checking whether service account is bounded to certain role or policy rules 7 | var ServiceAccountIsRoleBound Rule 8 | 9 | // RBACRules is a bundle of data, needed to check rbac rules 10 | type RBACRules struct { 11 | Data interface{} 12 | Type Rule 13 | } 14 | -------------------------------------------------------------------------------- /pkg/validator/rbac/error.go: -------------------------------------------------------------------------------- 1 | package rbac 2 | 3 | import "fmt" 4 | 5 | // Error is a custom rbac error type 6 | type Error interface { 7 | error 8 | OrigError() error 9 | } 10 | 11 | type rbacError struct { 12 | message string 13 | } 14 | 15 | func (r *rbacError) OrigError() error { 16 | return fmt.Errorf(r.message) 17 | } 18 | 19 | func (r *rbacError) Error() string { 20 | return fmt.Sprintf("failed to validate rbac: %s", r.message) 21 | } 22 | 23 | // NewRBACError is a constructor for rbac error 24 | func NewRBACError(message string) Error { 25 | return &rbacError{ 26 | message: message, 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /pkg/validator/rbac/matcher.go: -------------------------------------------------------------------------------- 1 | package rbac 2 | 3 | import ( 4 | rbacv1 "k8s.io/api/rbac/v1" 5 | ) 6 | 7 | // Matcher is a helper for matching actual resources with requested ones 8 | type Matcher interface { 9 | MatchPolicyRules(actual, requested []rbacv1.PolicyRule) (matches bool) 10 | MatchPolicyRule(actual, requested *rbacv1.PolicyRule) (matches bool) 11 | MatchRoleBindingsSubjects(roleBindings []rbacv1.RoleBinding, subjectName, namespace string) (matchesRoleBindings []rbacv1.RoleBinding) 12 | MatchRoleBindingSubjects(roleBinding *rbacv1.RoleBinding, subjectName, namespace string) (matches bool) 13 | MatchRoles(roles []rbacv1.Role, names []string) (matchesRoles []rbacv1.Role) 14 | } 15 | 16 | type matcher struct{} 17 | 18 | func (m *matcher) MatchPolicyRules(actual, requested []rbacv1.PolicyRule) (matches bool) { 19 | for i := 0; i < len(actual); i++ { 20 | for j := 0; j < len(requested); j++ { 21 | if matches = m.MatchPolicyRule(&actual[i], &requested[j]); !matches { 22 | matches = false 23 | break 24 | } 25 | } 26 | 27 | if matches { 28 | return true 29 | } 30 | } 31 | return false 32 | } 33 | 34 | func (m *matcher) MatchPolicyRule(actual, requested *rbacv1.PolicyRule) (matches bool) { 35 | preparedActualVerbs := make(map[string]struct{}) 36 | for i := 0; i < len(actual.Verbs); i++ { 37 | preparedActualVerbs[actual.Verbs[i]] = struct{}{} 38 | } 39 | preparedActualAPIGroups := make(map[string]struct{}) 40 | for i := 0; i < len(actual.APIGroups); i++ { 41 | preparedActualAPIGroups[actual.APIGroups[i]] = struct{}{} 42 | } 43 | preparedActualResources := make(map[string]struct{}) 44 | for i := 0; i < len(actual.Resources); i++ { 45 | preparedActualResources[actual.Resources[i]] = struct{}{} 46 | } 47 | preparedActualResourceNames := make(map[string]struct{}) 48 | for i := 0; i < len(actual.ResourceNames); i++ { 49 | preparedActualResourceNames[actual.ResourceNames[i]] = struct{}{} 50 | } 51 | 52 | for i := 0; i < len(requested.Verbs); i++ { 53 | if _, ok := preparedActualVerbs[requested.Verbs[i]]; !ok { 54 | return false 55 | } 56 | } 57 | 58 | for i := 0; i < len(requested.APIGroups); i++ { 59 | if _, ok := preparedActualAPIGroups[requested.APIGroups[i]]; !ok { 60 | return false 61 | } 62 | } 63 | 64 | for i := 0; i < len(requested.Resources); i++ { 65 | if _, ok := preparedActualResources[requested.Resources[i]]; !ok { 66 | return false 67 | } 68 | } 69 | 70 | for i := 0; i < len(requested.ResourceNames); i++ { 71 | if _, ok := preparedActualResourceNames[requested.ResourceNames[i]]; !ok { 72 | return false 73 | } 74 | } 75 | 76 | return true 77 | } 78 | 79 | func (m *matcher) MatchRoleBindingsSubjects( 80 | roleBindings []rbacv1.RoleBinding, subjectName, namespace string, 81 | ) (matchesRoleBindings []rbacv1.RoleBinding) { 82 | for i := 0; i < len(roleBindings); i++ { 83 | if m.MatchRoleBindingSubjects(&roleBindings[i], subjectName, namespace) { 84 | matchesRoleBindings = append(matchesRoleBindings, roleBindings[i]) 85 | } 86 | } 87 | return matchesRoleBindings 88 | } 89 | 90 | func (m *matcher) MatchRoleBindingSubjects( 91 | roleBinding *rbacv1.RoleBinding, subjectName, namespace string, 92 | ) (matches bool) { 93 | for _, subject := range roleBinding.Subjects { 94 | if subject.Name == subjectName && subject.Namespace == namespace { 95 | return true 96 | } 97 | } 98 | return false 99 | } 100 | 101 | func (m *matcher) MatchRoles(roles []rbacv1.Role, names []string) (matchesRoles []rbacv1.Role) { 102 | preparedNames := make(map[string]struct{}) 103 | for i := 0; i < len(names); i++ { 104 | preparedNames[names[i]] = struct{}{} 105 | } 106 | 107 | for i := 0; i < len(roles); i++ { 108 | if _, ok := preparedNames[roles[i].Name]; ok { 109 | matchesRoles = append(matchesRoles, roles[i]) 110 | } 111 | } 112 | return 113 | } 114 | 115 | // NewMatcher is a constructor for matcher 116 | func NewMatcher() Matcher { 117 | return &matcher{} 118 | } 119 | -------------------------------------------------------------------------------- /pkg/validator/rbac/models/rules.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import v1 "k8s.io/api/rbac/v1" 4 | 5 | // ServiceAccountIsRoleBoundData is bundle of data, needed for checking whether service account is bounded 6 | // to certain role or policy rules 7 | type ServiceAccountIsRoleBoundData struct { 8 | Role *v1.Role 9 | ServiceAccountName string 10 | Namespace string 11 | } 12 | -------------------------------------------------------------------------------- /pkg/validator/rbac/validator.go: -------------------------------------------------------------------------------- 1 | package rbac 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/sirupsen/logrus" 8 | rbacv1 "k8s.io/api/rbac/v1" 9 | "sigs.k8s.io/controller-runtime/pkg/client" 10 | 11 | "github.com/dell/csi-baremetal-operator/pkg/validator/rbac/models" 12 | ) 13 | 14 | // Validator is rbac validator for checking predefined rule (e.g. service account is bound to role with certain policy rules) 15 | type Validator interface { 16 | ValidateServiceAccountIsBound(ctx context.Context, rules *models.ServiceAccountIsRoleBoundData) error 17 | } 18 | 19 | type rbac struct { 20 | client client.Client 21 | log *logrus.Entry 22 | matcher Matcher 23 | } 24 | 25 | func (r *rbac) ValidateServiceAccountIsBound(ctx context.Context, rules *models.ServiceAccountIsRoleBoundData) (err error) { 26 | // obtaining role bindings for current namespace 27 | roleBindings := rbacv1.RoleBindingList{} 28 | if err = r.client.List(ctx, &roleBindings, &client.ListOptions{ 29 | Namespace: rules.Namespace, 30 | }); err != nil { 31 | r.log.Errorf("failed to get roles list: %s", err.Error()) 32 | return err 33 | } 34 | 35 | // check if there exists role bindings, which matches passed service account 36 | matchesRoleBindings := r.matcher.MatchRoleBindingsSubjects(roleBindings.Items, rules.ServiceAccountName, rules.Namespace) 37 | if len(matchesRoleBindings) == 0 { 38 | return NewRBACError(fmt.Sprintf("service account not matched, service account: '%s', namespace: '%s'", 39 | rules.ServiceAccountName, rules.Namespace)) 40 | } 41 | 42 | // obtaining roles for current namespace 43 | roles := rbacv1.RoleList{} 44 | if err = r.client.List(ctx, &roles, &client.ListOptions{ 45 | Namespace: rules.Namespace, 46 | }); err != nil { 47 | r.log.Errorf("failed to get roles list: %s", err.Error()) 48 | return err 49 | } 50 | 51 | // preparing founded role bindings refs and finding matched ones between them 52 | matchesRoleBindingsRefs := make([]string, len(matchesRoleBindings)) 53 | for i := 0; i < len(matchesRoleBindings); i++ { 54 | matchesRoleBindingsRefs[i] = matchesRoleBindings[i].RoleRef.Name 55 | } 56 | matchesRoles := r.matcher.MatchRoles(roles.Items, matchesRoleBindingsRefs) 57 | if len(matchesRoles) == 0 { 58 | return NewRBACError(fmt.Sprintf("roles not matched, service account: '%s', namespace: '%s'", 59 | rules.ServiceAccountName, rules.Namespace)) 60 | } 61 | 62 | // matching requested policies between obtained roles 63 | for i := 0; i < len(matchesRoles); i++ { 64 | if rules.Role.Name != "" && rules.Role.Name != matchesRoles[i].Name { 65 | continue 66 | } 67 | if rules.Role.Namespace != "" && rules.Role.Namespace != matchesRoles[i].Namespace { 68 | continue 69 | } 70 | if r.matcher.MatchPolicyRules(matchesRoles[i].Rules, rules.Role.Rules) { 71 | return err 72 | } 73 | } 74 | return NewRBACError(fmt.Sprintf("failed to find any roles, matched to passed service account, "+ 75 | "service account: '%s', namespace: '%s'", rules.ServiceAccountName, rules.Namespace)) 76 | } 77 | 78 | // NewValidator is a constructor for rbac validator 79 | func NewValidator(client client.Client, log *logrus.Entry, matcher Matcher) Validator { 80 | return &rbac{ 81 | client: client, 82 | log: log, 83 | matcher: matcher, 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /pkg/validator/validator.go: -------------------------------------------------------------------------------- 1 | package validator 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/dell/csi-baremetal-operator/pkg/validator/models" 8 | rbacmodels "github.com/dell/csi-baremetal-operator/pkg/validator/rbac/models" 9 | ) 10 | 11 | // Validator is a generic validator for validating certain conditions (e.g. rbac resources matches) 12 | type Validator interface { 13 | ValidateRBAC(ctx context.Context, rules *models.RBACRules) error 14 | } 15 | 16 | type validator struct { 17 | rbacValidator 18 | } 19 | 20 | func (v *validator) ValidateRBAC(ctx context.Context, rules *models.RBACRules) (err error) { 21 | switch rules.Type { 22 | case models.ServiceAccountIsRoleBound: 23 | adaptedRules, ok := rules.Data.(*rbacmodels.ServiceAccountIsRoleBoundData) 24 | if !ok { 25 | return fmt.Errorf("unknown data for service account is role bound validation") 26 | } 27 | return v.ValidateServiceAccountIsBound(ctx, adaptedRules) 28 | default: 29 | return fmt.Errorf("unknown validation rule type, %s", rules.Type) 30 | } 31 | } 32 | 33 | // NewValidator is a constructor for validator 34 | func NewValidator(rbacValidator rbacValidator) Validator { 35 | return &validator{ 36 | rbacValidator: rbacValidator, 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /variables.mk: -------------------------------------------------------------------------------- 1 | # project name 2 | PROJECT := csi-baremetal-operator 3 | 4 | # controller-gen related vars 5 | CSI_OPERATOR_CHART_PATH=charts/csi-baremetal-operator 6 | CSI_DEPLOYMENT_CHART_PATH=charts/csi-baremetal-deployment 7 | CSI_CHART_CRDS_PATH=charts/csi-baremetal-operator/crds 8 | CONTROLLER_GEN_BIN=./bin/controller-gen 9 | CRD_OPTIONS ?= "crd:trivialVersions=true" 10 | 11 | # image vars 12 | BASE_IMAGE ?= golang:1.21 13 | CRD_BUILD_IMAGE ?= ${REGISTRY}/csi-baremetal-pre-upgrade-crds:${TAG} 14 | KUBECTL_IMAGE ?= bitnami/kubectl:1.29.11 # https://hub.docker.com/r/bitnami/kubectl 15 | 16 | ### version 17 | MAJOR := 1 18 | MINOR := 7 19 | PATCH := 0 20 | PRODUCT_VERSION ?= ${MAJOR}.${MINOR}.${PATCH} 21 | BUILD_REL_A := $(shell git rev-list HEAD |wc -l) 22 | BUILD_REL_B := $(shell git rev-parse --short HEAD) 23 | BLD_CNT := $(shell echo ${BUILD_REL_A}) 24 | BLD_SHA := $(shell echo ${BUILD_REL_B}) 25 | RELEASE_STR := ${BLD_CNT}.${BLD_SHA} 26 | FULL_VERSION := ${PRODUCT_VERSION}-${RELEASE_STR} 27 | TAG := ${FULL_VERSION} 28 | BRANCH := $(shell git rev-parse --abbrev-ref HEAD) 29 | 30 | ### go env vars 31 | GO_ENV_VARS := GO111MODULE=on ${GOPRIVATE_PART} ${GOPROXY_PART} 32 | 33 | ### custom variables that could be ommited 34 | GOPRIVATE_PART := 35 | GOPROXY_PART := GOPROXY=https://proxy.golang.org,direct 36 | 37 | # override some of variables, optional file 38 | -include variables.override.mk 39 | --------------------------------------------------------------------------------