From 48ca0f52ca6648658af27404eee1f90c6a9441fe Mon Sep 17 00:00:00 2001 From: Aleksandr Stefurishin Date: Tue, 18 Feb 2025 15:29:19 +0300 Subject: [PATCH] Move LLVS to EE (#126) Signed-off-by: Aleksandr Stefurishin Signed-off-by: v.oleynikov Signed-off-by: Pavel Karpov Signed-off-by: Aleksandr Zimin Co-authored-by: Vasily Oleynikov Co-authored-by: Pavel Karpov Co-authored-by: Nikolay Demchuk Co-authored-by: Aleksandr Zimin --- .github/workflows/build_dev.yml | 53 +++++-- .github/workflows/build_prod.yml | 19 ++- .github/workflows/go_lint.yaml | 24 ++-- .github/workflows/go_modules_check.yaml | 12 +- .github/workflows/go_tests.yaml | 22 +-- .github/workflows/trivy_check.yaml | 6 +- .gitignore | 2 + .golangci.yaml | 3 +- .werf/consts.yaml | 11 +- api/go.mod | 2 +- api/v1alpha1/const.go | 29 ++++ api/v1alpha1/register.go | 26 ++-- ...ed_lvm_logical_volume_snapshot.deepcopy.go | 1 - images/agent/src/cmd/llvs_ce.go | 35 +++++ images/agent/src/cmd/llvs_ee.go | 59 ++++++++ images/agent/src/cmd/main.go | 25 +--- images/agent/src/go.mod | 69 ++++----- images/agent/src/go.sum | 134 ++++++++---------- images/agent/src/internal/const.go | 10 -- .../src/internal/controller/llv/llvs_ce.go | 27 ++++ .../src/internal/controller/llv/llvs_ee.go | 41 ++++++ .../src/internal/controller/llv/reconciler.go | 52 ++++--- .../controller/llv/reconciler_test.go | 50 ++++--- .../controller/llv_extender/reconciler.go | 10 +- .../llvs/{reconciler.go => reconciler_ee.go} | 24 ++-- images/agent/src/internal/utils/client_llv.go | 5 +- images/agent/werf.inc.yaml | 21 ++- .../src/internal/const.go | 5 - .../pkg/controller/lvg_conditions_watcher.go | 10 +- .../lvm_volume_group_set_watcher.go | 7 +- images/sds-utils-installer/werf.inc.yaml | 3 +- images/webhooks/src/cmd/main.go | 83 +++++++++++ images/webhooks/src/go.mod | 40 ++++++ images/webhooks/src/go.sum | 110 ++++++++++++++ images/webhooks/src/handlers/func.go | 48 +++++++ images/webhooks/src/handlers/llvsValidator.go | 38 +++++ images/webhooks/werf.inc.yaml | 80 +++++++++++ lib/go/common/go.mod | 3 + lib/go/common/go.sum | 0 lib/go/common/pkg/feature/const_ce.go | 18 +++ lib/go/common/pkg/feature/const_csepro.go | 11 ++ lib/go/common/pkg/feature/const_ee.go | 11 ++ lib/go/common/pkg/feature/const_se.go | 11 ++ lib/go/common/pkg/feature/const_seplus.go | 11 ++ lib/go/common/pkg/feature/feature.go | 5 + templates/webhooks/deployment.yaml | 96 +++++++++++++ templates/webhooks/rbac-for-us.yaml | 36 +++++ templates/webhooks/secret.yaml | 12 ++ templates/webhooks/service.yaml | 16 +++ templates/webhooks/webhook.yaml | 23 +++ werf-giterminism.yaml | 2 +- 51 files changed, 1172 insertions(+), 279 deletions(-) create mode 100644 api/v1alpha1/const.go create mode 100644 images/agent/src/cmd/llvs_ce.go create mode 100644 images/agent/src/cmd/llvs_ee.go create mode 100644 images/agent/src/internal/controller/llv/llvs_ce.go create mode 100644 images/agent/src/internal/controller/llv/llvs_ee.go rename images/agent/src/internal/controller/llvs/{reconciler.go => reconciler_ee.go} (95%) create mode 100644 images/webhooks/src/cmd/main.go create mode 100644 images/webhooks/src/go.mod create mode 100644 images/webhooks/src/go.sum create mode 100644 images/webhooks/src/handlers/func.go create mode 100644 images/webhooks/src/handlers/llvsValidator.go create mode 100644 images/webhooks/werf.inc.yaml create mode 100644 lib/go/common/go.mod create mode 100644 lib/go/common/go.sum create mode 100644 lib/go/common/pkg/feature/const_ce.go create mode 100644 lib/go/common/pkg/feature/const_csepro.go create mode 100644 lib/go/common/pkg/feature/const_ee.go create mode 100644 lib/go/common/pkg/feature/const_se.go create mode 100644 lib/go/common/pkg/feature/const_seplus.go create mode 100644 lib/go/common/pkg/feature/feature.go create mode 100644 templates/webhooks/deployment.yaml create mode 100644 templates/webhooks/rbac-for-us.yaml create mode 100644 templates/webhooks/secret.yaml create mode 100644 templates/webhooks/service.yaml create mode 100644 templates/webhooks/webhook.yaml diff --git a/.github/workflows/build_dev.yml b/.github/workflows/build_dev.yml index 544f18e0..3b39d027 100644 --- a/.github/workflows/build_dev.yml +++ b/.github/workflows/build_dev.yml @@ -6,37 +6,72 @@ env: MODULES_MODULE_NAME: ${{ vars.MODULE_NAME }} MODULES_MODULE_SOURCE: ${{ vars.DEV_MODULE_SOURCE }} MODULES_REGISTRY_LOGIN: ${{ vars.DEV_MODULES_REGISTRY_LOGIN }} + DEFAULT_EDITION: ${{ vars.DEFAULT_EDITION }} MODULES_REGISTRY_PASSWORD: ${{ secrets.DEV_MODULES_REGISTRY_PASSWORD }} SOURCE_REPO: "${{ secrets.SOURCE_REPO }}" - - on: - #pull_request: + pull_request: + types: [opened, reopened, labeled, unlabeled, synchronize] + # call from trivy_image_check.yaml, which in turn call from pull_request + # https://stackoverflow.com/a/71489231 + workflow_call: push: branches: - main - # make this job as dependency for trivy_image_check workflow - # https://stackoverflow.com/a/71489231 - workflow_call: +defaults: + run: + shell: bash jobs: + set_edition: + runs-on: [self-hosted, regular, selectel] + name: Set edition + outputs: + module_edition: ${{ steps.set-vars.outputs.MODULE_EDITION }} + steps: + - name: Get Pull Request Labels + id: get-labels + uses: actions/github-script@v7 + with: + script: | + if (context.eventName === "pull_request" || context.eventName === "pull_request_target" ) { + const prNumber = context.payload.pull_request.number; + const { data: labels } = await github.rest.issues.listLabelsOnIssue({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + }); + return labels.map(label => label.name); + } else { + return []; + } + result-encoding: string + + - name: Set vars + id: set-vars + run: | + MODULE_EDITION=$DEFAULT_EDITION + EDITION=$(echo "${{ steps.get-labels.outputs.result }}" | grep -Po "edition/\K\w+" | head -n 1 || true) + [[ -n $EDITION ]] && MODULE_EDITION=$EDITION + echo "MODULE_EDITION=$MODULE_EDITION" >> "$GITHUB_OUTPUT" dev_setup_build: runs-on: [self-hosted, regular, selectel] name: Build and Push images + needs: [set_edition] + env: + MODULE_EDITION: ${{needs.set_edition.outputs.module_edition}} steps: - name: Set vars for PR if: ${{ github.ref_name != 'main' }} run: | MODULES_MODULE_TAG="$(echo pr${{ github.ref_name }} | sed 's/\/.*//g')" echo "MODULES_MODULE_TAG=$MODULES_MODULE_TAG" >> "$GITHUB_ENV" - shell: bash - name: Set vars for main if: ${{ github.ref_name == 'main' }} run: | echo "MODULES_MODULE_TAG=${{ github.ref_name }}" >> "$GITHUB_ENV" - shell: bash - name: Print vars run: | echo MODULES_REGISTRY=$MODULES_REGISTRY @@ -44,7 +79,7 @@ jobs: echo MODULES_MODULE_NAME=$MODULES_MODULE_NAME echo MODULES_MODULE_SOURCE=$MODULES_MODULE_SOURCE echo MODULES_MODULE_TAG=$MODULES_MODULE_TAG - shell: bash + echo MODULE_EDITION=$MODULE_EDITION - uses: actions/checkout@v4 - uses: deckhouse/modules-actions/setup@v1 diff --git a/.github/workflows/build_prod.yml b/.github/workflows/build_prod.yml index 71c2407c..612c1b6e 100644 --- a/.github/workflows/build_prod.yml +++ b/.github/workflows/build_prod.yml @@ -15,6 +15,10 @@ on: tags: - '**' +defaults: + run: + shell: bash + jobs: prod_ce_setup_build: runs-on: [self-hosted, regular, selectel] @@ -23,12 +27,13 @@ jobs: - name: SET VAR run: | echo "MODULES_MODULE_SOURCE=$MODULES_REGISTRY/$MODULE_SOURCE_NAME/ce/modules" >> "$GITHUB_ENV" + echo "MODULE_EDITION=ce" >> "$GITHUB_ENV" - run: | echo $MODULES_REGISTRY echo $MODULES_MODULE_NAME echo $MODULES_MODULE_SOURCE echo $MODULES_MODULE_TAG - shell: bash + echo $MODULE_EDITION name: Show vars - uses: actions/checkout@v4 @@ -56,12 +61,13 @@ jobs: - name: SET VAR run: | echo "MODULES_MODULE_SOURCE=$MODULES_REGISTRY/$MODULE_SOURCE_NAME/ee/modules" >> "$GITHUB_ENV" + echo "MODULE_EDITION=ee" >> "$GITHUB_ENV" - run: | echo $MODULES_REGISTRY echo $MODULES_MODULE_NAME echo $MODULES_MODULE_SOURCE echo $MODULES_MODULE_TAG - shell: bash + echo $MODULE_EDITION name: Show vars - uses: actions/checkout@v4 @@ -89,12 +95,13 @@ jobs: - name: SET VAR run: | echo "MODULES_MODULE_SOURCE=$MODULES_REGISTRY/$MODULE_SOURCE_NAME/fe/modules" >> "$GITHUB_ENV" + echo "MODULE_EDITION=ee" >> "$GITHUB_ENV" - run: | echo $MODULES_REGISTRY echo $MODULES_MODULE_NAME echo $MODULES_MODULE_SOURCE echo $MODULES_MODULE_TAG - shell: bash + echo $MODULE_EDITION name: Show vars - uses: actions/checkout@v4 @@ -122,12 +129,13 @@ jobs: - name: SET VAR run: | echo "MODULES_MODULE_SOURCE=$MODULES_REGISTRY/$MODULE_SOURCE_NAME/se/modules" >> "$GITHUB_ENV" + echo "MODULE_EDITION=se" >> "$GITHUB_ENV" - run: | echo $MODULES_REGISTRY echo $MODULES_MODULE_NAME echo $MODULES_MODULE_SOURCE echo $MODULES_MODULE_TAG - shell: bash + echo $MODULE_EDITION name: Show vars - uses: actions/checkout@v4 @@ -155,12 +163,13 @@ jobs: - name: SET VAR run: | echo "MODULES_MODULE_SOURCE=$MODULES_REGISTRY/$MODULE_SOURCE_NAME/se-plus/modules" >> "$GITHUB_ENV" + echo "MODULE_EDITION=seplus" >> "$GITHUB_ENV" - run: | echo $MODULES_REGISTRY echo $MODULES_MODULE_NAME echo $MODULES_MODULE_SOURCE echo $MODULES_MODULE_TAG - shell: bash + echo $MODULE_EDITION name: Show vars - uses: actions/checkout@v4 diff --git a/.github/workflows/go_lint.yaml b/.github/workflows/go_lint.yaml index 46b6e4be..85fc9824 100644 --- a/.github/workflows/go_lint.yaml +++ b/.github/workflows/go_lint.yaml @@ -1,5 +1,8 @@ name: Go linter for images +env: + GO_BUILD_TAGS: "ce se seplus ee csepro" + on: pull_request: push: @@ -18,26 +21,27 @@ jobs: - name: Setup Go environment uses: actions/setup-go@v5 with: - go-version: '1.22' + go-version: '1.23.5' - name: Install golangci-lint - run: go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.59.1 + run: go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.61.0 - name: Run Go lint run: | basedir=$(pwd) failed='false' - for dir in $(find images -type d); do - if ls $dir/go.mod &> /dev/null; then - echo "Running linter in $dir" - cd $dir - golangci-lint run + for i in $(find images -type f -name go.mod);do + dir=$(echo $i | sed 's/go.mod$//') + cd $basedir/$dir + # check all editions + for edition in $GO_BUILD_TAGS ;do + echo "Running linter in $dir (edition: $edition)" + golangci-lint run --build-tags $edition if [ $? -ne 0 ]; then - echo "Linter failed in $dir" + echo "Linter failed in $dir (edition: $edition)" failed='true' fi - cd $basedir - fi + done done if [ $failed == 'true' ]; then exit 1 diff --git a/.github/workflows/go_modules_check.yaml b/.github/workflows/go_modules_check.yaml index 37bbdb17..bd2bf6ab 100644 --- a/.github/workflows/go_modules_check.yaml +++ b/.github/workflows/go_modules_check.yaml @@ -18,7 +18,7 @@ jobs: - name: Setup Go environment uses: actions/setup-go@v5 with: - go-version: '1.22' + go-version: '1.23.5' - name: Run Go modules version check run: | @@ -44,8 +44,14 @@ jobs: if [[ "$line" == *github.com/deckhouse/sds-* || "$line" == *github.com/deckhouse/csi-* || "$line" == *github.com/deckhouse/virtualization ]]; then repository=$(echo "$line" | awk '{print $1}' | awk -F'/' '{ print "https://"$1"/"$2"/"$3".git" }') pseudo_tag=$(echo "$line" | awk '{print $2}') + + go_pkg=$(echo "$line" | awk '{print $1}') + if grep -q "^replace $go_pkg" $go_mod_file ;then + echo "Skipping $go_pkg check because it exists in replacement" + continue + fi + echo "Cloning repo $repository into $temp_dir" - git clone "$repository" "$temp_dir/$repository" >/dev/null 2>&1 if [ -d "$temp_dir/$repository/api" ]; then @@ -79,4 +85,4 @@ jobs: if [ $alert_lines_count != 0 ]; then echo "We have non-actual pseudo-tags in repository's go.mod files" exit 1 - fi \ No newline at end of file + fi diff --git a/.github/workflows/go_tests.yaml b/.github/workflows/go_tests.yaml index 184ee37a..19db8e13 100644 --- a/.github/workflows/go_tests.yaml +++ b/.github/workflows/go_tests.yaml @@ -1,5 +1,8 @@ name: Go tests for images +env: + GO_BUILD_TAGS: "ce se seplus ee csepro" + on: pull_request: push: @@ -18,23 +21,24 @@ jobs: - name: Setup Go environment uses: actions/setup-go@v5 with: - go-version: '1.22' + go-version: '1.23.5' - name: Run Go tests run: | basedir=$(pwd) failed='false' - for dir in $(find images -type d); do - if ls $dir/*_test.go &> /dev/null; then - echo "Running tests in $dir" - cd $dir - go test -v + for i in $(find images -type f -name '*_test.go');do + dir=$(echo $i | sed 's/[a-z_A-Z0-9-]*_test.go$//') + cd $basedir/$dir + # check all editions + for edition in $GO_BUILD_TAGS ;do + echo "Running tests in $dir (edition: $edition)" + go test -v -tags $edition if [ $? -ne 0 ]; then - echo "Tests failed in $dir" + echo "Tests failed in $dir (edition: $edition)" failed='true' fi - cd $basedir - fi + done done if [ $failed == 'true' ]; then exit 1 diff --git a/.github/workflows/trivy_check.yaml b/.github/workflows/trivy_check.yaml index f8692f1c..fc19c007 100644 --- a/.github/workflows/trivy_check.yaml +++ b/.github/workflows/trivy_check.yaml @@ -45,12 +45,12 @@ jobs: - name: Prepare sub repo run: | - version=v`grep "UTIL_LINUX_VERSION :=" images/agent/werf.inc.yaml | awk -F'"' '{ print $2}'` + version=`grep '"UTIL_LINUX"' .werf/consts.yaml | awk -F'"' '{ print $4}'` git clone --depth 1 --branch $version ${{ secrets.SOURCE_REPO }}/util-linux/util-linux.git ./util-linux git clone ${{ secrets.SOURCE_REPO }}/lvmteam/lvm2.git ./lvm2 - version=`grep "LVM2_VERSION :=" images/sds-utils-installer/werf.inc.yaml | awk -F'"' '{ print $2}'` + version=`grep '"LVM2"' .werf/consts.yaml | awk -F'"' '{ print $4}'` cd ./lvm2 - git checkout $version + git checkout $version cd .. - name: Run Trivy vulnerability scanner in fs mode diff --git a/.gitignore b/.gitignore index 36cb128f..4b561694 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,8 @@ .idea/ venv/ *.code-workspace +.vscode +*.code-workspace # macOS Finder files *.DS_Store diff --git a/.golangci.yaml b/.golangci.yaml index f0eb7ce0..1ba14916 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -17,8 +17,7 @@ linters-settings: - prefix(agent) - prefix(sds-health-watcher-controller) - prefix(sds-utils-installer) - errcheck: - ignore: fmt:.*,[rR]ead|[wW]rite|[cC]lose,io:Copy + - prefix(webhooks) linters: disable-all: true diff --git a/.werf/consts.yaml b/.werf/consts.yaml index b00cab8d..5d41585c 100644 --- a/.werf/consts.yaml +++ b/.werf/consts.yaml @@ -1,11 +1,20 @@ # base images {{- $_ := set $ "BASE_ALT" "registry.deckhouse.io/base_images/alt:p10@sha256:f105773c682498700680d7cd61a702a4315c4235aee3622757591fd510fb8b4a" }} {{- $_ := set $ "BASE_ALT_P11" "registry.deckhouse.io/base_images/alt:p11@sha256:e47d84424485d3674240cb2f67d3a1801b37d327e6d1eb8cc8d01be8ed3b34f3" }} -{{- $_ := set $ "BASE_GOLANG_1_23" "registry.deckhouse.io/base_images/golang:1.23.1-alpine3.20@sha256:716820a183116e643839611ff9eca9bd1c92d2bf8f7a5eda2f9fd16e8acbaa72" }} +{{- $_ := set $ "BASE_GOLANG_1_23" "registry.deckhouse.io/base_images/golang:1.23.5-alpine3.20@sha256:623ef3f63012bbd648021a2f097de3f411889332ba83bd98f0ac8d1288bdaa06" }} {{- $_ := set $ "BASE_SCRATCH" "registry.deckhouse.io/base_images/scratch@sha256:653ae76965c98c8cd1c8c9ff7725316d2983986f896655b30e0f44d2f8b2dd7e" }} {{- $_ := set $ "BASE_ALPINE" "registry.deckhouse.io/base_images/alpine:3.20.3@sha256:41628df7c9b935d248f64542634e7a843f9bc7f2252d7f878e77f7b79a947466" }} +# Edition module settings, default ce +{{- $_ := set . "MODULE_EDITION" (env "MODULE_EDITION" "ce") }} + # component versions {{- $versions := dict }} +{{- $_ := set $versions "UTIL_LINUX" "v2.39.3" }} +{{- $_ := set $versions "LVM2" "d786a8f820d54ce87a919e6af5426c333c173b11" }} {{- $_ := set $ "VERSIONS" $versions }} + +# custom constants +{{- $_ := set $ "DECKHOUSE_UID_GID" "64535" }} +{{- $_ := set $ "ALT_CLEANUP_CMD" "rm -rf /var/lib/apt/lists/* /var/cache/apt/* && mkdir -p /var/lib/apt/lists/partial /var/cache/apt/archives/partial" }} diff --git a/api/go.mod b/api/go.mod index 05a0cf0b..0eb99944 100644 --- a/api/go.mod +++ b/api/go.mod @@ -1,6 +1,6 @@ module github.com/deckhouse/sds-node-configurator/api -go 1.22.2 +go 1.22.3 require k8s.io/apimachinery v0.31.3 diff --git a/api/v1alpha1/const.go b/api/v1alpha1/const.go new file mode 100644 index 00000000..5b302610 --- /dev/null +++ b/api/v1alpha1/const.go @@ -0,0 +1,29 @@ +/* +Copyright 2025 Flant JSC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +const ( + PhaseCreated = "Created" + PhasePending = "Pending" + PhaseResizing = "Resizing" + PhaseFailed = "Failed" + PhaseNotReady = "NotReady" + PhaseReady = "Ready" + PhaseTerminating = "Terminating" + + LLVSNameTag = "storage.deckhouse.io/lvmLogicalVolumeSnapshotName" +) diff --git a/api/v1alpha1/register.go b/api/v1alpha1/register.go index 41750972..a9e63312 100644 --- a/api/v1alpha1/register.go +++ b/api/v1alpha1/register.go @@ -37,20 +37,22 @@ var ( AddToScheme = SchemeBuilder.AddToScheme ) +var knownTypes = []runtime.Object{ + &BlockDevice{}, + &BlockDeviceList{}, + &LVMVolumeGroup{}, + &LVMVolumeGroupList{}, + &LVMLogicalVolume{}, + &LVMLogicalVolumeList{}, + &LVMVolumeGroupSet{}, + &LVMVolumeGroupSetList{}, + &LVMLogicalVolumeSnapshot{}, + &LVMLogicalVolumeSnapshotList{}, +} + // Adds the list of known types to Scheme. func addKnownTypes(scheme *runtime.Scheme) error { - scheme.AddKnownTypes(SchemeGroupVersion, - &BlockDevice{}, - &BlockDeviceList{}, - &LVMVolumeGroup{}, - &LVMVolumeGroupList{}, - &LVMLogicalVolume{}, - &LVMLogicalVolumeList{}, - &LVMLogicalVolumeSnapshot{}, - &LVMLogicalVolumeSnapshotList{}, - &LVMVolumeGroupSet{}, - &LVMVolumeGroupSetList{}, - ) + scheme.AddKnownTypes(SchemeGroupVersion, knownTypes...) metav1.AddToGroupVersion(scheme, SchemeGroupVersion) return nil } diff --git a/api/v1alpha1/zz_generated_lvm_logical_volume_snapshot.deepcopy.go b/api/v1alpha1/zz_generated_lvm_logical_volume_snapshot.deepcopy.go index 9cc347d7..6d5d8438 100644 --- a/api/v1alpha1/zz_generated_lvm_logical_volume_snapshot.deepcopy.go +++ b/api/v1alpha1/zz_generated_lvm_logical_volume_snapshot.deepcopy.go @@ -1,5 +1,4 @@ //go:build !ignore_autogenerated -// +build !ignore_autogenerated /* Copyright 2024 Flant JSC diff --git a/images/agent/src/cmd/llvs_ce.go b/images/agent/src/cmd/llvs_ce.go new file mode 100644 index 00000000..4a6f0b74 --- /dev/null +++ b/images/agent/src/cmd/llvs_ce.go @@ -0,0 +1,35 @@ +//go:build ce + +/* +Copyright 2025 Flant JSC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "sigs.k8s.io/controller-runtime/pkg/manager" + + "agent/internal/cache" + "agent/internal/config" + "agent/internal/logger" + "agent/internal/monitoring" +) + +func addLLVSReconciler( + _ manager.Manager, + _ logger.Logger, + _ monitoring.Metrics, + _ *cache.Cache, + _ *config.Config, +) { + // noop +} diff --git a/images/agent/src/cmd/llvs_ee.go b/images/agent/src/cmd/llvs_ee.go new file mode 100644 index 00000000..1fd4ede6 --- /dev/null +++ b/images/agent/src/cmd/llvs_ee.go @@ -0,0 +1,59 @@ +//go:build !ce + +/* +Copyright 2025 Flant JSC +Licensed under the Deckhouse Platform Enterprise Edition (EE) license. +See https://github.com/deckhouse/deckhouse/blob/main/ee/LICENSE +*/ + +package main + +import ( + "os" + + "github.com/deckhouse/sds-node-configurator/lib/go/common/pkg/feature" + "sigs.k8s.io/controller-runtime/pkg/manager" + + "agent/internal/cache" + "agent/internal/config" + "agent/internal/controller" + "agent/internal/controller/llvs" + "agent/internal/logger" + "agent/internal/monitoring" +) + +func addLLVSReconciler( + mgr manager.Manager, + log logger.Logger, + metrics monitoring.Metrics, + sdsCache *cache.Cache, + cfgParams *config.Config, +) { + if !feature.SnapshotsEnabled() { + log.Info("[addLLVSReconciler] Snapshot feature is disabled") + return + } + + log.Info("[addLLVSReconciler] Snapshot feature is enabled. Adding LLVS reconciler") + + err := controller.AddReconciler( + mgr, + log, + llvs.NewReconciler( + mgr.GetClient(), + log, + metrics, + sdsCache, + llvs.ReconcilerConfig{ + NodeName: cfgParams.NodeName, + LLVRequeueInterval: cfgParams.LLVRequeueInterval, + VolumeGroupScanInterval: cfgParams.VolumeGroupScanInterval, + LLVSRequeueInterval: cfgParams.LLVSRequeueInterval, + }, + ), + ) + if err != nil { + log.Error(err, "[main] unable to start llvs.NewReconciler") + os.Exit(1) + } +} diff --git a/images/agent/src/cmd/main.go b/images/agent/src/cmd/main.go index e0a4df6e..96a90e26 100644 --- a/images/agent/src/cmd/main.go +++ b/images/agent/src/cmd/main.go @@ -23,6 +23,7 @@ import ( goruntime "runtime" "github.com/deckhouse/sds-node-configurator/api/v1alpha1" + "github.com/deckhouse/sds-node-configurator/lib/go/common/pkg/feature" v1 "k8s.io/api/core/v1" sv1 "k8s.io/api/storage/v1" extv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" @@ -38,7 +39,6 @@ import ( "agent/internal/controller/bd" "agent/internal/controller/llv" "agent/internal/controller/llv_extender" - "agent/internal/controller/llvs" "agent/internal/controller/lvg" "agent/internal/kubutils" "agent/internal/logger" @@ -74,6 +74,8 @@ func main() { log.Info(fmt.Sprintf("[main] Go Version:%s ", goruntime.Version())) log.Info(fmt.Sprintf("[main] OS/Arch:Go OS/Arch:%s/%s ", goruntime.GOOS, goruntime.GOARCH)) + log.Info(fmt.Sprintf("[main] Feature SnapshotsEnabled: %t", feature.SnapshotsEnabled())) + log.Info("[main] CfgParams has been successfully created") log.Info(fmt.Sprintf("[main] %s = %s", config.LogLevel, cfgParams.Loglevel)) log.Info(fmt.Sprintf("[main] %s = %s", config.NodeName, cfgParams.NodeName)) @@ -234,26 +236,7 @@ func main() { os.Exit(1) } - err = controller.AddReconciler( - mgr, - log, - llvs.NewReconciler( - mgr.GetClient(), - log, - metrics, - sdsCache, - llvs.ReconcilerConfig{ - NodeName: cfgParams.NodeName, - LLVRequeueInterval: cfgParams.LLVRequeueInterval, - VolumeGroupScanInterval: cfgParams.VolumeGroupScanInterval, - LLVSRequeueInterval: cfgParams.LLVSRequeueInterval, - }, - ), - ) - if err != nil { - log.Error(err, "[main] unable to start llvs.NewReconciler") - os.Exit(1) - } + addLLVSReconciler(mgr, log, metrics, sdsCache, cfgParams) if err = mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { log.Error(err, "[main] unable to mgr.AddHealthzCheck") diff --git a/images/agent/src/go.mod b/images/agent/src/go.mod index 38086fb1..ceb3fd0b 100644 --- a/images/agent/src/go.mod +++ b/images/agent/src/go.mod @@ -1,53 +1,57 @@ module agent -go 1.22.2 +go 1.23.4 + +toolchain go1.23.5 require ( - github.com/deckhouse/sds-node-configurator/api v0.0.0-20250114161813-c1a8b09cd47d + github.com/deckhouse/sds-node-configurator/api v0.0.0-20250130211935-b68366dfd0f8 + github.com/deckhouse/sds-node-configurator/lib/go/common v0.0.0-00010101000000-000000000000 github.com/go-logr/logr v1.4.2 github.com/google/go-cmp v0.6.0 github.com/gosimple/slug v1.14.0 - github.com/onsi/ginkgo/v2 v2.19.0 - github.com/onsi/gomega v1.33.1 + github.com/onsi/ginkgo/v2 v2.21.0 + github.com/onsi/gomega v1.35.1 github.com/pilebones/go-udev v0.9.0 github.com/prometheus/client_golang v1.19.1 github.com/stretchr/testify v1.9.0 - k8s.io/api v0.31.0 - k8s.io/apiextensions-apiserver v0.31.0 - k8s.io/apimachinery v0.31.3 - k8s.io/client-go v0.31.0 + k8s.io/api v0.32.1 + k8s.io/apiextensions-apiserver v0.32.0 + k8s.io/apimachinery v0.32.1 + k8s.io/client-go v0.32.1 k8s.io/klog/v2 v2.130.1 - k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 - sigs.k8s.io/controller-runtime v0.19.0 + k8s.io/utils v0.0.0-20241210054802-24370beab758 + sigs.k8s.io/controller-runtime v0.20.1 ) replace github.com/deckhouse/sds-node-configurator/api => ../../../api +replace github.com/deckhouse/sds-node-configurator/lib/go/common => ../../../lib/go/common + require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/emicklei/go-restful/v3 v3.12.1 // indirect github.com/evanphx/json-patch v5.6.0+incompatible // indirect - github.com/evanphx/json-patch/v5 v5.9.0 // indirect + github.com/evanphx/json-patch/v5 v5.9.11 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect - github.com/go-openapi/jsonpointer v0.20.0 // indirect - github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/swag v0.22.4 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/jsonreference v0.21.0 // indirect + github.com/go-openapi/swag v0.23.0 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect - github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/btree v1.1.3 // indirect + github.com/google/gnostic-models v0.6.9 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af // indirect + github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db // indirect github.com/google/uuid v1.6.0 // indirect github.com/gosimple/unidecode v1.0.1 // indirect - github.com/imdario/mergo v0.3.16 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/mailru/easyjson v0.7.7 // indirect + github.com/mailru/easyjson v0.9.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect @@ -58,22 +62,21 @@ require ( github.com/prometheus/procfs v0.15.1 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/x448/float16 v0.8.4 // indirect - golang.org/x/exp v0.0.0-20231127185646-65229373498e // indirect - golang.org/x/net v0.33.0 // indirect - golang.org/x/oauth2 v0.21.0 // indirect - golang.org/x/sys v0.28.0 // indirect - golang.org/x/term v0.27.0 // indirect - golang.org/x/text v0.21.0 // indirect - golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect + golang.org/x/net v0.35.0 // indirect + golang.org/x/oauth2 v0.26.0 // indirect + golang.org/x/sync v0.11.0 // indirect + golang.org/x/sys v0.30.0 // indirect + golang.org/x/term v0.29.0 // indirect + golang.org/x/text v0.22.0 // indirect + golang.org/x/time v0.10.0 // indirect + golang.org/x/tools v0.26.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/protobuf v1.34.2 // indirect + google.golang.org/protobuf v1.36.5 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect - sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect + k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 // indirect + sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.5.0 // indirect sigs.k8s.io/yaml v1.4.0 // indirect ) diff --git a/images/agent/src/go.sum b/images/agent/src/go.sum index 8c40072d..f7b05204 100644 --- a/images/agent/src/go.sum +++ b/images/agent/src/go.sum @@ -2,17 +2,16 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= -github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU= +github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg= -github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= +github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU= +github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= @@ -21,40 +20,36 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonpointer v0.20.0 h1:ESKJdU9ASRfaPNOPRx12IUyA1vn3R9GiE3KYD14BXdQ= -github.com/go-openapi/jsonpointer v0.20.0/go.mod h1:6PGzBjjIIumbLYysB73Klnms1mwnU4G3YHOECG3CedA= -github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= -github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= -github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= +github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= -github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= +github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= +github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw= +github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM= -github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= +github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo= +github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gosimple/slug v1.14.0 h1:RtTL/71mJNDfpUbCOmnf/XFkzKRtD6wL6Uy+3akm4Es= github.com/gosimple/slug v1.14.0/go.mod h1:UiRaFH+GEilHstLUmcBgWcI42viBN7mAb818JrYOeFQ= github.com/gosimple/unidecode v1.0.1 h1:hZzFTMMqSswvf0LBJZCZgThIZrpDHFXux9KeGmn6T/o= github.com/gosimple/unidecode v1.0.1/go.mod h1:CP0Cr1Y1kogOtx0bJblKzsVWrqYaqfNOnHzpgWw4Awc= -github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= -github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -68,8 +63,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= +github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -77,10 +72,10 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= -github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= -github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= -github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= +github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM= +github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= +github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4= +github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= github.com/pilebones/go-udev v0.9.0 h1:N1uEO/SxUwtIctc0WLU0t69JeBxIYEYnj8lT/Nabl9Q= github.com/pilebones/go-udev v0.9.0/go.mod h1:T2eI2tUSK0hA2WS5QLjXJUfQkluZQu+18Cqvem3CaXI= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -101,12 +96,7 @@ github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99 github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= @@ -117,53 +107,53 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/exp v0.0.0-20231127185646-65229373498e h1:Gvh4YaCaXNs6dKTlfgismwWZKyjVZXwOPfIyUaqU3No= -golang.org/x/exp v0.0.0-20231127185646-65229373498e/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= -golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= -golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= -golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= +golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= +golang.org/x/oauth2 v0.26.0 h1:afQXWNNaeC4nvZ0Ed9XvCCzXM6UHJG7iCg0W4fPqSBE= +golang.org/x/oauth2 v0.26.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= +golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= -golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= +golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4= +golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= +golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= +google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -171,31 +161,27 @@ gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSP gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.31.0 h1:b9LiSjR2ym/SzTOlfMHm1tr7/21aD7fSkqgD/CVJBCo= -k8s.io/api v0.31.0/go.mod h1:0YiFF+JfFxMM6+1hQei8FY8M7s1Mth+z/q7eF1aJkTE= -k8s.io/apiextensions-apiserver v0.31.0 h1:fZgCVhGwsclj3qCw1buVXCV6khjRzKC5eCFt24kyLSk= -k8s.io/apiextensions-apiserver v0.31.0/go.mod h1:b9aMDEYaEe5sdK+1T0KU78ApR/5ZVp4i56VacZYEHxk= -k8s.io/apimachinery v0.31.3 h1:6l0WhcYgasZ/wk9ktLq5vLaoXJJr5ts6lkaQzgeYPq4= -k8s.io/apimachinery v0.31.3/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= -k8s.io/client-go v0.31.0 h1:QqEJzNjbN2Yv1H79SsS+SWnXkBgVu4Pj3CJQgbx0gI8= -k8s.io/client-go v0.31.0/go.mod h1:Y9wvC76g4fLjmU0BA+rV+h2cncoadjvjjkkIGoTLcGU= +k8s.io/api v0.32.1 h1:f562zw9cy+GvXzXf0CKlVQ7yHJVYzLfL6JAS4kOAaOc= +k8s.io/api v0.32.1/go.mod h1:/Yi/BqkuueW1BgpoePYBRdDYfjPF5sgTr5+YqDZra5k= +k8s.io/apiextensions-apiserver v0.32.0 h1:S0Xlqt51qzzqjKPxfgX1xh4HBZE+p8KKBq+k2SWNOE0= +k8s.io/apiextensions-apiserver v0.32.0/go.mod h1:86hblMvN5yxMvZrZFX2OhIHAuFIMJIZ19bTvzkP+Fmw= +k8s.io/apimachinery v0.32.1 h1:683ENpaCBjma4CYqsmZyhEzrGz6cjn1MY/X2jB2hkZs= +k8s.io/apimachinery v0.32.1/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= +k8s.io/client-go v0.32.1 h1:otM0AxdhdBIaQh7l1Q0jQpmo7WOFIk5FFa4bg6YMdUU= +k8s.io/client-go v0.32.1/go.mod h1:aTTKZY7MdxUaJ/KiUs8D+GssR9zJZi77ZqtzcGXIiDg= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= -k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= -k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= -k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/controller-runtime v0.19.0 h1:nWVM7aq+Il2ABxwiCizrVDSlmDcshi9llbaFbC0ji/Q= -sigs.k8s.io/controller-runtime v0.19.0/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4= -sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= -sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= -sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= +k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 h1:hcha5B1kVACrLujCKLbr8XWMxCxzQx42DY8QKYJrDLg= +k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7/go.mod h1:GewRfANuJ70iYzvn+i4lezLDAFzvjxZYK1gn1lWcfas= +k8s.io/utils v0.0.0-20241210054802-24370beab758 h1:sdbE21q2nlQtFh65saZY+rRM6x6aJJI8IUa1AmH/qa0= +k8s.io/utils v0.0.0-20241210054802-24370beab758/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/controller-runtime v0.20.1 h1:JbGMAG/X94NeM3xvjenVUaBjy6Ui4Ogd/J5ZtjZnHaE= +sigs.k8s.io/controller-runtime v0.20.1/go.mod h1:BrP3w158MwvB3ZbNpaAcIKkHQ7YGpYnzpoSTZ8E14WU= +sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= +sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +sigs.k8s.io/structured-merge-diff/v4 v4.5.0 h1:nbCitCK2hfnhyiKo6uf2HxUPTCodY6Qaf85SbDIaMBk= +sigs.k8s.io/structured-merge-diff/v4 v4.5.0/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/images/agent/src/internal/const.go b/images/agent/src/internal/const.go index 583461bb..a7238143 100644 --- a/images/agent/src/internal/const.go +++ b/images/agent/src/internal/const.go @@ -77,16 +77,6 @@ const ( Thick = "Thick" Thin = "Thin" - LLVStatusPhaseCreated = "Created" - LLVStatusPhasePending = "Pending" - LLVStatusPhaseResizing = "Resizing" - LLVStatusPhaseFailed = "Failed" - - LLVSStatusPhaseCreated = "Created" - LLVSStatusPhasePending = "Pending" - LLVSStatusPhaseFailed = "Failed" - LLVSNameTag = "storage.deckhouse.io/lvmLogicalVolumeSnapshotName" - Local = "Local" Shared = "Shared" diff --git a/images/agent/src/internal/controller/llv/llvs_ce.go b/images/agent/src/internal/controller/llv/llvs_ce.go new file mode 100644 index 00000000..2b37f7cc --- /dev/null +++ b/images/agent/src/internal/controller/llv/llvs_ce.go @@ -0,0 +1,27 @@ +//go:build ce + +/* +Copyright 2025 Flant JSC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package llv + +import ( + "context" + "errors" + + "github.com/deckhouse/sds-node-configurator/api/v1alpha1" +) + +func (r *Reconciler) handleLLVSSource(_ context.Context, _ *v1alpha1.LVMLogicalVolume, _ *v1alpha1.LVMVolumeGroup) (string, bool, error) { + return "", false, errors.New("LVMLocalVolumeSnapshot as a source is not supported in your edition") +} diff --git a/images/agent/src/internal/controller/llv/llvs_ee.go b/images/agent/src/internal/controller/llv/llvs_ee.go new file mode 100644 index 00000000..b4753d5a --- /dev/null +++ b/images/agent/src/internal/controller/llv/llvs_ee.go @@ -0,0 +1,41 @@ +//go:build !ce + +/* +Copyright 2025 Flant JSC +Licensed under the Deckhouse Platform Enterprise Edition (EE) license. +See https://github.com/deckhouse/deckhouse/blob/main/ee/LICENSE +*/ + +package llv + +import ( + "context" + "errors" + "fmt" + + "github.com/deckhouse/sds-node-configurator/api/v1alpha1" + "github.com/deckhouse/sds-node-configurator/lib/go/common/pkg/feature" + "k8s.io/apimachinery/pkg/types" + + "agent/internal/utils" +) + +func (r *Reconciler) handleLLVSSource(ctx context.Context, llv *v1alpha1.LVMLogicalVolume, lvg *v1alpha1.LVMVolumeGroup) (string, bool, error) { + if !feature.SnapshotsEnabled() { + return "", false, errors.New("LVMLocalVolumeSnapshot as a source is not supported: snapshot feature is disabled") + } + + sourceLLVS := &v1alpha1.LVMLogicalVolumeSnapshot{} + if err := r.cl.Get(ctx, types.NamespacedName{Name: llv.Spec.Source.Name}, sourceLLVS); err != nil { + r.log.Error(err, fmt.Sprintf("[reconcileLLVCreateFunc] unable to get source LVMLogicalVolumeSnapshot %s for the LVMLogicalVolume %s", llv.Spec.Source.Name, llv.Name)) + return "", true, err + } + + if sourceLLVS.Status.ActualVGNameOnTheNode != lvg.Spec.ActualVGNameOnTheNode || sourceLLVS.Status.NodeName != lvg.Spec.Local.NodeName { + return "", false, errors.New("restored volume should be in the same volume group as the origin volume") + } + + cmd, err := utils.CreateThinLogicalVolumeFromSource(llv.Spec.ActualLVNameOnTheNode, sourceLLVS.Status.ActualVGNameOnTheNode, sourceLLVS.Spec.ActualSnapshotNameOnTheNode) + + return cmd, err != nil, err +} diff --git a/images/agent/src/internal/controller/llv/reconciler.go b/images/agent/src/internal/controller/llv/reconciler.go index afa1b0c0..5e8b6cfb 100644 --- a/images/agent/src/internal/controller/llv/reconciler.go +++ b/images/agent/src/internal/controller/llv/reconciler.go @@ -1,3 +1,19 @@ +/* +Copyright 2024 Flant JSC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package llv import ( @@ -117,7 +133,7 @@ func (r *Reconciler) Reconcile( err = r.llvCl.UpdatePhaseIfNeeded( ctx, llv, - internal.LLVStatusPhaseFailed, + v1alpha1.PhaseFailed, fmt.Sprintf("LVMVolumeGroup %s not found", llv.Spec.LVMVolumeGroupName), ) if err != nil { @@ -133,7 +149,7 @@ func (r *Reconciler) Reconcile( err = r.llvCl.UpdatePhaseIfNeeded( ctx, llv, - internal.LLVStatusPhaseFailed, + v1alpha1.PhaseFailed, fmt.Sprintf("Unable to get selected LVMVolumeGroup, err: %s", err.Error()), ) if err != nil { @@ -170,7 +186,7 @@ func (r *Reconciler) Reconcile( valid, reason := r.validateLVMLogicalVolume(llv, lvg) if !valid { r.log.Warning(fmt.Sprintf("[ReconcileLVMLogicalVolume] the LVMLogicalVolume %s is not valid, reason: %s", llv.Name, reason)) - err = r.llvCl.UpdatePhaseIfNeeded(ctx, llv, internal.LLVStatusPhaseFailed, reason) + err = r.llvCl.UpdatePhaseIfNeeded(ctx, llv, v1alpha1.PhaseFailed, reason) if err != nil { r.log.Error(err, fmt.Sprintf("[ReconcileLVMLogicalVolume] unable to update the LVMLogicalVolume %s", llv.Name)) return controller.Result{}, err @@ -183,7 +199,7 @@ func (r *Reconciler) Reconcile( shouldRequeue, err := r.ReconcileLVMLogicalVolume(ctx, llv, lvg) if err != nil { r.log.Error(err, fmt.Sprintf("[RunLVMLogicalVolumeWatcherController] an error occurred while reconciling the LVMLogicalVolume: %s", llv.Name)) - updErr := r.llvCl.UpdatePhaseIfNeeded(ctx, llv, internal.LLVStatusPhaseFailed, err.Error()) + updErr := r.llvCl.UpdatePhaseIfNeeded(ctx, llv, v1alpha1.PhaseFailed, err.Error()) if updErr != nil { r.log.Error(updErr, fmt.Sprintf("[RunLVMLogicalVolumeWatcherController] unable to update the LVMLogicalVolume %s", llv.Name)) return controller.Result{}, updErr @@ -213,9 +229,9 @@ func (r *Reconciler) ReconcileLVMLogicalVolume(ctx context.Context, llv *v1alpha return r.reconcileLLVDeleteFunc(ctx, llv, lvg) default: r.log.Info(fmt.Sprintf("[runEventReconcile] the LVMLogicalVolume %s has compeleted configuration and should not be reconciled", llv.Name)) - if llv.Status.Phase != internal.LLVStatusPhaseCreated { - r.log.Warning(fmt.Sprintf("[runEventReconcile] the LVMLogicalVolume %s should not be reconciled but has an unexpected phase: %s. Setting the phase to %s", llv.Name, llv.Status.Phase, internal.LLVStatusPhaseCreated)) - err := r.llvCl.UpdatePhaseIfNeeded(ctx, llv, internal.LLVStatusPhaseCreated, "") + if llv.Status.Phase != v1alpha1.PhaseCreated { + r.log.Warning(fmt.Sprintf("[runEventReconcile] the LVMLogicalVolume %s should not be reconciled but has an unexpected phase: %s. Setting the phase to %s", llv.Name, llv.Status.Phase, v1alpha1.PhaseCreated)) + err := r.llvCl.UpdatePhaseIfNeeded(ctx, llv, v1alpha1.PhaseCreated, "") if err != nil { return true, err } @@ -234,7 +250,7 @@ func (r *Reconciler) reconcileLLVCreateFunc( // this check prevents infinite resource updating after retries if llv.Status == nil { - err := r.llvCl.UpdatePhaseIfNeeded(ctx, llv, internal.LLVStatusPhasePending, "") + err := r.llvCl.UpdatePhaseIfNeeded(ctx, llv, v1alpha1.PhasePending, "") if err != nil { r.log.Error(err, fmt.Sprintf("[reconcileLLVCreateFunc] unable to update the LVMLogicalVolume %s", llv.Name)) return true, err @@ -280,17 +296,11 @@ func (r *Reconciler) reconcileLLVCreateFunc( cmd, err = utils.CreateThinLogicalVolumeFromSource(llv.Spec.ActualLVNameOnTheNode, lvg.Spec.ActualVGNameOnTheNode, sourceLLV.Spec.ActualLVNameOnTheNode) case llv.Spec.Source.Kind == "LVMLogicalVolumeSnapshot": - sourceLLVS := &v1alpha1.LVMLogicalVolumeSnapshot{} - if err := r.cl.Get(ctx, types.NamespacedName{Name: llv.Spec.Source.Name}, sourceLLVS); err != nil { - r.log.Error(err, fmt.Sprintf("[reconcileLLVCreateFunc] unable to get source LVMLogicalVolumeSnapshot %s for the LVMLogicalVolume %s", llv.Spec.Source.Name, llv.Name)) - return true, err - } - - if sourceLLVS.Status.ActualVGNameOnTheNode != lvg.Spec.ActualVGNameOnTheNode || sourceLLVS.Status.NodeName != lvg.Spec.Local.NodeName { - return false, errors.New("restored volume should be in the same volume group as the origin volume") + cmdTmp, shouldRequeue, err := r.handleLLVSSource(ctx, llv, lvg) + if err != nil { + return shouldRequeue, err } - - cmd, err = utils.CreateThinLogicalVolumeFromSource(llv.Spec.ActualLVNameOnTheNode, sourceLLVS.Status.ActualVGNameOnTheNode, sourceLLVS.Spec.ActualSnapshotNameOnTheNode) + cmd = cmdTmp } r.log.Debug(fmt.Sprintf("[reconcileLLVCreateFunc] ran cmd: %s", cmd)) if err != nil { @@ -328,7 +338,7 @@ func (r *Reconciler) reconcileLLVUpdateFunc( // status might be nil if a user creates the resource with LV name which matches existing LV on the node if llv.Status == nil { - err := r.llvCl.UpdatePhaseIfNeeded(ctx, llv, internal.LLVStatusPhasePending, "") + err := r.llvCl.UpdatePhaseIfNeeded(ctx, llv, v1alpha1.PhasePending, "") if err != nil { r.log.Error(err, fmt.Sprintf("[reconcileLLVUpdateFunc] unable to update the LVMLogicalVolume %s", llv.Name)) return true, err @@ -374,8 +384,8 @@ func (r *Reconciler) reconcileLLVUpdateFunc( r.log.Info(fmt.Sprintf("[reconcileLLVUpdateFunc] the LVMLogicalVolume %s should be resized", llv.Name)) // this check prevents infinite resource updates after retry - if llv.Status.Phase != internal.LLVStatusPhaseFailed { - err := r.llvCl.UpdatePhaseIfNeeded(ctx, llv, internal.LLVStatusPhaseResizing, "") + if llv.Status.Phase != v1alpha1.PhaseFailed { + err := r.llvCl.UpdatePhaseIfNeeded(ctx, llv, v1alpha1.PhaseResizing, "") if err != nil { r.log.Error(err, fmt.Sprintf("[reconcileLLVUpdateFunc] unable to update the LVMLogicalVolume %s", llv.Name)) return true, err diff --git a/images/agent/src/internal/controller/llv/reconciler_test.go b/images/agent/src/internal/controller/llv/reconciler_test.go index 50c2bdf9..3c91d78b 100644 --- a/images/agent/src/internal/controller/llv/reconciler_test.go +++ b/images/agent/src/internal/controller/llv/reconciler_test.go @@ -1,3 +1,19 @@ +/* +Copyright 2024 Flant JSC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package llv import ( @@ -279,7 +295,7 @@ func TestLVMLogicaVolumeWatcher(t *testing.T) { ActualLVNameOnTheNode: lvName, }, Status: &v1alpha1.LVMLogicalVolumeStatus{ - Phase: internal.LLVStatusPhaseCreated, + Phase: v1alpha1.PhaseCreated, }, } r.sdsCache.StoreLVs([]internal.LVData{ @@ -300,7 +316,7 @@ func TestLVMLogicaVolumeWatcher(t *testing.T) { llv := &v1alpha1.LVMLogicalVolume{ ObjectMeta: v1.ObjectMeta{DeletionTimestamp: &v1.Time{}}, Status: &v1alpha1.LVMLogicalVolumeStatus{ - Phase: internal.LLVStatusPhaseCreated, + Phase: v1alpha1.PhaseCreated, }, } @@ -320,7 +336,7 @@ func TestLVMLogicaVolumeWatcher(t *testing.T) { ActualLVNameOnTheNode: lvName, }, Status: &v1alpha1.LVMLogicalVolumeStatus{ - Phase: internal.LLVStatusPhaseCreated, + Phase: v1alpha1.PhaseCreated, }, } @@ -336,7 +352,7 @@ func TestLVMLogicaVolumeWatcher(t *testing.T) { ActualLVNameOnTheNode: lvName, }, Status: &v1alpha1.LVMLogicalVolumeStatus{ - Phase: internal.LLVStatusPhaseCreated, + Phase: v1alpha1.PhaseCreated, }, } r.sdsCache.StoreLVs([]internal.LVData{ @@ -358,7 +374,7 @@ func TestLVMLogicaVolumeWatcher(t *testing.T) { ActualLVNameOnTheNode: lvName, }, Status: &v1alpha1.LVMLogicalVolumeStatus{ - Phase: internal.LLVStatusPhaseCreated, + Phase: v1alpha1.PhaseCreated, }, } should := r.shouldReconcileByCreateFunc(vgName, llv) @@ -387,7 +403,7 @@ func TestLVMLogicaVolumeWatcher(t *testing.T) { ActualLVNameOnTheNode: lvName, }, Status: &v1alpha1.LVMLogicalVolumeStatus{ - Phase: internal.LLVStatusPhaseCreated, + Phase: v1alpha1.PhaseCreated, }, } r.sdsCache.StoreLVs([]internal.LVData{ @@ -408,7 +424,7 @@ func TestLVMLogicaVolumeWatcher(t *testing.T) { ActualLVNameOnTheNode: lvName, }, Status: &v1alpha1.LVMLogicalVolumeStatus{ - Phase: internal.LLVStatusPhaseCreated, + Phase: v1alpha1.PhaseCreated, }, } should := r.shouldReconcileByUpdateFunc(vgName, llv) @@ -444,7 +460,7 @@ func TestLVMLogicaVolumeWatcher(t *testing.T) { Name: "test", }, Status: &v1alpha1.LVMLogicalVolumeStatus{ - Phase: internal.LLVStatusPhaseCreated, + Phase: v1alpha1.PhaseCreated, Reason: "", }, } @@ -462,7 +478,7 @@ func TestLVMLogicaVolumeWatcher(t *testing.T) { } }() - err = r.llvCl.UpdatePhaseIfNeeded(ctx, llv, internal.LLVStatusPhaseFailed, reason) + err = r.llvCl.UpdatePhaseIfNeeded(ctx, llv, v1alpha1.PhaseFailed, reason) if assert.NoError(t, err) { newLLV := &v1alpha1.LVMLogicalVolume{} err = r.cl.Get(ctx, client.ObjectKey{ @@ -470,7 +486,7 @@ func TestLVMLogicaVolumeWatcher(t *testing.T) { Namespace: "", }, newLLV) - assert.Equal(t, newLLV.Status.Phase, internal.LLVStatusPhaseFailed) + assert.Equal(t, newLLV.Status.Phase, v1alpha1.PhaseFailed) assert.Equal(t, newLLV.Status.Reason, reason) } }) @@ -574,7 +590,7 @@ func TestLVMLogicaVolumeWatcher(t *testing.T) { Size: oldSize.String(), }, Status: &v1alpha1.LVMLogicalVolumeStatus{ - Phase: internal.LLVStatusPhasePending, + Phase: v1alpha1.PhasePending, Reason: "", ActualSize: *oldSize, }, @@ -603,12 +619,12 @@ func TestLVMLogicaVolumeWatcher(t *testing.T) { } if assert.NotNil(t, oldLLV) { - assert.Equal(t, internal.LLVStatusPhasePending, oldLLV.Status.Phase) + assert.Equal(t, v1alpha1.PhasePending, oldLLV.Status.Phase) assert.Equal(t, oldSize.Value(), oldLLV.Status.ActualSize.Value()) } oldLLV.Spec.Size = newSize.String() - oldLLV.Status.Phase = internal.LLVStatusPhaseCreated + oldLLV.Status.Phase = v1alpha1.PhaseCreated oldLLV.Status.ActualSize = *newSize err = r.updateLVMLogicalVolumeSpec(ctx, oldLLV) @@ -622,7 +638,7 @@ func TestLVMLogicaVolumeWatcher(t *testing.T) { return } - assert.Equal(t, internal.LLVStatusPhasePending, newLLV.Status.Phase) + assert.Equal(t, v1alpha1.PhasePending, newLLV.Status.Phase) assert.Equal(t, oldSize.Value(), newLLV.Status.ActualSize.Value()) } }) @@ -646,7 +662,7 @@ func TestLVMLogicaVolumeWatcher(t *testing.T) { Size: oldSize.String(), }, Status: &v1alpha1.LVMLogicalVolumeStatus{ - Phase: internal.LLVStatusPhasePending, + Phase: v1alpha1.PhasePending, Reason: "", ActualSize: *oldSize, }, @@ -675,7 +691,7 @@ func TestLVMLogicaVolumeWatcher(t *testing.T) { } if assert.NotNil(t, oldLLV) { - assert.Equal(t, internal.LLVStatusPhasePending, oldLLV.Status.Phase) + assert.Equal(t, v1alpha1.PhasePending, oldLLV.Status.Phase) assert.Equal(t, oldSize.Value(), oldLLV.Status.ActualSize.Value()) } @@ -693,7 +709,7 @@ func TestLVMLogicaVolumeWatcher(t *testing.T) { } assert.Equal(t, oldSize.String(), newLLV.Spec.Size) - assert.Equal(t, internal.LLVStatusPhaseCreated, newLLV.Status.Phase) + assert.Equal(t, v1alpha1.PhaseCreated, newLLV.Status.Phase) assert.Equal(t, newSize.Value(), newLLV.Status.ActualSize.Value()) } }) diff --git a/images/agent/src/internal/controller/llv_extender/reconciler.go b/images/agent/src/internal/controller/llv_extender/reconciler.go index 062645f6..a7c7d41f 100644 --- a/images/agent/src/internal/controller/llv_extender/reconciler.go +++ b/images/agent/src/internal/controller/llv_extender/reconciler.go @@ -155,7 +155,7 @@ func (r *Reconciler) ReconcileLVMLogicalVolumeExtension( if lv == nil { err = fmt.Errorf("lv %s not found", llv.Spec.ActualLVNameOnTheNode) r.log.Error(err, fmt.Sprintf("[ReconcileLVMLogicalVolumeExtension] unable to find LV %s of the LVMLogicalVolume %s", llv.Spec.ActualLVNameOnTheNode, llv.Name)) - err = r.llvCl.UpdatePhaseIfNeeded(ctx, &llv, internal.LLVStatusPhaseFailed, err.Error()) + err = r.llvCl.UpdatePhaseIfNeeded(ctx, &llv, v1alpha1.PhaseFailed, err.Error()) if err != nil { r.log.Error(err, fmt.Sprintf("[ReconcileLVMLogicalVolumeExtension] unable to update the LVMLogicalVolume %s", llv.Name)) } @@ -177,7 +177,7 @@ func (r *Reconciler) ReconcileLVMLogicalVolumeExtension( if llvRequestedSize.Value()+internal.ResizeDelta.Value() > freeSpace.Value() { err = errors.New("not enough space") r.log.Error(err, fmt.Sprintf("[ReconcileLVMLogicalVolumeExtension] unable to extend the LV %s of the LVMLogicalVolume %s", llv.Spec.ActualLVNameOnTheNode, llv.Name)) - err = r.llvCl.UpdatePhaseIfNeeded(ctx, &llv, internal.LLVStatusPhaseFailed, fmt.Sprintf("unable to extend LV, err: %s", err.Error())) + err = r.llvCl.UpdatePhaseIfNeeded(ctx, &llv, v1alpha1.PhaseFailed, fmt.Sprintf("unable to extend LV, err: %s", err.Error())) if err != nil { r.log.Error(err, fmt.Sprintf("[ReconcileLVMLogicalVolumeExtension] unable to update the LVMLogicalVolume %s", llv.Name)) shouldRetry = true @@ -186,7 +186,7 @@ func (r *Reconciler) ReconcileLVMLogicalVolumeExtension( } r.log.Info(fmt.Sprintf("[ReconcileLVMLogicalVolumeExtension] the LVMLogicalVolume %s should be extended from %s to %s size", llv.Name, llv.Status.ActualSize.String(), llvRequestedSize.String())) - err = r.llvCl.UpdatePhaseIfNeeded(ctx, &llv, internal.LLVStatusPhaseResizing, "") + err = r.llvCl.UpdatePhaseIfNeeded(ctx, &llv, v1alpha1.PhaseResizing, "") if err != nil { r.log.Error(err, fmt.Sprintf("[ReconcileLVMLogicalVolumeExtension] unable to update the LVMLogicalVolume %s", llv.Name)) shouldRetry = true @@ -196,7 +196,7 @@ func (r *Reconciler) ReconcileLVMLogicalVolumeExtension( cmd, err := utils.ExtendLV(llvRequestedSize.Value(), lvg.Spec.ActualVGNameOnTheNode, llv.Spec.ActualLVNameOnTheNode) if err != nil { r.log.Error(err, fmt.Sprintf("[ReconcileLVMLogicalVolumeExtension] unable to extend LV %s of the LVMLogicalVolume %s, cmd: %s", llv.Spec.ActualLVNameOnTheNode, llv.Name, cmd)) - err = r.llvCl.UpdatePhaseIfNeeded(ctx, &llv, internal.LLVStatusPhaseFailed, fmt.Sprintf("unable to extend LV, err: %s", err.Error())) + err = r.llvCl.UpdatePhaseIfNeeded(ctx, &llv, v1alpha1.PhaseFailed, fmt.Sprintf("unable to extend LV, err: %s", err.Error())) if err != nil { r.log.Error(err, fmt.Sprintf("[ReconcileLVMLogicalVolumeExtension] unable to update the LVMLogicalVolume %s", llv.Name)) } @@ -226,7 +226,7 @@ func (r *Reconciler) ReconcileLVMLogicalVolumeExtension( r.log.Error(err, fmt.Sprintf("[ReconcileLVMLogicalVolumeExtension] unable to resize the LVMLogicalVolume %s", llv.Name)) shouldRetry = true - if err = r.llvCl.UpdatePhaseIfNeeded(ctx, &llv, internal.LLVStatusPhaseFailed, err.Error()); err != nil { + if err = r.llvCl.UpdatePhaseIfNeeded(ctx, &llv, v1alpha1.PhaseFailed, err.Error()); err != nil { r.log.Error(err, fmt.Sprintf("[ReconcileLVMLogicalVolumeExtension] unable to update the LVMLogicalVolume %s", llv.Name)) } continue diff --git a/images/agent/src/internal/controller/llvs/reconciler.go b/images/agent/src/internal/controller/llvs/reconciler_ee.go similarity index 95% rename from images/agent/src/internal/controller/llvs/reconciler.go rename to images/agent/src/internal/controller/llvs/reconciler_ee.go index 694f66b0..ecbaebf9 100644 --- a/images/agent/src/internal/controller/llvs/reconciler.go +++ b/images/agent/src/internal/controller/llvs/reconciler_ee.go @@ -1,3 +1,5 @@ +//go:build !ce + package llvs import ( @@ -116,9 +118,9 @@ func (r *Reconciler) reconcileLVMLogicalVolumeSnapshot( case llvs.DeletionTimestamp != nil: // delete return r.reconcileLLVSDeleteFunc(ctx, llvs) - case llvs.Status == nil || llvs.Status.Phase == internal.LLVSStatusPhasePending: + case llvs.Status == nil || llvs.Status.Phase == v1alpha1.PhasePending: return r.reconcileLLVSCreateFunc(ctx, llvs) - case llvs.Status.Phase == internal.LLVSStatusPhaseCreated: + case llvs.Status.Phase == v1alpha1.PhaseCreated: r.log.Info(fmt.Sprintf("the LVMLogicalVolumeSnapshot %s is already Created and should not be reconciled", llvs.Name)) default: r.log.Warning(fmt.Sprintf("skipping LLVS reconciliation, since it is in phase: %s", llvs.Status.Phase)) @@ -146,7 +148,7 @@ func (r *Reconciler) reconcileLLVSCreateFunc( if llv.Spec.Thin == nil { r.log.Error(nil, fmt.Sprintf("Failed reconciling LLVS %s, LLV %s is not Thin", llvs.Name, llv.Name)) llvs.Status = &v1alpha1.LVMLogicalVolumeSnapshotStatus{ - Phase: internal.LLVSStatusPhaseFailed, + Phase: v1alpha1.PhaseFailed, Reason: fmt.Sprintf("Source LLV %s is not Thin", llv.Name), } return false, r.cl.Status().Update(ctx, llvs) @@ -173,7 +175,7 @@ func (r *Reconciler) reconcileLLVSCreateFunc( if thinPoolIndex < 0 { r.log.Error(nil, fmt.Sprintf("LLVS %s thin pool %s is not found in LVG %s", llvs.Name, llv.Spec.Thin.PoolName, lvg.Name)) llvs.Status = &v1alpha1.LVMLogicalVolumeSnapshotStatus{ - Phase: internal.LLVSStatusPhasePending, + Phase: v1alpha1.PhasePending, Reason: fmt.Sprintf("Thin pool %s is not found in LVG %s", llv.Spec.Thin.PoolName, lvg.Name), } return true, r.cl.Status().Update(ctx, llvs) @@ -182,7 +184,7 @@ func (r *Reconciler) reconcileLLVSCreateFunc( if llv.Status == nil || llv.Status.ActualSize.Value() == 0 { r.log.Error(nil, fmt.Sprintf("Error reconciling LLVS %s, source LLV %s ActualSize is not known", llvs.Name, llv.Name)) llvs.Status = &v1alpha1.LVMLogicalVolumeSnapshotStatus{ - Phase: internal.LLVSStatusPhasePending, + Phase: v1alpha1.PhasePending, Reason: fmt.Sprintf("Source LLV %s ActualSize is not known", llv.Name), } return true, r.cl.Status().Update(ctx, llvs) @@ -197,7 +199,7 @@ func (r *Reconciler) reconcileLLVSCreateFunc( lvg.Status.ThinPools[thinPoolIndex].AvailableSpace.String(), )) llvs.Status = &v1alpha1.LVMLogicalVolumeSnapshotStatus{ - Phase: internal.LLVSStatusPhasePending, + Phase: v1alpha1.PhasePending, Reason: fmt.Sprintf( "Not enough space available in thin pool %s: need at least %s, got %s", llv.Spec.Thin.PoolName, @@ -212,7 +214,7 @@ func (r *Reconciler) reconcileLLVSCreateFunc( NodeName: lvg.Spec.Local.NodeName, ActualVGNameOnTheNode: lvg.Spec.ActualVGNameOnTheNode, ActualLVNameOnTheNode: llv.Spec.ActualLVNameOnTheNode, - Phase: internal.LLVSStatusPhasePending, + Phase: v1alpha1.PhasePending, Reason: "Creating volume", } @@ -247,7 +249,7 @@ func (r *Reconciler) reconcileLLVSCreateFunc( llvs.ActualSnapshotNameOnTheNode(), llvs.Status.ActualVGNameOnTheNode, llvs.Status.ActualLVNameOnTheNode, - utils.NewEnabledTags(internal.LLVSNameTag, llvs.Name), + utils.NewEnabledTags(v1alpha1.LLVSNameTag, llvs.Name), ) r.log.Debug(fmt.Sprintf("[reconcileLLVSCreateFunc] ran cmd: %s", cmd)) if err != nil { @@ -294,7 +296,7 @@ func (r *Reconciler) reconcileLLVSCreateFunc( llvs.Status.Size = *size llvs.Status.UsedSize = *usedSize - llvs.Status.Phase = internal.LLVSStatusPhaseCreated + llvs.Status.Phase = v1alpha1.PhaseCreated llvs.Status.Reason = "" err = r.cl.Status().Update(ctx, llvs) return false, err @@ -342,7 +344,7 @@ func (r *Reconciler) deleteLVIfNeeded(llvsName, llvsActualNameOnTheNode, vgActua return nil } - if ok, name := utils.ReadValueFromTags(lv.Data.LvTags, internal.LLVSNameTag); !ok { + if ok, name := utils.ReadValueFromTags(lv.Data.LvTags, v1alpha1.LLVSNameTag); !ok { r.log.Warning(fmt.Sprintf("[deleteLVIfNeeded] did not find required tags on LV %s in VG %s", llvsActualNameOnTheNode, vgActualNameOnTheNode)) return nil } else if name != llvsName { @@ -371,7 +373,7 @@ func (r *Reconciler) getObjectOrSetPendingStatus( ) error { if err := r.cl.Get(ctx, key, obj); err != nil { llvs.Status = &v1alpha1.LVMLogicalVolumeSnapshotStatus{ - Phase: internal.LLVSStatusPhasePending, + Phase: v1alpha1.PhasePending, Reason: fmt.Sprintf("Error while getting object %s: %v", obj.GetName(), err), } updErr := r.cl.Status().Update(ctx, llvs) diff --git a/images/agent/src/internal/utils/client_llv.go b/images/agent/src/internal/utils/client_llv.go index baead2bc..2551d973 100644 --- a/images/agent/src/internal/utils/client_llv.go +++ b/images/agent/src/internal/utils/client_llv.go @@ -8,7 +8,6 @@ import ( "k8s.io/apimachinery/pkg/api/resource" "sigs.k8s.io/controller-runtime/pkg/client" - "agent/internal" "agent/internal/logger" ) @@ -69,7 +68,7 @@ func (llvCl *LLVClient) UpdatePhaseToCreatedIfNeeded( } } - updateNeeded := llv.Status.Phase != internal.LLVStatusPhaseCreated || + updateNeeded := llv.Status.Phase != v1alpha1.PhaseCreated || llv.Status.ActualSize.Value() != actualSize.Value() || llv.Status.Reason != "" || llv.Status.Contiguous != contiguous @@ -79,7 +78,7 @@ func (llvCl *LLVClient) UpdatePhaseToCreatedIfNeeded( return nil } - llv.Status.Phase = internal.LLVStatusPhaseCreated + llv.Status.Phase = v1alpha1.PhaseCreated llv.Status.Reason = "" llv.Status.ActualSize = actualSize llv.Status.Contiguous = contiguous diff --git a/images/agent/werf.inc.yaml b/images/agent/werf.inc.yaml index 02a734c1..a58c50c4 100644 --- a/images/agent/werf.inc.yaml +++ b/images/agent/werf.inc.yaml @@ -1,5 +1,4 @@ {{ $binaries := "/opt/deckhouse/sds/lib/libblkid.so.1 /opt/deckhouse/sds/lib/libmount.so.1 /opt/deckhouse/sds/lib/libsmartcols.so.1 /opt/deckhouse/sds/bin/nsenter.static /opt/deckhouse/sds/lib/x86_64-linux-gnu/libudev.so.1 /opt/deckhouse/sds/lib/x86_64-linux-gnu/libcap.so.2 /opt/deckhouse/sds/bin/lsblk.dynamic /usr/lib/x86_64-linux-gnu/sys-root/lib64/ld-linux-x86-64.so.2" }} -{{ $UTIL_LINUX_VERSION := "2.39.3" }} # Do not remove. It's used in external tests. --- @@ -8,23 +7,23 @@ from: {{ $.Root.BASE_ALT_P11 }} final: false git: - - add: /images/{{ $.ImageName }}/src - to: /src/images/{{ $.ImageName }}/src - stageDependencies: - install: - - "**/*" - - add: /api - to: /src/api + - add: / + to: /src + includePaths: + - api + - lib/go + - images/{{ $.ImageName }}/src stageDependencies: install: - - "**/*" + - '**/*' shell: install: - apt-get update - apt-get -y install git - - git clone --depth 1 --branch v{{ $UTIL_LINUX_VERSION }} {{ env "SOURCE_REPO" }}/util-linux/util-linux.git /src/util-linux + - git clone --depth 1 --branch {{ $.Versions.UTIL_LINUX }} {{ env "SOURCE_REPO" }}/util-linux/util-linux.git /src/util-linux - rm -rf /src/util-linux/.git + - rm -rf /src/.git --- @@ -101,7 +100,7 @@ mount: shell: setup: - cd /src/images/{{ $.ImageName }}/src/cmd - - GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags="-s -w" -o /{{ $.ImageName }} + - GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags="-s -w" -tags {{ $.Root.MODULE_EDITION }} -o /{{ $.ImageName }} - chmod +x /{{ $.ImageName }} --- diff --git a/images/sds-health-watcher-controller/src/internal/const.go b/images/sds-health-watcher-controller/src/internal/const.go index 37e0fdc4..572947cb 100644 --- a/images/sds-health-watcher-controller/src/internal/const.go +++ b/images/sds-health-watcher-controller/src/internal/const.go @@ -19,11 +19,6 @@ package internal const ( SdsNodeConfiguratorNamespace = "d8-sds-node-configurator" - PhasePending = "Pending" - PhaseNotReady = "NotReady" - PhaseReady = "Ready" - PhaseTerminating = "Terminating" - ReasonPending = "Pending" ReasonUpdating = "Updating" ReasonCreating = "Creating" diff --git a/images/sds-health-watcher-controller/src/pkg/controller/lvg_conditions_watcher.go b/images/sds-health-watcher-controller/src/pkg/controller/lvg_conditions_watcher.go index f382e08e..86df4283 100644 --- a/images/sds-health-watcher-controller/src/pkg/controller/lvg_conditions_watcher.go +++ b/images/sds-health-watcher-controller/src/pkg/controller/lvg_conditions_watcher.go @@ -146,7 +146,7 @@ func reconcileLVGConditions(ctx context.Context, cl client.Client, log logger.Lo if len(lvg.Status.Conditions) < targetConCount { log.Info(fmt.Sprintf("[reconcileLVGConditions] the LVMVolumeGroup %s misses some conditions, wait for them to got configured", lvg.Name)) log.Debug(fmt.Sprintf("[reconcileLVGConditions] the LVMVolumeGroup %s conditions current count: %d, target count: %d", lvg.Name, len(lvg.Status.Conditions), targetConCount)) - err = updateLVMVolumeGroupPhaseIfNeeded(ctx, cl, lvg, internal.PhasePending) + err = updateLVMVolumeGroupPhaseIfNeeded(ctx, cl, lvg, v1alpha1.PhasePending) if err != nil { log.Error(err, fmt.Sprintf("[reconcileLVGConditions] unable to update the LVMVolumeGroup %s phase", lvg.Name)) return true, err @@ -182,7 +182,7 @@ func reconcileLVGConditions(ctx context.Context, cl client.Client, log logger.Lo ready = false falseConditions = nil log.Debug(fmt.Sprintf("[reconcileLVGConditions] the LVMVolumeGroup %s condition %s has Creating reason. Turn the LVMVolumeGroup Ready condition and phase to Pending", lvg.Name, c.Type)) - err = updateLVMVolumeGroupPhaseIfNeeded(ctx, cl, lvg, internal.PhasePending) + err = updateLVMVolumeGroupPhaseIfNeeded(ctx, cl, lvg, v1alpha1.PhasePending) if err != nil { log.Error(err, fmt.Sprintf("[reconcileLVGConditions] unable to update the LVMVolumeGroup %s phase", lvg.Name)) return true, err @@ -201,7 +201,7 @@ func reconcileLVGConditions(ctx context.Context, cl client.Client, log logger.Lo ready = false falseConditions = nil log.Debug(fmt.Sprintf("[reconcileLVGConditions] the LVMVolumeGroup %s condition %s has Terminating reason. Turn the LVMVolumeGroup Ready condition and phase to Terminating", lvg.Name, c.Type)) - err := updateLVMVolumeGroupPhaseIfNeeded(ctx, cl, lvg, internal.PhaseTerminating) + err := updateLVMVolumeGroupPhaseIfNeeded(ctx, cl, lvg, v1alpha1.PhaseTerminating) if err != nil { log.Error(err, fmt.Sprintf("[reconcileLVGConditions] unable to update the LVMVolumeGroup %s phase", lvg.Name)) return true, err @@ -224,7 +224,7 @@ func reconcileLVGConditions(ctx context.Context, cl client.Client, log logger.Lo } if len(falseConditions) > 0 { - err := updateLVMVolumeGroupPhaseIfNeeded(ctx, cl, lvg, internal.PhaseNotReady) + err := updateLVMVolumeGroupPhaseIfNeeded(ctx, cl, lvg, v1alpha1.PhaseNotReady) if err != nil { log.Error(err, fmt.Sprintf("[reconcileLVGConditions] unable to update the LVMVolumeGroup %s phase", lvg.Name)) return true, err @@ -249,7 +249,7 @@ func reconcileLVGConditions(ctx context.Context, cl client.Client, log logger.Lo return true, err } - err = updateLVMVolumeGroupPhaseIfNeeded(ctx, cl, lvg, internal.PhaseReady) + err = updateLVMVolumeGroupPhaseIfNeeded(ctx, cl, lvg, v1alpha1.PhaseReady) if err != nil { log.Error(err, fmt.Sprintf("[reconcileLVGConditions] unable to update the LVMVolumeGroup %s phase", lvg.Name)) } diff --git a/images/sds-health-watcher-controller/src/pkg/controller/lvm_volume_group_set_watcher.go b/images/sds-health-watcher-controller/src/pkg/controller/lvm_volume_group_set_watcher.go index 64bfca4a..f96c388c 100644 --- a/images/sds-health-watcher-controller/src/pkg/controller/lvm_volume_group_set_watcher.go +++ b/images/sds-health-watcher-controller/src/pkg/controller/lvm_volume_group_set_watcher.go @@ -22,7 +22,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/source" "sds-health-watcher-controller/config" - "sds-health-watcher-controller/internal" "sds-health-watcher-controller/pkg/logger" "sds-health-watcher-controller/pkg/monitoring" ) @@ -107,13 +106,13 @@ func RunLVMVolumeGroupSetWatcher( return nil } -func shouldLVGSetWatcherReconcileUpdateEvent(old, new *v1alpha1.LVMVolumeGroupSet) bool { - return !reflect.DeepEqual(old.Spec, new.Spec) +func shouldLVGSetWatcherReconcileUpdateEvent(oldLVG, newLVG *v1alpha1.LVMVolumeGroupSet) bool { + return !reflect.DeepEqual(oldLVG.Spec, newLVG.Spec) } func reconcileLVMVolumeGroupSet(ctx context.Context, cl client.Client, log logger.Logger, metrics monitoring.Metrics, lvgSet *v1alpha1.LVMVolumeGroupSet) (bool, error) { log.Debug(fmt.Sprintf("[reconcileLVMVolumeGroupSet] starts the reconciliation of the LVMVolumeGroupSet %s", lvgSet.Name)) - err := updateLVMVolumeGroupSetPhaseIfNeeded(ctx, cl, log, lvgSet, internal.PhasePending, reasonWorkInProgress) + err := updateLVMVolumeGroupSetPhaseIfNeeded(ctx, cl, log, lvgSet, v1alpha1.PhasePending, reasonWorkInProgress) if err != nil { return false, err } diff --git a/images/sds-utils-installer/werf.inc.yaml b/images/sds-utils-installer/werf.inc.yaml index caac4b12..76036d18 100644 --- a/images/sds-utils-installer/werf.inc.yaml +++ b/images/sds-utils-installer/werf.inc.yaml @@ -1,5 +1,4 @@ {{ $binaries := "/sds-utils/bin/lvm.static" }} -{{ $LVM2_VERSION := "d786a8f820d54ce87a919e6af5426c333c173b11" }} # Do not remove. It's used in external tests. --- @@ -25,7 +24,7 @@ shell: - apt-get -y install git - git clone --depth 1 {{ env "SOURCE_REPO" }}/lvmteam/lvm2.git /src/lvm2 - cd /src/lvm2 - - git fetch --depth 1 origin {{ $LVM2_VERSION }} + - git fetch --depth 1 origin {{ $.Versions.LVM2 }} - rm -rf /src/lvm2/.git --- diff --git a/images/webhooks/src/cmd/main.go b/images/webhooks/src/cmd/main.go new file mode 100644 index 00000000..5f30edda --- /dev/null +++ b/images/webhooks/src/cmd/main.go @@ -0,0 +1,83 @@ +/* +Copyright 2025 Flant JSC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "flag" + "fmt" + "net/http" + "os" + + cn "github.com/deckhouse/sds-node-configurator/api/v1alpha1" + "github.com/sirupsen/logrus" + kwhlogrus "github.com/slok/kubewebhook/v2/pkg/log/logrus" + + "webhooks/handlers" +) + +type config struct { + certFile string + keyFile string +} + +func httpHandlerHealthz(w http.ResponseWriter, _ *http.Request) { + fmt.Fprint(w, "Ok.") +} + +func initFlags() config { + cfg := config{} + + fl := flag.NewFlagSet(os.Args[0], flag.ExitOnError) + fl.StringVar(&cfg.certFile, "tls-cert-file", "", "TLS certificate file") + fl.StringVar(&cfg.keyFile, "tls-key-file", "", "TLS key file") + + if err := fl.Parse(os.Args[1:]); err != nil { + fmt.Fprintf(os.Stderr, "error parsing os.Args: %s", err) + os.Exit(1) + } + return cfg +} + +const ( + port = ":8443" + llvsValidatorID = "LLVSValidator" +) + +func main() { + logrusLogEntry := logrus.NewEntry(logrus.New()) + logrusLogEntry.Logger.SetLevel(logrus.DebugLevel) + logger := kwhlogrus.NewLogrus(logrusLogEntry) + + cfg := initFlags() + + llvsValidatingWebhookHandler, err := handlers.GetValidatingWebhookHandler(handlers.LLVSValidate, llvsValidatorID, &cn.LVMLogicalVolumeSnapshot{}, logger) + if err != nil { + fmt.Fprintf(os.Stderr, "error creating llvsValidatingWebhookHandler: %s", err) + os.Exit(1) + } + + mux := http.NewServeMux() + mux.Handle("/llvs-validate", llvsValidatingWebhookHandler) + mux.HandleFunc("/healthz", httpHandlerHealthz) + + logger.Infof("Listening on %s", port) + err = http.ListenAndServeTLS(port, cfg.certFile, cfg.keyFile, mux) + if err != nil { + fmt.Fprintf(os.Stderr, "error serving webhook: %s", err) + os.Exit(1) + } +} diff --git a/images/webhooks/src/go.mod b/images/webhooks/src/go.mod new file mode 100644 index 00000000..c79a985f --- /dev/null +++ b/images/webhooks/src/go.mod @@ -0,0 +1,40 @@ +module webhooks + +go 1.23.5 + +require ( + github.com/deckhouse/sds-node-configurator/api v0.0.0-20250206203415-a9ffd855f5a3 + github.com/deckhouse/sds-node-configurator/lib/go/common v0.0.0-00010101000000-000000000000 + github.com/sirupsen/logrus v1.9.3 + github.com/slok/kubewebhook/v2 v2.7.0 + k8s.io/apimachinery v0.32.1 +) + +replace github.com/deckhouse/sds-node-configurator/api => ../../../api + +replace github.com/deckhouse/sds-node-configurator/lib/go/common => ../../../lib/go/common + +require ( + github.com/fxamacker/cbor/v2 v2.7.0 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/spf13/pflag v1.0.6 // indirect + github.com/stretchr/testify v1.10.0 // indirect + github.com/x448/float16 v0.8.4 // indirect + golang.org/x/net v0.35.0 // indirect + golang.org/x/sys v0.30.0 // indirect + golang.org/x/text v0.22.0 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + k8s.io/api v0.32.1 // indirect + k8s.io/client-go v0.32.1 // indirect + k8s.io/klog/v2 v2.130.1 // indirect + k8s.io/utils v0.0.0-20241210054802-24370beab758 // indirect + sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.5.0 // indirect + sigs.k8s.io/yaml v1.4.0 // indirect +) diff --git a/images/webhooks/src/go.sum b/images/webhooks/src/go.sum new file mode 100644 index 00000000..d3c9d42c --- /dev/null +++ b/images/webhooks/src/go.sum @@ -0,0 +1,110 @@ +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= +github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/slok/kubewebhook/v2 v2.7.0 h1:0Wq3IVBAKDQROiB4ugxzypKUKN4FI50Wd+nyKGNiH1w= +github.com/slok/kubewebhook/v2 v2.7.0/go.mod h1:H9QZ1Z+0RpuE50y4aZZr85rr6d/4LSYX+hbvK6Oe+T4= +github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= +github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= +golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= +gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +k8s.io/api v0.32.1 h1:f562zw9cy+GvXzXf0CKlVQ7yHJVYzLfL6JAS4kOAaOc= +k8s.io/api v0.32.1/go.mod h1:/Yi/BqkuueW1BgpoePYBRdDYfjPF5sgTr5+YqDZra5k= +k8s.io/apimachinery v0.32.1 h1:683ENpaCBjma4CYqsmZyhEzrGz6cjn1MY/X2jB2hkZs= +k8s.io/apimachinery v0.32.1/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= +k8s.io/client-go v0.32.1 h1:otM0AxdhdBIaQh7l1Q0jQpmo7WOFIk5FFa4bg6YMdUU= +k8s.io/client-go v0.32.1/go.mod h1:aTTKZY7MdxUaJ/KiUs8D+GssR9zJZi77ZqtzcGXIiDg= +k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= +k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/utils v0.0.0-20241210054802-24370beab758 h1:sdbE21q2nlQtFh65saZY+rRM6x6aJJI8IUa1AmH/qa0= +k8s.io/utils v0.0.0-20241210054802-24370beab758/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= +sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +sigs.k8s.io/structured-merge-diff/v4 v4.5.0 h1:nbCitCK2hfnhyiKo6uf2HxUPTCodY6Qaf85SbDIaMBk= +sigs.k8s.io/structured-merge-diff/v4 v4.5.0/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4= +sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= +sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/images/webhooks/src/handlers/func.go b/images/webhooks/src/handlers/func.go new file mode 100644 index 00000000..cf4de9a5 --- /dev/null +++ b/images/webhooks/src/handlers/func.go @@ -0,0 +1,48 @@ +/* +Copyright 2025 Flant JSC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package handlers + +import ( + "context" + "net/http" + + kwhhttp "github.com/slok/kubewebhook/v2/pkg/http" + "github.com/slok/kubewebhook/v2/pkg/log" + "github.com/slok/kubewebhook/v2/pkg/model" + kwhvalidating "github.com/slok/kubewebhook/v2/pkg/webhook/validating" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func GetValidatingWebhookHandler(validationFunc func(ctx context.Context, _ *model.AdmissionReview, obj metav1.Object) (*kwhvalidating.ValidatorResult, error), validatorID string, obj metav1.Object, logger log.Logger) (http.Handler, error) { + validatorFunc := kwhvalidating.ValidatorFunc(validationFunc) + + validatingWebhookConfig := kwhvalidating.WebhookConfig{ + ID: validatorID, + Obj: obj, + Validator: validatorFunc, + Logger: logger, + } + + validatingWebhook, err := kwhvalidating.NewWebhook(validatingWebhookConfig) + if err != nil { + return nil, err + } + + validatingWebhookHandler, err := kwhhttp.HandlerFor(kwhhttp.HandlerConfig{Webhook: validatingWebhook, Logger: logger}) + + return validatingWebhookHandler, err +} diff --git a/images/webhooks/src/handlers/llvsValidator.go b/images/webhooks/src/handlers/llvsValidator.go new file mode 100644 index 00000000..b43e66ec --- /dev/null +++ b/images/webhooks/src/handlers/llvsValidator.go @@ -0,0 +1,38 @@ +/* +Copyright 2025 Flant JSC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package handlers + +import ( + "context" + + "github.com/deckhouse/sds-node-configurator/lib/go/common/pkg/feature" + "github.com/slok/kubewebhook/v2/pkg/model" + kwhvalidating "github.com/slok/kubewebhook/v2/pkg/webhook/validating" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func LLVSValidate(_ context.Context, _ *model.AdmissionReview, _ metav1.Object) (*kwhvalidating.ValidatorResult, error) { + if !feature.SnapshotsEnabled() { + return &kwhvalidating.ValidatorResult{ + Valid: false, + Message: "LVMLogicalVolumeSnapshot is not available in this Deckhouse edition.", + }, nil + } + return &kwhvalidating.ValidatorResult{ + Valid: true, + }, nil +} diff --git a/images/webhooks/werf.inc.yaml b/images/webhooks/werf.inc.yaml new file mode 100644 index 00000000..6edbb7a4 --- /dev/null +++ b/images/webhooks/werf.inc.yaml @@ -0,0 +1,80 @@ +--- +# do not remove this image: used in external audits (DKP CSE) +image: {{ $.ImageName }}-src-artifact +from: {{ $.Root.BASE_ALT_P11 }} +final: false +git: + - add: / + to: /src + includePaths: + - api + - lib/go + - images/{{ $.ImageName }}/src + stageDependencies: + install: + - '**/*' +shell: + install: + - rm -rf /src/.git + +--- +image: {{ $.ImageName }}-golang-artifact +from: {{ $.Root.BASE_GOLANG_1_23 }} +final: false +import: + - image: {{ $.ImageName }}-src-artifact + add: /src + to: /src + before: setup +mount: + - fromPath: ~/go-pkg-cache + to: /go/pkg +shell: + setup: + - cd /src/images/{{ $.ImageName }}/src/cmd + - export CGO_ENABLED=0 GOOS=linux GOARCH=amd64 + - go build -ldflags="-s -w" -tags {{ $.Root.MODULE_EDITION }} -o /webhooks + - chmod +x /webhooks + +--- +image: {{ $.ImageName }}-distroless-artifact +from: {{ $.Root.BASE_ALT_P11 }} +final: false +shell: + beforeInstall: + - apt-get update + - apt-get install -y openssl libtirpc + - {{ $.Root.ALT_CLEANUP_CMD }} + install: + - mkdir -p /relocate/bin /relocate/sbin /relocate/etc /relocate/var/lib/ssl /relocate/usr/bin /relocate/usr/sbin /relocate/usr/share + - cp -pr /tmp /relocate + - cp -pr /etc/passwd /etc/group /etc/hostname /etc/hosts /etc/shadow /etc/protocols /etc/services /etc/nsswitch.conf /etc/netconfig /relocate/etc + - cp -pr /usr/share/ca-certificates /relocate/usr/share + - cp -pr /usr/share/zoneinfo /relocate/usr/share + - cp -pr /var/lib/ssl/cert.pem /relocate/var/lib/ssl + - cp -pr /var/lib/ssl/certs /relocate/var/lib/ssl + - echo "deckhouse:x:{{ $.Root.DECKHOUSE_UID_GID }}:{{ $.Root.DECKHOUSE_UID_GID }}:deckhouse:/:/sbin/nologin" >> /relocate/etc/passwd + - echo "deckhouse:x:{{ $.Root.DECKHOUSE_UID_GID }}:" >> /relocate/etc/group + - echo "deckhouse:!::0:::::" >> /relocate/etc/shadow + +--- +image: {{ $.ImageName }}-distroless +from: {{ $.Root.BASE_SCRATCH }} +final: false +import: + - image: {{ $.ImageName }}-distroless-artifact + add: /relocate + to: / + before: setup + +--- +image: {{ $.ImageName }} +fromImage: {{ $.ImageName }}-distroless +import: + - image: {{ $.ImageName }}-golang-artifact + add: /webhooks + to: /webhooks + before: setup +docker: + ENTRYPOINT: ["/webhooks"] + USER: deckhouse:deckhouse diff --git a/lib/go/common/go.mod b/lib/go/common/go.mod new file mode 100644 index 00000000..48a4e80e --- /dev/null +++ b/lib/go/common/go.mod @@ -0,0 +1,3 @@ +module github.com/deckhouse/sds-node-configurator/lib/go/common + +go 1.23.4 diff --git a/lib/go/common/go.sum b/lib/go/common/go.sum new file mode 100644 index 00000000..e69de29b diff --git a/lib/go/common/pkg/feature/const_ce.go b/lib/go/common/pkg/feature/const_ce.go new file mode 100644 index 00000000..f1240f87 --- /dev/null +++ b/lib/go/common/pkg/feature/const_ce.go @@ -0,0 +1,18 @@ +//go:build ce + +/* +Copyright 2025 Flant JSC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package feature + +const snapshotsEnabled = false diff --git a/lib/go/common/pkg/feature/const_csepro.go b/lib/go/common/pkg/feature/const_csepro.go new file mode 100644 index 00000000..3a0b2587 --- /dev/null +++ b/lib/go/common/pkg/feature/const_csepro.go @@ -0,0 +1,11 @@ +//go:build csepro + +/* +Copyright 2025 Flant JSC +Licensed under the Deckhouse Platform Enterprise Edition (EE) license. +See https://github.com/deckhouse/deckhouse/blob/main/ee/LICENSE +*/ + +package feature + +const snapshotsEnabled = true diff --git a/lib/go/common/pkg/feature/const_ee.go b/lib/go/common/pkg/feature/const_ee.go new file mode 100644 index 00000000..cf1d2165 --- /dev/null +++ b/lib/go/common/pkg/feature/const_ee.go @@ -0,0 +1,11 @@ +//go:build ee + +/* +Copyright 2025 Flant JSC +Licensed under the Deckhouse Platform Enterprise Edition (EE) license. +See https://github.com/deckhouse/deckhouse/blob/main/ee/LICENSE +*/ + +package feature + +const snapshotsEnabled = true diff --git a/lib/go/common/pkg/feature/const_se.go b/lib/go/common/pkg/feature/const_se.go new file mode 100644 index 00000000..8a5bbca0 --- /dev/null +++ b/lib/go/common/pkg/feature/const_se.go @@ -0,0 +1,11 @@ +//go:build se + +/* +Copyright 2025 Flant JSC +Licensed under the Deckhouse Platform Enterprise Edition (EE) license. +See https://github.com/deckhouse/deckhouse/blob/main/ee/LICENSE +*/ + +package feature + +const snapshotsEnabled = true diff --git a/lib/go/common/pkg/feature/const_seplus.go b/lib/go/common/pkg/feature/const_seplus.go new file mode 100644 index 00000000..d2445b57 --- /dev/null +++ b/lib/go/common/pkg/feature/const_seplus.go @@ -0,0 +1,11 @@ +//go:build seplus + +/* +Copyright 2025 Flant JSC +Licensed under the Deckhouse Platform Enterprise Edition (EE) license. +See https://github.com/deckhouse/deckhouse/blob/main/ee/LICENSE +*/ + +package feature + +const snapshotsEnabled = true diff --git a/lib/go/common/pkg/feature/feature.go b/lib/go/common/pkg/feature/feature.go new file mode 100644 index 00000000..18ed9940 --- /dev/null +++ b/lib/go/common/pkg/feature/feature.go @@ -0,0 +1,5 @@ +package feature + +func SnapshotsEnabled() bool { + return snapshotsEnabled +} diff --git a/templates/webhooks/deployment.yaml b/templates/webhooks/deployment.yaml new file mode 100644 index 00000000..3c1c044a --- /dev/null +++ b/templates/webhooks/deployment.yaml @@ -0,0 +1,96 @@ +{{- define "webhooks_resources" }} +cpu: 10m +memory: 50Mi +{{- end }} + +{{- if (.Values.global.enabledModules | has "vertical-pod-autoscaler-crd") }} +--- +apiVersion: autoscaling.k8s.io/v1 +kind: VerticalPodAutoscaler +metadata: + name: webhooks + namespace: d8-{{ .Chart.Name }} + {{- include "helm_lib_module_labels" (list . (dict "app" "webhooks" "workload-resource-policy.deckhouse.io" "master")) | nindent 2 }} +spec: + targetRef: + apiVersion: "apps/v1" + kind: Deployment + name: webhooks + updatePolicy: + updateMode: "Auto" + resourcePolicy: + containerPolicies: + - containerName: webhooks + minAllowed: + {{- include "webhooks_resources" . | nindent 8 }} + maxAllowed: + cpu: 20m + memory: 100Mi +{{- end }} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: webhooks + namespace: d8-{{ .Chart.Name }} + {{- include "helm_lib_module_labels" (list . (dict "app" "webhooks" )) | nindent 2 }} +spec: + {{- include "helm_lib_deployment_on_master_strategy_and_replicas_for_ha" . | nindent 2 }} + selector: + matchLabels: + app: webhooks + template: + metadata: + labels: + app: webhooks + spec: + {{- include "helm_lib_priority_class" (tuple . "system-cluster-critical") | nindent 6 }} + {{- include "helm_lib_tolerations" (tuple . "any-node" "with-uninitialized" "with-cloud-provider-uninitialized") | nindent 6 }} + {{- include "helm_lib_node_selector" (tuple . "master") | nindent 6 }} + {{- include "helm_lib_pod_anti_affinity_for_ha" (list . (dict "app" "webhooks")) | nindent 6 }} + containers: + - name: webhooks + command: + - /webhooks + - -tls-cert-file=/etc/webhook/certs/tls.crt + - -tls-key-file=/etc/webhook/certs/tls.key + image: {{ include "helm_lib_module_image" (list . "webhooks") }} + imagePullPolicy: IfNotPresent + volumeMounts: + - name: webhook-certs + mountPath: /etc/webhook/certs + readOnly: true + readinessProbe: + httpGet: + path: /healthz + port: 8443 + scheme: HTTPS + initialDelaySeconds: 5 + failureThreshold: 2 + periodSeconds: 1 + livenessProbe: + httpGet: + path: /healthz + port: 8443 + scheme: HTTPS + periodSeconds: 1 + failureThreshold: 3 + ports: + - name: http + containerPort: 8443 + protocol: TCP + resources: + requests: + {{- include "helm_lib_module_ephemeral_storage_only_logs" . | nindent 12 }} +{{- if not ( .Values.global.enabledModules | has "vertical-pod-autoscaler-crd") }} + {{- include "webhooks_resources" . | nindent 12 }} +{{- end }} + + imagePullSecrets: + - name: {{ .Chart.Name }}-module-registry + serviceAccount: webhooks + serviceAccountName: webhooks + volumes: + - name: webhook-certs + secret: + secretName: webhooks-https-certs diff --git a/templates/webhooks/rbac-for-us.yaml b/templates/webhooks/rbac-for-us.yaml new file mode 100644 index 00000000..6e37a4d8 --- /dev/null +++ b/templates/webhooks/rbac-for-us.yaml @@ -0,0 +1,36 @@ +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: webhooks + namespace: d8-{{ .Chart.Name }} + {{- include "helm_lib_module_labels" (list . (dict "app" "webhooks")) | nindent 2 }} +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: d8:{{ .Chart.Name }}:webhooks + {{- include "helm_lib_module_labels" (list . (dict "app" "webhooks")) | nindent 2 }} +rules: + - verbs: + - get + - list + - watch + apiGroups: + - storage.deckhouse.io + resources: + - lvmlogicalvolumesnapshots +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: d8:{{ .Chart.Name }}:webhooks + {{- include "helm_lib_module_labels" (list . (dict "app" "webhooks")) | nindent 2 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: d8:{{ .Chart.Name }}:webhooks +subjects: + - kind: ServiceAccount + name: webhooks + namespace: d8-{{ .Chart.Name }} diff --git a/templates/webhooks/secret.yaml b/templates/webhooks/secret.yaml new file mode 100644 index 00000000..55d975ea --- /dev/null +++ b/templates/webhooks/secret.yaml @@ -0,0 +1,12 @@ +--- +apiVersion: v1 +kind: Secret +metadata: + name: webhooks-https-certs + namespace: d8-{{ .Chart.Name }} + {{- include "helm_lib_module_labels" (list . (dict "app" "webhooks")) | nindent 2 }} +type: kubernetes.io/tls +data: + ca.crt: {{ .Values.sdsNodeConfigurator.internal.customWebhookCert.ca }} + tls.crt: {{ .Values.sdsNodeConfigurator.internal.customWebhookCert.crt }} + tls.key: {{ .Values.sdsNodeConfigurator.internal.customWebhookCert.key }} diff --git a/templates/webhooks/service.yaml b/templates/webhooks/service.yaml new file mode 100644 index 00000000..894fd457 --- /dev/null +++ b/templates/webhooks/service.yaml @@ -0,0 +1,16 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: webhooks + namespace: d8-{{ .Chart.Name }} + {{- include "helm_lib_module_labels" (list . (dict "app" "webhooks" )) | nindent 2 }} +spec: + type: ClusterIP + ports: + - port: 443 + targetPort: 8443 + protocol: TCP + name: http + selector: + app: webhooks diff --git a/templates/webhooks/webhook.yaml b/templates/webhooks/webhook.yaml new file mode 100644 index 00000000..e375e50c --- /dev/null +++ b/templates/webhooks/webhook.yaml @@ -0,0 +1,23 @@ +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: "d8-{{ .Chart.Name }}-llvs-validation" +webhooks: + - name: "d8-{{ .Chart.Name }}-llvs-validation.deckhouse.io" + rules: + - apiGroups: ["storage.deckhouse.io"] + apiVersions: ["v1alpha1"] + operations: ["*"] + resources: ["lvmlogicalvolumesnapshots"] + scope: "Cluster" + clientConfig: + service: + namespace: "d8-{{ .Chart.Name }}" + name: "webhooks" + path: "/llvs-validate" + caBundle: | + {{ .Values.sdsNodeConfigurator.internal.customWebhookCert.ca }} + admissionReviewVersions: ["v1", "v1beta1"] + sideEffects: None + timeoutSeconds: 5 diff --git a/werf-giterminism.yaml b/werf-giterminism.yaml index 1fc78d98..fb48bee8 100644 --- a/werf-giterminism.yaml +++ b/werf-giterminism.yaml @@ -1,7 +1,7 @@ giterminismConfigVersion: 1 config: goTemplateRendering: # The rules for the Go-template functions - allowEnvVariables: [ /CI_.+/, SOURCE_REPO ] + allowEnvVariables: [ /CI_.+/, SOURCE_REPO, MODULE_EDITION ] stapel: mount: allowFromPaths: