From 2c3970a711ba8bb603dd6ffcf79508255abd02cb Mon Sep 17 00:00:00 2001 From: Denis Shipkov Date: Tue, 19 Nov 2024 19:58:11 +0300 Subject: [PATCH] pv minimum check logic, lable, alert added Signed-off-by: Denis Shipkov --- .../controller/linstor_resources_watcher.go | 113 +++++++-- ...replicated-pv-with-incorrect-settings.yaml | 24 +- test/config/config.go | 98 -------- test/go.mod | 78 ------ test/go.sum | 218 ----------------- test/main.go | 227 ------------------ test/pkg/kubeutils/kubernetes.go | 37 --- test/pkg/logger/logger.go | 87 ------- 8 files changed, 116 insertions(+), 766 deletions(-) delete mode 100644 test/config/config.go delete mode 100644 test/go.mod delete mode 100644 test/go.sum delete mode 100644 test/main.go delete mode 100644 test/pkg/kubeutils/kubernetes.go delete mode 100644 test/pkg/logger/logger.go diff --git a/images/sds-replicated-volume-controller/src/pkg/controller/linstor_resources_watcher.go b/images/sds-replicated-volume-controller/src/pkg/controller/linstor_resources_watcher.go index f9273d8d..122b6252 100644 --- a/images/sds-replicated-volume-controller/src/pkg/controller/linstor_resources_watcher.go +++ b/images/sds-replicated-volume-controller/src/pkg/controller/linstor_resources_watcher.go @@ -39,6 +39,7 @@ const ( linstorResourcesWatcherCtrlName = "linstor-resources-watcher-controller" missMatchedLabel = "storage.deckhouse.io/linstor-settings-mismatch" unableToSetQuorumMinimumRedundancyLabel = "storage.deckhouse.io/unable-to-set-quorum-minimum-redundancy" + pvNotEnoughReplicasLabel = "storage.deckhouse.io/pv-not-enough-replicas" PVCSIDriver = "replicated.csi.storage.deckhouse.io" replicasOnSameRGKey = "replicas_on_same" replicasOnDifferentRGKey = "replicas_on_different" @@ -112,8 +113,23 @@ func NewLinstorResourcesWatcher( rgMap[rg.Name] = rg } - ReconcileParams(ctx, log, cl, lc, scMap, rdMap, rgMap) - ReconcileTieBreaker(ctx, log, lc, rdMap, rgMap) + pvsList, err := GetListPV(ctx, cl) + if err != nil { + log.Error(err, "[NewLinstorResourcesWatcher] unable to get Persistent Volumes") + } + + resMap := make(map[string][]lapi.Resource, len(rdMap)) + for name := range rdMap { + res, err := lc.Resources.GetAll(ctx, name) + if err != nil { + log.Error(err, fmt.Sprintf("[NewLinstorResourcesWatcher] unable to get Linstor Resources, name: %s", name)) + } + resMap[name] = res + } + + ReconcileParams(ctx, log, cl, lc, scMap, rdMap, rgMap, pvsList) + ReconcileTieBreaker(ctx, log, lc, rdMap, rgMap, resMap) + ReconcilePVReplicas(ctx, log, cl, lc, rdMap, rgMap, resMap, pvsList) log.Info("[NewLinstorResourcesWatcher] ends reconcile") } @@ -128,12 +144,9 @@ func ReconcileParams( scs map[string]v1.StorageClass, rds map[string]lapi.ResourceDefinitionWithVolumeDefinition, rgs map[string]lapi.ResourceGroup, + pvs []core.PersistentVolume, ) { log.Info("[ReconcileParams] starts work") - pvs, err := GetListPV(ctx, cl) - if err != nil { - log.Error(err, "[ReconcileParams] unable to get Persistent Volumes") - } for _, pv := range pvs { if pv.Spec.CSI != nil && pv.Spec.CSI.Driver == PVCSIDriver { @@ -206,30 +219,94 @@ func ReconcileParams( log.Info("[ReconcileParams] ends work") } -func ReconcileTieBreaker( +func ReconcilePVReplicas( ctx context.Context, log logger.Logger, + cl client.Client, lc *lapi.Client, rds map[string]lapi.ResourceDefinitionWithVolumeDefinition, rgs map[string]lapi.ResourceGroup, + res map[string][]lapi.Resource, + pvs []core.PersistentVolume, ) { - log.Info("[ReconcileTieBreaker] starts work") + log.Info("[ReconcilePVReplicas] starts work") - allResources := make(map[string][]lapi.Resource, len(rds)*3) - for name := range rds { - res, err := lc.Resources.GetAll(ctx, name) + for _, pv := range pvs { + if pv.Spec.CSI != nil && pv.Spec.CSI.Driver == PVCSIDriver { + RGName := rds[pv.Name].ResourceGroupName + rg := rgs[RGName] + log.Debug(fmt.Sprintf("[ReconcilePVReplicas] PV: %s, RG: %s", pv.Name, rg.Name)) + + enoughReplicas := checkPVMinReplicasCount(ctx, log, lc, rg, res[pv.Name]) + + if pv.Labels == nil { + pv.Labels = make(map[string]string) + } + + origLabelVal, exists := pv.Labels[pvNotEnoughReplicasLabel] + log.Debug(fmt.Sprintf("[ReconcilePVReplicas] Update label \"%s\", old: \"%s\", new: \"%t\"", pvNotEnoughReplicasLabel, origLabelVal, !enoughReplicas)) + + upd := false + if !enoughReplicas && (!exists || origLabelVal != "true") { + pv.Labels[pvNotEnoughReplicasLabel] = "true" + upd = true + } + if enoughReplicas && exists { + delete(pv.Labels, pvNotEnoughReplicasLabel) + upd = true + } + + if upd { + err := UpdatePV(ctx, cl, &pv) + if err != nil { + log.Error(err, fmt.Sprintf("[ReconcilePVReplicas] unable to update the PV, name: %s", pv.Name)) + } + } + } + } + + log.Info("[ReconcilePVReplicas] ends work") +} + +func checkPVMinReplicasCount(ctx context.Context, log logger.Logger, lc *lapi.Client, rg lapi.ResourceGroup, resList []lapi.Resource) bool { + placeCount := int(rg.SelectFilter.PlaceCount) + upVols := 0 + + if placeCount <= 0 { + return true + } + + for _, r := range resList { + volList, err := lc.Resources.GetVolumes(ctx, r.Name, r.NodeName) if err != nil { - log.Error(err, fmt.Sprintf("[ReconcileTieBreaker] unable to get Linstor Resources by the Resource Definition, name: %s", name)) + log.Error(err, fmt.Sprintf("[checkPVMinReplicasCount] unable to get Linstor Resources Volumes, name: %s, node: %s", r.Name, r.NodeName)) } - allResources[name] = res + for _, v := range volList { + if v.State.DiskState == "UpToDate" { + upVols += 1 + } + } } + return upVols >= placeCount +} + +func ReconcileTieBreaker( + ctx context.Context, + log logger.Logger, + lc *lapi.Client, + rds map[string]lapi.ResourceDefinitionWithVolumeDefinition, + rgs map[string]lapi.ResourceGroup, + res map[string][]lapi.Resource, +) { + log.Info("[ReconcileTieBreaker] starts work") + var ( nodes []lapi.Node err error ) - for name, resources := range allResources { + for name, resources := range res { if len(resources) == 0 { log.Warning(fmt.Sprintf("[ReconcileTieBreaker] no actual Linstor Resources for the Resource Definition, name: %s", name)) continue @@ -300,7 +377,9 @@ func getNodeForTieBreaker( for _, node := range unusedNodes { log.Trace(fmt.Sprintf("[getNodeForTieBreaker] resource %s does not use a node %s", resources[0].Name, node.Name)) } - rg := getResourceGroupByResource(resources[0].Name, rds, rgs) + + RGName := rds[resources[0].Name].ResourceGroupName + rg := rgs[RGName] if key, exist := rg.Props[replicasOnSameRGKey]; exist { unusedNodes = filterNodesByReplicasOnSame(unusedNodes, key) @@ -389,10 +468,6 @@ func filterNodesByReplicasOnSame(nodes []lapi.Node, key string) []lapi.Node { return filtered } -func getResourceGroupByResource(resourceName string, rds map[string]lapi.ResourceDefinitionWithVolumeDefinition, rgs map[string]lapi.ResourceGroup) lapi.ResourceGroup { - return rgs[rds[resourceName].ResourceGroupName] -} - func filterOutUsedNodes(nodes []lapi.Node, resources []lapi.Resource) []lapi.Node { unusedNodes := make([]lapi.Node, 0, len(nodes)) resNodes := make(map[string]struct{}, len(resources)) diff --git a/monitoring/prometheus-rules/replicated-pv-with-incorrect-settings.yaml b/monitoring/prometheus-rules/replicated-pv-with-incorrect-settings.yaml index 72fafa4a..a775d20a 100644 --- a/monitoring/prometheus-rules/replicated-pv-with-incorrect-settings.yaml +++ b/monitoring/prometheus-rules/replicated-pv-with-incorrect-settings.yaml @@ -13,11 +13,11 @@ plk_grouped_by__d8_drbd_device_health: "ReplicatedPVSettingsCheck,tier=~tier,prometheus=deckhouse,kubernetes=~kubernetes" summary: Replicated PVs has incorrect settings description: | - There are persistent volumes in the cluster that were created before migration to ReplicatedStorageClass. + There are persistent volumes in the cluster that were created before migration to ReplicatedStorageClass. You can recreate it, or add the label storage.deckhouse.io/linstor-settings-mismatch-ignore!=true to ignore it for the PV. Please note that in the future, when transitioning from LINSTOR to a new controller, the settings for all such PVs will be automatically modified to match the current StorageClass settings. - You can view all of such PV with command + You can view all of such PV with command `kubectl get pv -l storage.deckhouse.io/linstor-settings-mismatch=true,storage.deckhouse.io/linstor-settings-mismatch-ignore!=true` Also, you can add label for all incorrect PVs @@ -38,3 +38,23 @@ There are persistent volumes in the cluster that has incorrect quorum-minimum-redundancy setting. Please, contact tech support for assistance. + - alert: ReplicatedPVWithIncorrectReplicasCount + expr: count(kube_persistentvolume_labels{label_storage_deckhouse_io_pv_not_enough_replicas="true"}) > 0 + for: 5m + labels: + severity_level: "3" + tier: cluster + annotations: + plk_markup_format: "markdown" + plk_protocol_version: "1" + plk_create_group_if_not_exists__d8_drbd_device_health: "ReplicatedPVSettingsCheck,tier=~tier,prometheus=deckhouse,kubernetes=~kubernetes" + plk_grouped_by__d8_drbd_device_health: "ReplicatedPVSettingsCheck,tier=~tier,prometheus=deckhouse,kubernetes=~kubernetes" + summary: Replicated PVs has not enough replicas + description: | + There are persistent volumes in the cluster that has not enough replicas (set of UpToDate resources less than minimal count) + + You can get minimal limit for StorageClass with command + `kubectl get sc -o yaml | grep -E "(\sname|/placementCount)"` + + And view all Resource States with + `linstor r l` diff --git a/test/config/config.go b/test/config/config.go deleted file mode 100644 index 480c3c38..00000000 --- a/test/config/config.go +++ /dev/null @@ -1,98 +0,0 @@ -/* -Copyright 2023 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 config - -import ( - "log" - "os" - - "sds-replicated-volume-controller/pkg/logger" -) - -// ScanInterval Scan block device interval seconds -const ( - ScanInterval = 10 - LinstorResourcesReconcileInterval = 120 - ReplicatedStorageClassWatchInterval = 120 - ConfigSecretName = "d8-sds-replicated-volume-controller-config" - LinstorLeaseName = "linstor" - NodeName = "NODE_NAME" - DefaultHealthProbeBindAddressEnvName = "HEALTH_PROBE_BIND_ADDRESS" - DefaultHealthProbeBindAddress = ":8081" - MetricsPortEnv = "METRICS_PORT" - ControllerNamespaceEnv = "CONTROLLER_NAMESPACE" - HardcodedControllerNS = "d8-sds-replicated-volume" - ControllerName = "sds-replicated-volume-controller" - LogLevel = "LOG_LEVEL" -) - -type Options struct { - ScanInterval int - LinstorResourcesReconcileInterval int - ReplicatedStorageClassWatchInterval int - ConfigSecretName string - LinstorLeaseName string - MetricsPort string - HealthProbeBindAddress string - ControllerNamespace string - Loglevel logger.Verbosity -} - -func NewConfig() (*Options, error) { - var opts Options - opts.ScanInterval = ScanInterval - opts.LinstorResourcesReconcileInterval = LinstorResourcesReconcileInterval - opts.ReplicatedStorageClassWatchInterval = ReplicatedStorageClassWatchInterval - opts.LinstorLeaseName = LinstorLeaseName - opts.ConfigSecretName = ConfigSecretName - - loglevel := os.Getenv(LogLevel) - if loglevel == "" { - opts.Loglevel = logger.DebugLevel - } else { - opts.Loglevel = logger.Verbosity(loglevel) - } - - opts.MetricsPort = os.Getenv(MetricsPortEnv) - if opts.MetricsPort == "" { - opts.MetricsPort = ":8080" - } - - opts.HealthProbeBindAddress = os.Getenv(DefaultHealthProbeBindAddressEnvName) - if opts.HealthProbeBindAddress == "" { - opts.HealthProbeBindAddress = DefaultHealthProbeBindAddress - } - - opts.ControllerNamespace = os.Getenv(ControllerNamespaceEnv) - if opts.ControllerNamespace == "" { - namespace, err := os.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace") - if err != nil { - log.Printf("Failed to get namespace from filesystem: %v", err) - log.Printf("Using hardcoded namespace: %s", HardcodedControllerNS) - opts.ControllerNamespace = HardcodedControllerNS - } else { - log.Printf("Got namespace from filesystem: %s", string(namespace)) - opts.ControllerNamespace = string(namespace) - } - } - - return &opts, nil -} - -type SdsReplicatedVolumeOperatorConfig struct { - NodeSelector map[string]string `yaml:"nodeSelector"` -} diff --git a/test/go.mod b/test/go.mod deleted file mode 100644 index 44f33818..00000000 --- a/test/go.mod +++ /dev/null @@ -1,78 +0,0 @@ -module sds-replicated-volume-controller - -go 1.23.2 - -require ( - github.com/LINBIT/golinstor v0.49.0 - github.com/deckhouse/sds-node-configurator/api v0.0.0-20240925090458-249de2896583 - github.com/deckhouse/sds-replicated-volume/api v0.0.0-20241103101138-0ca6a8ff05ba // v0.0.0-20240812165341-a73e664454b9 - github.com/go-logr/logr v1.4.2 - github.com/google/uuid v1.6.0 - github.com/onsi/ginkgo/v2 v2.19.0 - github.com/onsi/gomega v1.33.1 - github.com/stretchr/testify v1.9.0 - gopkg.in/yaml.v3 v3.0.1 - k8s.io/api v0.31.0 - k8s.io/apiextensions-apiserver v0.31.0 - k8s.io/apimachinery v0.31.0 - k8s.io/client-go v0.31.0 - k8s.io/klog/v2 v2.130.1 - k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 - sigs.k8s.io/controller-runtime v0.19.0 -) - -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/donovanhide/eventsource v0.0.0-20210830082556-c59027999da0 // indirect - github.com/emicklei/go-restful/v3 v3.11.0 // indirect - github.com/evanphx/json-patch/v5 v5.9.0 // indirect - github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/fxamacker/cbor/v2 v2.7.0 // indirect - github.com/go-openapi/jsonpointer v0.19.6 // indirect - github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/swag v0.22.4 // 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/go-cmp v0.6.0 // indirect - github.com/google/go-querystring v1.1.0 // indirect - github.com/google/gofuzz v1.2.0 // indirect - github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af // indirect - github.com/imdario/mergo v0.3.6 // 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/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 - github.com/pkg/errors v0.9.1 // indirect - github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/client_golang v1.19.1 // indirect - github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.55.0 // indirect - 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-20230515195305-f3d0a9c9a5cc // indirect - golang.org/x/net v0.26.0 // indirect - golang.org/x/oauth2 v0.21.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/term v0.21.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect - gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/protobuf v1.34.2 // 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 - k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect - moul.io/http2curl/v2 v2.3.0 // indirect - sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect - sigs.k8s.io/yaml v1.4.0 // indirect -) diff --git a/test/go.sum b/test/go.sum deleted file mode 100644 index c0723b84..00000000 --- a/test/go.sum +++ /dev/null @@ -1,218 +0,0 @@ -github.com/LINBIT/golinstor v0.49.0 h1:2Q5u0mjB+vMA8xkFfB04eT09qg1wFRxnmS1SkfK4Jr0= -github.com/LINBIT/golinstor v0.49.0/go.mod h1:wwtsHgmgK/+Kz0g3uJoEljqBEsEfmnCXvM64JcyuiwU= -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/deckhouse/sds-node-configurator/api v0.0.0-20240925090458-249de2896583 h1:HQd5YFQqoHj/CQwBKFCyuVCQmNV0PdML8QJiyDka4fQ= -github.com/deckhouse/sds-node-configurator/api v0.0.0-20240925090458-249de2896583/go.mod h1:H71+9G0Jr46Qs0BA3z3/xt0h9lbnJnCEYcaCJCWFBf0= -github.com/deckhouse/sds-replicated-volume/api v0.0.0-20240812165341-a73e664454b9 h1:keKcnq6do7yxGZHeNERhhx3dH1/wQmj+x5vxcWH3CcI= -github.com/deckhouse/sds-replicated-volume/api v0.0.0-20240812165341-a73e664454b9/go.mod h1:6yz0RtbkLVJtK2DeuvgfaqBZRl5V5ax1WsfPF5pbnvo= -github.com/deckhouse/sds-replicated-volume/api v0.0.0-20241103101138-0ca6a8ff05ba h1:NtT0vii1BTFV4aaJgJD0+DP4ru86DLnl3x9imzUKNfg= -github.com/deckhouse/sds-replicated-volume/api v0.0.0-20241103101138-0ca6a8ff05ba/go.mod h1:6yz0RtbkLVJtK2DeuvgfaqBZRl5V5ax1WsfPF5pbnvo= -github.com/donovanhide/eventsource v0.0.0-20210830082556-c59027999da0 h1:C7t6eeMaEQVy6e8CarIhscYQlNmw5e3G36y7l7Y21Ao= -github.com/donovanhide/eventsource v0.0.0-20210830082556-c59027999da0/go.mod h1:56wL82FO0bfMU5RvfXoIwSOP2ggqqxT+tAfNEIyxuHw= -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/evanphx/json-patch v0.5.2 h1:xVCHIVMUu1wtM/VkR9jVZ45N3FhZfYMMYGorLCR8P3k= -github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= -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/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= -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/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 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -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-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/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -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/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= -github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= -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/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= -github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -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= -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.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -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/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/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/pkg/diff v0.0.0-20200914180035-5b29258ca4f7/go.mod h1:zO8QMzTeZd5cpnIkz/Gn6iK0jDfGicM1nynOkkPIl28= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -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/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= -github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= -github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= -github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= -github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= -github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= -github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= -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/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -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.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -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/tailscale/depaware v0.0.0-20210622194025-720c4b409502/go.mod h1:p9lPsd+cx33L3H9nNoecRRxPssFKUwwI50I3pZ0yT+8= -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= -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= -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-20230515195305-f3d0a9c9a5cc h1:mCRnTeVUjcrhlRmO0VK8a6k6Rrf6TF9htwo2pJVSjIU= -golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/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.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= -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/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.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= -golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= -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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -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-20201211185031-d93e913c1a58/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -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/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= -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/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= -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.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -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.0 h1:m9jOiSr3FoSSL5WO9bjm1n6B9KROYYgNZOb4tyZ1lBc= -k8s.io/apimachinery v0.31.0/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/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= -moul.io/http2curl/v2 v2.3.0 h1:9r3JfDzWPcbIklMOs2TnIFzDYvfAZvjeavG6EzP7jYs= -moul.io/http2curl/v2 v2.3.0/go.mod h1:RW4hyBjTWSYDOxapodpNEtX0g5Eb16sxklBqmd2RHcE= -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= -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/test/main.go b/test/main.go deleted file mode 100644 index af57acaf..00000000 --- a/test/main.go +++ /dev/null @@ -1,227 +0,0 @@ -package main - -import ( - "context" - "fmt" - "strconv" - "strings" - - lapi "github.com/LINBIT/golinstor/client" - snc "github.com/deckhouse/sds-node-configurator/api/v1alpha1" - "github.com/deckhouse/sds-replicated-volume/api/linstor" - srv "github.com/deckhouse/sds-replicated-volume/api/v1alpha1" - v1 "k8s.io/api/core/v1" - sv1 "k8s.io/api/storage/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - extv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - apiruntime "k8s.io/apimachinery/pkg/runtime" - clientgoscheme "k8s.io/client-go/kubernetes/scheme" -// "sigs.k8s.io/controller-runtime/pkg/cache" - "sigs.k8s.io/controller-runtime/pkg/client" -// "sigs.k8s.io/controller-runtime/pkg/manager" - - "sds-replicated-volume-controller/config" - kubutils "sds-replicated-volume-controller/pkg/kubeutils" - - _ "k8s.io/client-go/plugin/pkg/client/auth/oidc" -) - -const ( - PVCSIDriver = "replicated.csi.storage.deckhouse.io" - placementCountSCKey = "placementCount" -) - -var ( - resourcesSchemeFuncs = []func(*apiruntime.Scheme) error{ - srv.AddToScheme, - snc.AddToScheme, - linstor.AddToScheme, - clientgoscheme.AddToScheme, - extv1.AddToScheme, - v1.AddToScheme, - sv1.AddToScheme, - } -) - - -func main() { - // Create default config Kubernetes client - kConfig, err := kubutils.KubernetesDefaultConfigCreate() - if err != nil { - fmt.Println(err) - panic("error by reading a kubernetes configuration") - } - - fmt.Println(" step 1.1") - -// // Setup scheme for all resources -// scheme := apiruntime.NewScheme() -// for _, f := range resourcesSchemeFuncs { -// err := f(scheme) -// if err != nil { -// panic("failed to add to scheme") -// } -// } -// -// fmt.Println(" step 1.2") - - cfgParams, err := config.NewConfig() - if err != nil { - fmt.Println("unable to create NewConfig " + err.Error()) - } - -// fmt.Println("ControllerNamespace: " + cfgParams.ControllerNamespace) -// -// fmt.Println(" step 1.2.1") -// -// cacheOpt := cache.Options{ -// DefaultNamespaces: map[string]cache.Config{ -// cfgParams.ControllerNamespace: {}, -// }, -// } -// -// fmt.Println(" step 1.3") -// -// managerOpts := manager.Options{ -// Scheme: scheme, -// // MetricsBindAddress: cfgParams.MetricsPort, -// HealthProbeBindAddress: cfgParams.HealthProbeBindAddress, -// Cache: cacheOpt, -// LeaderElection: true, -// LeaderElectionNamespace: cfgParams.ControllerNamespace, -// LeaderElectionID: config.ControllerName, -// } -// -// fmt.Println(" step 1.4") -// -// mgr, err := manager.New(kConfig, managerOpts) -// if err != nil { -// fmt.Println(err) -// panic("failed to create a manager") -// } - - cl, err := client.New(kConfig, client.Options{}) - if err != nil { - fmt.Println(err) - panic("error by creating a client") - } - - lc, err := lapi.NewClient() - if err != nil { - fmt.Println(err) - panic("failed to create a linstor client") - } - - fmt.Println(" step 1.5") - - NewLinstorResourcesWatcher(cl, lc, cfgParams.LinstorResourcesReconcileInterval) -// NewLinstorResourcesWatcher(mgr, lc, cfgParams.LinstorResourcesReconcileInterval) -} - -func GetStorageClasses(ctx context.Context, cl client.Client) ([]sv1.StorageClass, error) { - listStorageClasses := &sv1.StorageClassList{ - TypeMeta: metav1.TypeMeta{ - Kind: "StorageClass", - APIVersion: "storage.k8s.io/v1", - }, - } - err := cl.List(ctx, listStorageClasses) - if err != nil { - return nil, err - } - return listStorageClasses.Items, nil -} - -func NewLinstorResourcesWatcher(cl client.Client, lc *lapi.Client, interval int) { - ctx := context.Background() - - scs, err := GetStorageClasses(ctx, cl) - if err != nil { - fmt.Println(err) - panic("[NewLinstorResourcesWatcher] unable to get Kubernetes Storage Classes") - } - - scMap := make(map[string]sv1.StorageClass, len(scs)) - for _, sc := range scs { - scMap[sc.Name] = sc - } - - rgs, err := lc.ResourceGroups.GetAll(ctx) - if err != nil { - fmt.Println(err) - panic("[NewLinstorResourcesWatcher] unable to get Linstor Resource Groups") - } - - rds, err := lc.ResourceDefinitions.GetAll(ctx, lapi.RDGetAllRequest{}) - if err != nil { - fmt.Println(err) - panic("[NewLinstorResourcesWatcher] unable to get Linstor Resource Definitions") - } - - rdMap := make(map[string]lapi.ResourceDefinitionWithVolumeDefinition, len(rds)) - for _, rd := range rds { - rdMap[rd.Name] = rd - } - - rgMap := make(map[string]lapi.ResourceGroup, len(rgs)) - for _, rg := range rgs { - rgMap[rg.Name] = rg - } - - ReconcileParams(ctx, cl, lc, scMap, rdMap, rgMap) -} - - -func GetListPV(ctx context.Context, cl client.Client) ([]v1.PersistentVolume, error) { - PersistentVolumeList := &v1.PersistentVolumeList{} - err := cl.List(ctx, PersistentVolumeList) - if err != nil { - return nil, err - } - return PersistentVolumeList.Items, nil -} - -func ReconcileParams( - ctx context.Context, - cl client.Client, - lc *lapi.Client, - scs map[string]sv1.StorageClass, - rds map[string]lapi.ResourceDefinitionWithVolumeDefinition, - rgs map[string]lapi.ResourceGroup, -) { - pvs, err := GetListPV(ctx, cl) - if err != nil { - fmt.Println(err) - panic("[ReconcileParams] unable to get Persistent Volumes") - } - - for _, pv := range pvs { - if pv.Spec.CSI != nil && pv.Spec.CSI.Driver == PVCSIDriver { - sc := scs[pv.Spec.StorageClassName] - - RGName := rds[pv.Name].ResourceGroupName - rg := rgs[RGName] - getMissMatchedParams(sc, rg) - } - } -} - -func removePrefixes(params map[string]string) map[string]string { - tmp := make(map[string]string, len(params)) - for k, v := range params { - tmpKey := strings.Split(k, "/") - if len(tmpKey) > 0 { - newKey := tmpKey[len(tmpKey)-1] - tmp[newKey] = v - } - } - return tmp -} - -func getMissMatchedParams(sc sv1.StorageClass, rg lapi.ResourceGroup) { - scParams := removePrefixes(sc.Parameters) - fmt.Println("!!!!!!!> " + scParams[placementCountSCKey]) - - placeCount := strconv.Itoa(int(rg.SelectFilter.PlaceCount)) - fmt.Println("!!!!!!!> " + placeCount) -} diff --git a/test/pkg/kubeutils/kubernetes.go b/test/pkg/kubeutils/kubernetes.go deleted file mode 100644 index 43c578df..00000000 --- a/test/pkg/kubeutils/kubernetes.go +++ /dev/null @@ -1,37 +0,0 @@ -/* -Copyright 2023 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 kubutils - -import ( - "fmt" - - "k8s.io/client-go/rest" - "k8s.io/client-go/tools/clientcmd" -) - -func KubernetesDefaultConfigCreate() (*rest.Config, error) { - clientConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig( - clientcmd.NewDefaultClientConfigLoadingRules(), - &clientcmd.ConfigOverrides{}, - ) - // Get a config to talk to API server - config, err := clientConfig.ClientConfig() - if err != nil { - return nil, fmt.Errorf("config kubernetes error %w", err) - } - return config, nil -} diff --git a/test/pkg/logger/logger.go b/test/pkg/logger/logger.go deleted file mode 100644 index aabf8801..00000000 --- a/test/pkg/logger/logger.go +++ /dev/null @@ -1,87 +0,0 @@ -/* -Copyright 2023 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 logger - -import ( - "fmt" - "strconv" - - "github.com/go-logr/logr" - "k8s.io/klog/v2/textlogger" -) - -const ( - ErrorLevel Verbosity = "0" - WarningLevel Verbosity = "1" - InfoLevel Verbosity = "2" - DebugLevel Verbosity = "3" - TraceLevel Verbosity = "4" -) - -const ( - warnLvl = iota + 1 - infoLvl - debugLvl - traceLvl -) - -type ( - Verbosity string -) - -type Logger struct { - log logr.Logger -} - -func NewLogger(level Verbosity) (*Logger, error) { - v, err := strconv.Atoi(string(level)) - if err != nil { - return nil, err - } - - log := textlogger.NewLogger(textlogger.NewConfig(textlogger.Verbosity(v))).WithCallDepth(1) - - return &Logger{log: log}, nil -} - -func (l Logger) GetLogger() logr.Logger { - return l.log -} - -func (l Logger) Error(err error, message string, keysAndValues ...interface{}) { - l.log.Error(err, fmt.Sprintf("ERROR %s", message), keysAndValues...) -} - -func (l Logger) Warning(message string, keysAndValues ...interface{}) { - l.log.V(warnLvl).Info(fmt.Sprintf("WARNING %s", message), keysAndValues...) -} - -func (l Logger) Info(message string, keysAndValues ...interface{}) { - l.log.V(infoLvl).Info(fmt.Sprintf("INFO %s", message), keysAndValues...) -} - -func (l Logger) Debug(message string, keysAndValues ...interface{}) { - l.log.V(debugLvl).Info(fmt.Sprintf("DEBUG %s", message), keysAndValues...) -} - -func (l Logger) Trace(message string, keysAndValues ...interface{}) { - l.log.V(traceLvl).Info(fmt.Sprintf("TRACE %s", message), keysAndValues...) -} - -func (l *Logger) Printf(format string, args ...interface{}) { - l.log.V(traceLvl).Info("%s", fmt.Sprintf(format, args...)) -}