diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..08a2644 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,3 @@ +# More info: https://docs.docker.com/engine/reference/builder/#dockerignore-file +# Ignore build and test binaries. +metal-provider diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 463e5ac..6485164 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,13 +1,13 @@ version: 2 updates: -#- package-ecosystem: gomod -# directory: "/" -# schedule: -# interval: daily -# commit-message: -# prefix: "" -# reviewers: -# - Gchbg +- package-ecosystem: gomod + directory: "/" + schedule: + interval: daily + commit-message: + prefix: "" + reviewers: + - Gchbg - package-ecosystem: github-actions directory: "/" schedule: @@ -15,7 +15,7 @@ updates: commit-message: prefix: "" reviewers: - - Gchbg + - Gchbg - package-ecosystem: docker directory: "/" schedule: @@ -23,4 +23,4 @@ updates: commit-message: prefix: "" reviewers: - - Gchbg + - Gchbg diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml index 0a8ae7e..b5b2853 100644 --- a/.github/release-drafter.yml +++ b/.github/release-drafter.yml @@ -41,9 +41,15 @@ autolabeler: - '/fix\/.+/' title: - '/fix/i' -- label: 'enhancement' +- label: 'feature' branch: - '/feature\/.+/' +- label: 'enhancement' + branch: + - '/enh\/.+/' +- label: 'chore' + branch: + - '/chore\/.+/' template: | ## Changes $CHANGES diff --git a/.github/workflows/auto-merge.yml b/.github/workflows/auto-merge.yml new file mode 100644 index 0000000..2cc8534 --- /dev/null +++ b/.github/workflows/auto-merge.yml @@ -0,0 +1,20 @@ +name: Enable auto-merge + +on: pull_request_target + +jobs: + auto-merge: + name: Enable auto-merge + runs-on: ubuntu-latest + permissions: + pull-requests: write + contents: write + if: ${{ github.event.pull_request.draft == false }} + steps: + - name: Set up CLI + uses: ksivamuthu/actions-setup-gh-cli@v3 + - name: Enable auto-merge + run: gh pr merge --auto --squash "$PR_URL" + env: + PR_URL: ${{github.event.pull_request.html_url}} + GH_TOKEN: ${{secrets.GITHUB_TOKEN}} diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/draft-release.yml similarity index 73% rename from .github/workflows/release-drafter.yml rename to .github/workflows/draft-release.yml index f3b86be..5f1d607 100644 --- a/.github/workflows/release-drafter.yml +++ b/.github/workflows/draft-release.yml @@ -1,23 +1,24 @@ -name: Release Drafter +name: Draft release on: + pull_request_target: push: branches: - main -permissions: - contents: write - pull-requests: write - jobs: release-drafter: name: Draft release runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write steps: - name: Draft release uses: release-drafter/release-drafter@v6 with: disable-releaser: github.ref != 'refs/heads/main' config-name: release-drafter.yml + commitish: main env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 743efe8..d4abbdb 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -7,15 +7,13 @@ jobs: name: Lint runs-on: ubuntu-latest steps: - - name: Check out repository - uses: actions/checkout@v4 - with: - ref: ${{ github.event.pull_request.head.sha }} - - name: Set up Go - uses: actions/setup-go@v5 - with: - go-version-file: go.mod - - name: Run linter - uses: golangci/golangci-lint-action@v6 - with: - args: --timeout=7m + - name: Check out repository + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version-file: go.mod + - name: Run linter + uses: golangci/golangci-lint-action@v6 diff --git a/.github/workflows/publish-docker.yml b/.github/workflows/publish-docker.yml index 16ba26c..4e7707c 100644 --- a/.github/workflows/publish-docker.yml +++ b/.github/workflows/publish-docker.yml @@ -1,4 +1,4 @@ -name: Build and Publish Docker Image +name: Build and publish Docker image env: platforms: linux/amd64,linux/arm64 @@ -9,16 +9,15 @@ on: - main tags: - v* - pull_request: - -permissions: - contents: read - packages: write + pull_request_target: jobs: publish-docker: name: Build and publish Docker image runs-on: ubuntu-latest + permissions: + contents: read + packages: write steps: - name: Check out repository uses: actions/checkout@v4 diff --git a/.github/workflows/reuse.yml b/.github/workflows/reuse.yml index 06b9068..7dda5ca 100644 --- a/.github/workflows/reuse.yml +++ b/.github/workflows/reuse.yml @@ -1,4 +1,4 @@ -name: REUSE Compliance Check +name: Check REUSE compliance on: pull_request diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5d65518 --- /dev/null +++ b/.gitignore @@ -0,0 +1,27 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib +Dockerfile.cross +metal-provider + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Go workspace file +go.work + +# Kubernetes Generated files - skip generated files, except for vendored files +!vendor/**/zz_generated.* + +# editor and IDE paraphernalia +.idea +.vscode +*.swp +*.swo +*~ diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..058f79a --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,24 @@ +run: + allow-parallel-runners: true + timeout: 5m + +linters: + disable-all: true + enable: + - dupl + - errcheck + - exportloopref + - goconst + - gofmt + - goimports + - gosimple + - govet + - ineffassign + - misspell + - nakedret + - prealloc + - staticcheck + - typecheck + - unconvert + - unparam + - unused diff --git a/Dockerfile b/Dockerfile index 7bc8527..3e84dad 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,21 +1,18 @@ -FROM golang:1.22.3 as builder -ARG GOARCH +FROM golang:1.22.3 AS builder +ARG TARGETOS +ARG TARGETARCH WORKDIR /metal-provider - COPY go.mod go.mod COPY go.sum go.sum RUN go mod download +COPY cmd/ cmd/ COPY internal/ internal/ -COPY servers/ servers/ -COPY *.go ./ -RUN CGO_ENABLED=0 GOOS=linux GOARCH=${GOARCH} go build -a -o metal-provider . +RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o metal-provider cmd/main.go FROM debian:bookworm-20240513-slim - WORKDIR / - USER 65532:65532 ENTRYPOINT ["/metal-provider"] diff --git a/Makefile b/Makefile index c575df4..721a7e1 100644 --- a/Makefile +++ b/Makefile @@ -4,9 +4,24 @@ SHELL = /usr/bin/env bash -o pipefail .PHONY: all all: build +##@ General + +# The help target prints out all targets with their descriptions organized +# beneath their categories. The categories are represented by '##@' and the +# target descriptions by '##'. The awk command is responsible for reading the +# entire set of makefiles included in this invocation, looking for lines of the +# file as xyz: ## something, and then pretty-format the target and help. Then, +# if there's a line with ##@ something, that gets pretty-printed as a category. +# More info on the usage of ANSI control characters for terminal formatting: +# https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters +# More info on the awk command: +# http://linuxcommand.org/lc3_adv_awk.php + .PHONY: help help: ## Display this help. - @awk 'BEGIN {FS = ":.*##"; printf "Usage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) + @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) + +##@ Development .PHONY: fmt fmt: ## Run go fmt against code. @@ -17,17 +32,23 @@ vet: ## Run go vet against code. @go vet ./... .PHONY: test -test: fmt vet ## Run tests. - @go run github.com/onsi/ginkgo/v2/ginkgo -r --race --randomize-suites --randomize-all --keep-going --timeout=9223372036s -v +test: ## Run tests. + @go run github.com/onsi/ginkgo/v2/ginkgo -r --race --randomize-suites --keep-going --randomize-all --repeat=11 -.PHONY: build -build: fmt vet ## Build manager binary. - @go build -o metal-provider . +.PHONY: lint +lint: ## Run golangci-lint linter & yamllint. + @go run github.com/golangci/golangci-lint/cmd/golangci-lint run .PHONY: addlicense addlicense: ## Add license headers to all go files. - find . -name '*.go' -exec go run github.com/google/addlicense -f hack/license-header.txt {} + + @find . -name '*.go' -exec go run github.com/google/addlicense -f .reuse/license-header.txt {} + .PHONY: checklicense checklicense: ## Check that every file has a license header present. - find . -name '*.go' -exec go run github.com/google/addlicense -check -c 'IronCore authors' {} + + @find . -name '*.go' -exec go run github.com/google/addlicense -check -c 'IronCore authors' {} + + +##@ Build + +.PHONY: build +build: fmt vet ## Build manager binary. + @go build -o metal-provider cmd/main.go diff --git a/PROJECT b/PROJECT new file mode 100644 index 0000000..2835291 --- /dev/null +++ b/PROJECT @@ -0,0 +1,6 @@ +domain: ironcore.dev +layout: +- go.kubebuilder.io/v4 +projectName: metal-provider +repo: github.com/ironcore-dev/metal-provider +version: "3" diff --git a/cmd/main.go b/cmd/main.go new file mode 100644 index 0000000..564c6bd --- /dev/null +++ b/cmd/main.go @@ -0,0 +1,247 @@ +// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and IronCore contributors +// SPDX-License-Identifier: Apache-2.0 + +package main + +import ( + "context" + "crypto/tls" + "fmt" + "os" + "os/signal" + "path/filepath" + "strings" + "syscall" + + "github.com/go-logr/logr" + computev1alpha1 "github.com/ironcore-dev/ironcore/api/compute/v1alpha1" + metalv1alpha1 "github.com/ironcore-dev/metal/api/v1alpha1" + "github.com/spf13/pflag" + "github.com/spf13/viper" + "k8s.io/apimachinery/pkg/runtime" + kscheme "k8s.io/client-go/kubernetes/scheme" + _ "k8s.io/client-go/plugin/pkg/client/auth" + "k8s.io/client-go/rest" + "k8s.io/klog/v2" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/config" + "sigs.k8s.io/controller-runtime/pkg/healthz" + "sigs.k8s.io/controller-runtime/pkg/manager" + metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" + "sigs.k8s.io/controller-runtime/pkg/webhook" + + "github.com/ironcore-dev/metal-provider/internal/log" + "github.com/ironcore-dev/metal-provider/internal/namespace" + "github.com/ironcore-dev/metal-provider/internal/server" +) + +type params struct { + dev bool + leaderElection bool + healthProbeBindAddress string + metricsBindAddress string + secureMetrics bool + enableHTTP2 bool + kubeconfig string + enableMetalProviderServer bool + metalProviderGRPCAddr string + metalProviderNamespace string // fixme +} + +func parseCmdLine() params { + pflag.Usage = usage + pflag.ErrHelp = nil + pflag.CommandLine = pflag.NewFlagSet(os.Args[0], pflag.ContinueOnError) + + pflag.Bool("dev", false, "Run in development mode.") + pflag.Bool("leader-elect", false, "Enable leader election to ensure there is only one active controller manager.") + pflag.String("health-probe-bind-address", "", "The address that the health probe server binds to.") + pflag.String("metrics-bind-address", "0", "The address that the metrics server binds to.") + pflag.Bool("metrics-secure", false, "Serve metrics securely.") + pflag.Bool("enable-http2", false, "Enable HTTP2 for the metrics and webhook servers.") + pflag.String("kubeconfig", "", "Use a kubeconfig to run out of cluster.") + pflag.Bool("enable-metal-provider-server", true, "Enable the metal provider server.") + pflag.String("metal-provider-grpc-address", "/run/metal-provider.sock", "Metal provider: The address that the gRPC server will listen on.") + pflag.String("metal-provider-namespace", "", "Limit monitoring to a specific namespace.") //fixme + + var help bool + pflag.BoolVarP(&help, "help", "h", false, "Show this help message.") + err := viper.BindPFlags(pflag.CommandLine) + if err != nil { + exitUsage(err) + } + viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_")) + viper.AutomaticEnv() + err = pflag.CommandLine.Parse(os.Args[1:]) + if err != nil { + exitUsage(err) + } + if help { + exitUsage(nil) + } + + return params{ + dev: viper.GetBool("dev"), + leaderElection: viper.GetBool("leader-elect"), + healthProbeBindAddress: viper.GetString("health-probe-bind-address"), + metricsBindAddress: viper.GetString("metrics-bind-address"), + secureMetrics: viper.GetBool("metrics-secure"), + enableHTTP2: viper.GetBool("enable-http2"), + kubeconfig: viper.GetString("kubeconfig"), + enableMetalProviderServer: viper.GetBool("enable-metal-provider-server"), + metalProviderGRPCAddr: viper.GetString("metal-provider-grpc-address"), + metalProviderNamespace: viper.GetString("metal-provider-namespace"), + } +} + +func usage() { + name := filepath.Base(os.Args[0]) + _, _ = fmt.Fprintf(os.Stderr, "Usage: %s [--option]...\n", name) + _, _ = fmt.Fprintf(os.Stderr, "Options:\n") + pflag.PrintDefaults() +} + +func exitUsage(err error) { + if err != nil { + _, _ = fmt.Fprintf(os.Stderr, "%s: %s\n", filepath.Base(os.Args[0]), err) + } + pflag.Usage() + os.Exit(2) +} + +func main() { + p := parseCmdLine() + + var exitCode int + defer func() { + os.Exit(exitCode) + }() + + ctx, stop := signal.NotifyContext(log.Setup(context.Background(), p.dev, false, os.Stderr), syscall.SIGTERM, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGHUP) + defer stop() + log.Info(ctx, "Starting Metal provider") + + defer func() { + log.Info(ctx, "Exiting", "exitCode", exitCode) + }() + + l := logr.FromContextOrDiscard(ctx) + klog.SetLogger(l) + ctrl.SetLogger(l) + + scheme := runtime.NewScheme() + err := kscheme.AddToScheme(scheme) + if err != nil { + log.Error(ctx, fmt.Errorf("cannot create type scheme: %w", err)) + exitCode = 1 + return + } + err = metalv1alpha1.AddToScheme(scheme) + if err != nil { + log.Error(ctx, fmt.Errorf("cannot create type scheme: %w", err)) + exitCode = 1 + return + } + err = computev1alpha1.AddToScheme(scheme) + if err != nil { + log.Error(ctx, fmt.Errorf("cannot create type scheme: %w", err)) + exitCode = 1 + return + } + //+kubebuilder:scaffold:scheme + + var kcfg *rest.Config + kcfg, err = ctrl.GetConfig() + if err != nil { + log.Error(ctx, fmt.Errorf("cannot get kubeconfig: %w", err)) + exitCode = 1 + return + } + + if p.metalProviderNamespace == "" { // fixme + p.metalProviderNamespace = namespace.InClusterNamespace() + if p.metalProviderNamespace == "" { + log.Error(ctx, fmt.Errorf("metal provider namespace must be specified when running out of cluster")) + exitCode = 1 + return + } + } + + var tlsOpts []func(*tls.Config) + if !p.enableHTTP2 { + tlsOpts = append(tlsOpts, func(c *tls.Config) { + c.NextProtos = []string{"http/1.1"} + }) + } + + maxConcurrentReconciles := 11 + if p.dev { + maxConcurrentReconciles = 1 + } + var mgr manager.Manager + mgr, err = ctrl.NewManager(kcfg, ctrl.Options{ + Scheme: scheme, + LeaderElection: p.leaderElection, + LeaderElectionID: "metal-provider.ironcore.dev", + Metrics: metricsserver.Options{ + BindAddress: p.metricsBindAddress, + SecureServing: p.secureMetrics, + TLSOpts: tlsOpts, + }, + HealthProbeBindAddress: p.healthProbeBindAddress, + WebhookServer: webhook.NewServer(webhook.Options{ + TLSOpts: tlsOpts, + }), + BaseContext: func() context.Context { + return ctx + }, + Controller: config.Controller{ + MaxConcurrentReconciles: maxConcurrentReconciles, + }, + }) + if err != nil { + log.Error(ctx, fmt.Errorf("cannot create manager: %w", err)) + exitCode = 1 + return + } + + if p.enableMetalProviderServer { + var metalProviderServer *server.MetalProviderServer + metalProviderServer, err = server.NewMetalProviderServer(p.metalProviderGRPCAddr, p.metalProviderNamespace) + if err != nil { + log.Error(ctx, fmt.Errorf("cannot create server: %w", err), "server", "MetalProvider") + exitCode = 1 + return + } + err = metalProviderServer.SetupWithManager(mgr) + if err != nil { + log.Error(ctx, fmt.Errorf("cannot create server: %w", err), "server", "MetalProvider") + exitCode = 1 + return + } + } + + //+kubebuilder:scaffold:builder + + err = mgr.AddHealthzCheck("health", healthz.Ping) + if err != nil { + log.Error(ctx, fmt.Errorf("cannot set up health check: %w", err)) + exitCode = 1 + return + } + + err = mgr.AddReadyzCheck("check", healthz.Ping) + if err != nil { + log.Error(ctx, fmt.Errorf("cannot set up ready check: %w", err)) + exitCode = 1 + return + } + + log.Info(ctx, "Starting manager") + err = mgr.Start(ctx) + if err != nil { + log.Error(ctx, err) + exitCode = 1 + return + } +} diff --git a/config/default/kustomization.yaml b/config/default/kustomization.yaml index c2262f9..2f14a3b 100644 --- a/config/default/kustomization.yaml +++ b/config/default/kustomization.yaml @@ -6,5 +6,5 @@ bases: - ../rbac - ../manager -patchesStrategicMerge: -- manager_auth_proxy_patch.yaml +patches: +- path: manager_auth_proxy_patch.yaml diff --git a/config/default/manager_auth_proxy_patch.yaml b/config/default/manager_auth_proxy_patch.yaml index 6600ac6..a4d6ef0 100644 --- a/config/default/manager_auth_proxy_patch.yaml +++ b/config/default/manager_auth_proxy_patch.yaml @@ -12,7 +12,7 @@ spec: allowPrivilegeEscalation: false capabilities: drop: - - "ALL" + - "ALL" image: gcr.io/kubebuilder/kube-rbac-proxy:v0.15.0 args: - "--secure-listen-address=0.0.0.0:8443" diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml index 4fe5cca..5c5f0b8 100644 --- a/config/manager/kustomization.yaml +++ b/config/manager/kustomization.yaml @@ -1,5 +1,2 @@ resources: - manager.yaml - -generatorOptions: - disableNameSuffixHash: true diff --git a/config/manager/manager.yaml b/config/manager/manager.yaml index e7041ac..f55a473 100644 --- a/config/manager/manager.yaml +++ b/config/manager/manager.yaml @@ -3,6 +3,12 @@ kind: Namespace metadata: labels: control-plane: controller-manager + app.kubernetes.io/name: namespace + app.kubernetes.io/instance: system + app.kubernetes.io/component: manager + app.kubernetes.io/created-by: metal-provider + app.kubernetes.io/part-of: metal-provider + app.kubernetes.io/managed-by: kustomize name: system --- apiVersion: apps/v1 @@ -12,6 +18,12 @@ metadata: namespace: system labels: control-plane: controller-manager + app.kubernetes.io/name: deployment + app.kubernetes.io/instance: controller-manager + app.kubernetes.io/component: manager + app.kubernetes.io/created-by: metal-provider + app.kubernetes.io/part-of: metal-provider + app.kubernetes.io/managed-by: kustomize spec: selector: matchLabels: diff --git a/config/rbac/auth_proxy_client_clusterrole.yaml b/config/rbac/auth_proxy_client_clusterrole.yaml index 51a75db..40e1401 100644 --- a/config/rbac/auth_proxy_client_clusterrole.yaml +++ b/config/rbac/auth_proxy_client_clusterrole.yaml @@ -1,6 +1,13 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: + labels: + app.kubernetes.io/name: clusterrole + app.kubernetes.io/instance: metrics-reader + app.kubernetes.io/component: kube-rbac-proxy + app.kubernetes.io/created-by: metal-provider + app.kubernetes.io/part-of: metal-provider + app.kubernetes.io/managed-by: kustomize name: metrics-reader rules: - nonResourceURLs: diff --git a/config/rbac/auth_proxy_role.yaml b/config/rbac/auth_proxy_role.yaml index 80e1857..d5c5fd7 100644 --- a/config/rbac/auth_proxy_role.yaml +++ b/config/rbac/auth_proxy_role.yaml @@ -1,6 +1,13 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: + labels: + app.kubernetes.io/name: clusterrole + app.kubernetes.io/instance: proxy-role + app.kubernetes.io/component: kube-rbac-proxy + app.kubernetes.io/created-by: metal-provider + app.kubernetes.io/part-of: metal-provider + app.kubernetes.io/managed-by: kustomize name: proxy-role rules: - apiGroups: diff --git a/config/rbac/auth_proxy_role_binding.yaml b/config/rbac/auth_proxy_role_binding.yaml index ec7acc0..2a74585 100644 --- a/config/rbac/auth_proxy_role_binding.yaml +++ b/config/rbac/auth_proxy_role_binding.yaml @@ -1,6 +1,13 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: + labels: + app.kubernetes.io/name: clusterrolebinding + app.kubernetes.io/instance: proxy-rolebinding + app.kubernetes.io/component: kube-rbac-proxy + app.kubernetes.io/created-by: metal-provider + app.kubernetes.io/part-of: metal-provider + app.kubernetes.io/managed-by: kustomize name: proxy-rolebinding roleRef: apiGroup: rbac.authorization.k8s.io diff --git a/config/rbac/auth_proxy_service.yaml b/config/rbac/auth_proxy_service.yaml index 71f1797..763a769 100644 --- a/config/rbac/auth_proxy_service.yaml +++ b/config/rbac/auth_proxy_service.yaml @@ -3,6 +3,12 @@ kind: Service metadata: labels: control-plane: controller-manager + app.kubernetes.io/name: service + app.kubernetes.io/instance: controller-manager-metrics-service + app.kubernetes.io/component: kube-rbac-proxy + app.kubernetes.io/created-by: metal-provider + app.kubernetes.io/part-of: metal-provider + app.kubernetes.io/managed-by: kustomize name: controller-manager-metrics-service namespace: system spec: diff --git a/config/rbac/leader_election_role.yaml b/config/rbac/leader_election_role.yaml index d11c2dd..cb19073 100644 --- a/config/rbac/leader_election_role.yaml +++ b/config/rbac/leader_election_role.yaml @@ -1,6 +1,13 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: + labels: + app.kubernetes.io/name: role + app.kubernetes.io/instance: leader-election-role + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: metal-provider + app.kubernetes.io/part-of: metal-provider + app.kubernetes.io/managed-by: kustomize name: leader-election-role rules: - apiGroups: diff --git a/config/rbac/leader_election_role_binding.yaml b/config/rbac/leader_election_role_binding.yaml index 1d1321e..a99bbf4 100644 --- a/config/rbac/leader_election_role_binding.yaml +++ b/config/rbac/leader_election_role_binding.yaml @@ -1,6 +1,13 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: + labels: + app.kubernetes.io/name: rolebinding + app.kubernetes.io/instance: leader-election-rolebinding + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: metal-provider + app.kubernetes.io/part-of: metal-provider + app.kubernetes.io/managed-by: kustomize name: leader-election-rolebinding roleRef: apiGroup: rbac.authorization.k8s.io diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 7f4c2bd..338c01c 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -59,130 +59,3 @@ rules: - certificatesigningrequests/machinepoolclient verbs: - create -- apiGroups: - - compute.ironcore.dev - resources: - - machineclasses - verbs: - - get - - list - - watch -- apiGroups: - - compute.ironcore.dev - resources: - - machinepools - verbs: - - create - - get - - list - - patch - - update - - watch -- apiGroups: - - compute.ironcore.dev - resources: - - machinepools/status - verbs: - - get - - patch - - update -- apiGroups: - - compute.ironcore.dev - resources: - - machines - verbs: - - get - - list - - patch - - update - - watch -- apiGroups: - - compute.ironcore.dev - resources: - - machines/finalizers - verbs: - - update -- apiGroups: - - compute.ironcore.dev - resources: - - machines/status - verbs: - - get - - patch - - update -- apiGroups: - - ipam.ironcore.dev - resources: - - prefixes - verbs: - - get - - list - - watch -- apiGroups: - - networking.ironcore.dev - resources: - - networkinterfaces - verbs: - - get - - list - - patch - - update - - watch -- apiGroups: - - networking.ironcore.dev - resources: - - networkinterfaces/status - verbs: - - get - - patch - - update -- apiGroups: - - networking.ironcore.dev - resources: - - networks - verbs: - - get - - list - - watch -- apiGroups: - - storage.ironcore.dev - resources: - - volumes - verbs: - - get - - list - - patch - - update - - watch -- apiGroups: - - metal.ironcore.dev - resources: - - machines - verbs: - - get - - list - - patch - - update - - watch -- apiGroups: - - metal.ironcore.dev - resources: - - machines/status - verbs: - - get - - patch - - update -- apiGroups: - - metal.ironcore.dev - resources: - - sizes - verbs: - - get - - list - - watch -- apiGroups: - - metal.ironcore.dev - resources: - - sizes/status - verbs: - - get diff --git a/config/rbac/role_binding.yaml b/config/rbac/role_binding.yaml index 2070ede..9372d2a 100644 --- a/config/rbac/role_binding.yaml +++ b/config/rbac/role_binding.yaml @@ -1,6 +1,13 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: + labels: + app.kubernetes.io/name: clusterrolebinding + app.kubernetes.io/instance: manager-rolebinding + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: metal-provider + app.kubernetes.io/part-of: metal-provider + app.kubernetes.io/managed-by: kustomize name: manager-rolebinding roleRef: apiGroup: rbac.authorization.k8s.io diff --git a/config/rbac/service_account.yaml b/config/rbac/service_account.yaml index 7cd6025..4c9628f 100644 --- a/config/rbac/service_account.yaml +++ b/config/rbac/service_account.yaml @@ -1,5 +1,12 @@ apiVersion: v1 kind: ServiceAccount metadata: + labels: + app.kubernetes.io/name: serviceaccount + app.kubernetes.io/instance: controller-manager-sa + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: metal-provider + app.kubernetes.io/part-of: metal-provider + app.kubernetes.io/managed-by: kustomize name: controller-manager namespace: system diff --git a/go.mod b/go.mod index 317b66d..a51a87b 100644 --- a/go.mod +++ b/go.mod @@ -1,106 +1,246 @@ module github.com/ironcore-dev/metal-provider -go 1.22 +go 1.22.3 require ( - github.com/go-logr/logr v1.4.1 + github.com/go-logr/logr v1.4.2 github.com/go-logr/zerologr v1.2.3 + github.com/golangci/golangci-lint v1.59.0 github.com/google/addlicense v1.1.1 - github.com/ironcore-dev/ironcore v0.1.2-0.20240305221731-20d84f49d48d - github.com/ironcore-dev/metal v0.11.2 - github.com/onsi/ginkgo/v2 v2.16.0 - github.com/onsi/gomega v1.31.1 - github.com/rs/zerolog v1.32.0 + github.com/ironcore-dev/ironcore v0.1.2 + github.com/ironcore-dev/metal v0.0.0-20240604143639-2360012c7845 + github.com/onsi/ginkgo/v2 v2.19.0 + github.com/onsi/gomega v1.33.1 + github.com/rs/zerolog v1.33.0 github.com/spf13/pflag v1.0.5 - github.com/spf13/viper v1.18.2 - golang.org/x/sync v0.6.0 - golang.org/x/sys v0.18.0 - google.golang.org/grpc v1.62.1 - k8s.io/api v0.29.2 - k8s.io/apimachinery v0.29.2 - k8s.io/client-go v0.29.2 + github.com/spf13/viper v1.19.0 + golang.org/x/sync v0.7.0 + golang.org/x/sys v0.20.0 + google.golang.org/grpc v1.64.0 + k8s.io/apimachinery v0.30.1 + k8s.io/client-go v0.30.1 k8s.io/klog/v2 v2.120.1 - sigs.k8s.io/controller-runtime v0.17.2 + sigs.k8s.io/controller-runtime v0.18.3 ) require ( + 4d63.com/gocheckcompilerdirectives v1.2.1 // indirect + 4d63.com/gochecknoglobals v0.2.1 // indirect + github.com/4meepo/tagalign v1.3.4 // indirect + github.com/Abirdcfly/dupword v0.0.14 // indirect + github.com/Antonboom/errname v0.1.13 // indirect + github.com/Antonboom/nilnil v0.1.9 // indirect + github.com/Antonboom/testifylint v1.3.0 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect + github.com/BurntSushi/toml v1.4.0 // indirect + github.com/Crocmagnon/fatcontext v0.2.2 // indirect + github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect + github.com/GaijinEntertainment/go-exhaustruct/v3 v3.2.0 // indirect + github.com/Masterminds/semver/v3 v3.2.1 // indirect + github.com/OpenPeeDeeP/depguard/v2 v2.2.0 // indirect + github.com/alecthomas/go-check-sumtype v0.1.4 // indirect + github.com/alexkohler/nakedret/v2 v2.0.4 // indirect + github.com/alexkohler/prealloc v1.0.0 // indirect + github.com/alingse/asasalint v0.0.11 // indirect + github.com/ashanbrown/forbidigo v1.6.0 // indirect + github.com/ashanbrown/makezero v1.1.1 // indirect github.com/beorn7/perks v1.0.1 // indirect + github.com/bkielbasa/cyclop v1.2.1 // indirect + github.com/blizzy78/varnamelen v0.8.0 // indirect github.com/bmatcuk/doublestar/v4 v4.0.2 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/bombsimon/wsl/v4 v4.2.1 // indirect + github.com/breml/bidichk v0.2.7 // indirect + github.com/breml/errchkjson v0.3.6 // indirect + github.com/butuzov/ireturn v0.3.0 // indirect + github.com/butuzov/mirror v1.2.0 // indirect + github.com/catenacyber/perfsprint v0.7.1 // indirect + github.com/ccojocar/zxcvbn-go v1.0.2 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/charithe/durationcheck v0.0.10 // indirect + github.com/chavacava/garif v0.1.0 // indirect + github.com/ckaznocha/intrange v0.1.2 // indirect + github.com/curioswitch/go-reassign v0.2.0 // indirect + github.com/daixiang0/gci v0.13.4 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/emicklei/go-restful/v3 v3.11.2 // indirect + github.com/denis-tingaikin/go-header v0.5.0 // indirect + github.com/emicklei/go-restful/v3 v3.12.0 // indirect + github.com/ettle/strcase v0.2.0 // indirect github.com/evanphx/json-patch/v5 v5.9.0 // indirect + github.com/fatih/color v1.17.0 // indirect + github.com/fatih/structtag v1.2.0 // indirect + github.com/firefart/nonamedreturns v1.0.5 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/fzipp/gocyclo v0.6.0 // indirect + github.com/ghostiam/protogetter v0.3.6 // indirect + github.com/go-critic/go-critic v0.11.4 // indirect github.com/go-logr/zapr v1.3.0 // indirect - github.com/go-openapi/jsonpointer v0.20.2 // indirect - github.com/go-openapi/jsonreference v0.20.4 // indirect - github.com/go-openapi/swag v0.22.9 // indirect - github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // 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/go-toolsmith/astcast v1.1.0 // indirect + github.com/go-toolsmith/astcopy v1.1.0 // indirect + github.com/go-toolsmith/astequal v1.2.0 // indirect + github.com/go-toolsmith/astfmt v1.1.0 // indirect + github.com/go-toolsmith/astp v1.1.0 // indirect + github.com/go-toolsmith/strparse v1.1.0 // indirect + github.com/go-toolsmith/typep v1.1.0 // indirect + github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1 // indirect + github.com/go-xmlfmt/xmlfmt v1.1.2 // indirect + github.com/gobwas/glob v0.2.3 // indirect + github.com/gofrs/flock v0.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.3 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect + github.com/golangci/gofmt v0.0.0-20231018234816-f50ced29576e // indirect + github.com/golangci/misspell v0.5.1 // indirect + github.com/golangci/modinfo v0.3.4 // indirect + github.com/golangci/plugin-module-register v0.1.1 // indirect + github.com/golangci/revgrep v0.5.3 // indirect + github.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect + github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 // indirect github.com/google/uuid v1.6.0 // indirect + github.com/gordonklaus/ineffassign v0.1.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect + github.com/gostaticanalysis/analysisutil v0.7.1 // indirect + github.com/gostaticanalysis/comment v1.4.2 // indirect + github.com/gostaticanalysis/forcetypeassert v0.1.0 // indirect + github.com/gostaticanalysis/nilerr v0.1.1 // indirect + github.com/hashicorp/go-version v1.7.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect + github.com/hexops/gotextdiff v1.0.3 // indirect github.com/imdario/mergo v0.3.16 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/jgautheron/goconst v1.7.1 // indirect + github.com/jingyugao/rowserrcheck v1.1.1 // indirect + github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect + github.com/jjti/go-spancheck v0.6.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/julz/importas v0.1.0 // indirect + github.com/karamaru-alpha/copyloopvar v1.1.0 // indirect + github.com/kisielk/errcheck v1.7.0 // indirect + github.com/kkHAIKE/contextcheck v1.1.5 // indirect + github.com/kulti/thelper v0.6.3 // indirect + github.com/kunwardeep/paralleltest v1.0.10 // indirect + github.com/kyoh86/exportloopref v0.1.11 // indirect + github.com/lasiar/canonicalheader v1.1.1 // indirect + github.com/ldez/gomoddirectives v0.2.4 // indirect + github.com/ldez/tagliatelle v0.5.0 // indirect + github.com/leonklingele/grouper v1.1.2 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect + github.com/lufeee/execinquery v1.2.1 // indirect + github.com/macabu/inamedparam v0.1.3 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect + github.com/maratori/testableexamples v1.0.0 // indirect + github.com/maratori/testpackage v1.1.1 // indirect + github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-runewidth v0.0.9 // indirect + github.com/mgechev/revive v1.3.7 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/moby/spdystream v0.2.0 // indirect github.com/moby/term v0.0.0-20221205130635-1aeaba878587 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/moricho/tparallel v0.3.1 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect - github.com/pelletier/go-toml/v2 v2.1.1 // indirect + github.com/nakabonne/nestif v0.3.1 // indirect + github.com/nishanths/exhaustive v0.12.0 // indirect + github.com/nishanths/predeclared v0.2.2 // indirect + github.com/nunnatsa/ginkgolinter v0.16.2 // indirect + github.com/olekukonko/tablewriter v0.0.5 // indirect + github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/prometheus/client_golang v1.18.0 // indirect - github.com/prometheus/client_model v0.5.0 // indirect - github.com/prometheus/common v0.46.0 // indirect - github.com/prometheus/procfs v0.12.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/polyfloyd/go-errorlint v1.5.1 // indirect + github.com/prometheus/client_golang v1.19.1 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.53.0 // indirect + github.com/prometheus/procfs v0.15.0 // indirect + github.com/quasilyte/go-ruleguard v0.4.2 // indirect + github.com/quasilyte/go-ruleguard/dsl v0.3.22 // indirect + github.com/quasilyte/gogrep v0.5.0 // indirect + github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect + github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect + github.com/ryancurrah/gomodguard v1.3.2 // indirect + github.com/ryanrolds/sqlclosecheck v0.5.1 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect + github.com/sanposhiho/wastedassign/v2 v2.0.7 // indirect + github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect + github.com/sashamelentyev/interfacebloat v1.1.0 // indirect + github.com/sashamelentyev/usestdlibvars v1.25.0 // indirect + github.com/securego/gosec/v2 v2.20.1-0.20240525090044-5f0084eb01a9 // indirect + github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect + github.com/sirupsen/logrus v1.9.3 // indirect + github.com/sivchari/containedctx v1.0.3 // indirect + github.com/sivchari/tenv v1.7.1 // indirect + github.com/sonatard/noctx v0.0.2 // indirect github.com/sourcegraph/conc v0.3.0 // indirect + github.com/sourcegraph/go-diff v0.7.0 // indirect github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect github.com/spf13/cobra v1.8.0 // indirect + github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect + github.com/stbenjam/no-sprintf-host-port v0.1.1 // indirect + github.com/stretchr/objx v0.5.2 // indirect + github.com/stretchr/testify v1.9.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect + github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c // indirect + github.com/tdakkota/asciicheck v0.2.0 // indirect + github.com/tetafro/godot v1.4.16 // indirect + github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966 // indirect + github.com/timonwong/loggercheck v0.9.4 // indirect + github.com/tomarrell/wrapcheck/v2 v2.8.3 // indirect + github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect + github.com/ultraware/funlen v0.1.0 // indirect + github.com/ultraware/whitespace v0.1.1 // indirect + github.com/uudashr/gocognit v1.1.2 // indirect + github.com/xen0n/gosmopolitan v1.2.2 // indirect + github.com/yagipy/maintidx v1.0.0 // indirect + github.com/yeya24/promlinter v0.3.0 // indirect + github.com/ykadowak/zerologlint v0.1.5 // indirect + gitlab.com/bosi/decorder v0.4.2 // indirect + go-simpler.org/musttag v0.12.2 // indirect + go-simpler.org/sloglint v0.7.0 // indirect + go.uber.org/automaxprocs v1.5.3 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.26.0 // indirect - go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect - golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3 // indirect - golang.org/x/net v0.23.0 // indirect - golang.org/x/oauth2 v0.16.0 // indirect - golang.org/x/term v0.18.0 // indirect - golang.org/x/text v0.14.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect + golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f // indirect + golang.org/x/mod v0.17.0 // indirect + golang.org/x/net v0.25.0 // indirect + golang.org/x/oauth2 v0.20.0 // indirect + golang.org/x/term v0.20.0 // indirect + golang.org/x/text v0.15.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.17.0 // indirect + golang.org/x/tools v0.21.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240205150955-31a09d347014 // indirect - google.golang.org/protobuf v1.33.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect + google.golang.org/protobuf v1.34.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apiextensions-apiserver v0.29.1 // indirect - k8s.io/cli-runtime v0.29.2 // indirect - k8s.io/component-base v0.29.2 // indirect - k8s.io/kube-openapi v0.0.0-20240126223410-2919ad4fcfec // indirect - k8s.io/kubectl v0.29.2 // indirect - k8s.io/utils v0.0.0-20240102154912-e7106e64919e // indirect + honnef.co/go/tools v0.4.7 // indirect + k8s.io/api v0.30.1 // indirect + k8s.io/apiextensions-apiserver v0.30.1 // indirect + k8s.io/cli-runtime v0.29.4 // indirect + k8s.io/kube-openapi v0.0.0-20240430033511-f0e62f92d13f // indirect + k8s.io/kubectl v0.29.4 // indirect + k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 // indirect + mvdan.cc/gofumpt v0.6.0 // indirect + mvdan.cc/unparam v0.0.0-20240427195214-063aff900ca1 // 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/go.sum b/go.sum index 05202cf..52b838f 100644 --- a/go.sum +++ b/go.sum @@ -1,112 +1,302 @@ +4d63.com/gocheckcompilerdirectives v1.2.1 h1:AHcMYuw56NPjq/2y615IGg2kYkBdTvOaojYCBcRE7MA= +4d63.com/gocheckcompilerdirectives v1.2.1/go.mod h1:yjDJSxmDTtIHHCqX0ufRYZDL6vQtMG7tJdKVeWwsqvs= +4d63.com/gochecknoglobals v0.2.1 h1:1eiorGsgHOFOuoOiJDy2psSrQbRdIHrlge0IJIkUgDc= +4d63.com/gochecknoglobals v0.2.1/go.mod h1:KRE8wtJB3CXCsb1xy421JfTHIIbmT3U5ruxw2Qu8fSU= +github.com/4meepo/tagalign v1.3.4 h1:P51VcvBnf04YkHzjfclN6BbsopfJR5rxs1n+5zHt+w8= +github.com/4meepo/tagalign v1.3.4/go.mod h1:M+pnkHH2vG8+qhE5bVc/zeP7HS/j910Fwa9TUSyZVI0= +github.com/Abirdcfly/dupword v0.0.14 h1:3U4ulkc8EUo+CaT105/GJ1BQwtgyj6+VaBVbAX11Ba8= +github.com/Abirdcfly/dupword v0.0.14/go.mod h1:VKDAbxdY8YbKUByLGg8EETzYSuC4crm9WwI6Y3S0cLI= +github.com/Antonboom/errname v0.1.13 h1:JHICqsewj/fNckzrfVSe+T33svwQxmjC+1ntDsHOVvM= +github.com/Antonboom/errname v0.1.13/go.mod h1:uWyefRYRN54lBg6HseYCFhs6Qjcy41Y3Jl/dVhA87Ns= +github.com/Antonboom/nilnil v0.1.9 h1:eKFMejSxPSA9eLSensFmjW2XTgTwJMjZ8hUHtV4s/SQ= +github.com/Antonboom/nilnil v0.1.9/go.mod h1:iGe2rYwCq5/Me1khrysB4nwI7swQvjclR8/YRPl5ihQ= +github.com/Antonboom/testifylint v1.3.0 h1:UiqrddKs1W3YK8R0TUuWwrVKlVAnS07DTUVWWs9c+y4= +github.com/Antonboom/testifylint v1.3.0/go.mod h1:NV0hTlteCkViPW9mSR4wEMfwp+Hs1T3dY60bkvSfhpM= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= +github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= +github.com/Crocmagnon/fatcontext v0.2.2 h1:OrFlsDdOj9hW/oBEJBNSuH7QWf+E9WPVHw+x52bXVbk= +github.com/Crocmagnon/fatcontext v0.2.2/go.mod h1:WSn/c/+MMNiD8Pri0ahRj0o9jVpeowzavOQplBJw6u0= +github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 h1:sHglBQTwgx+rWPdisA5ynNEsoARbiCBOyGcJM4/OzsM= +github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= +github.com/GaijinEntertainment/go-exhaustruct/v3 v3.2.0 h1:sATXp1x6/axKxz2Gjxv8MALP0bXaNRfQinEwyfMcx8c= +github.com/GaijinEntertainment/go-exhaustruct/v3 v3.2.0/go.mod h1:Nl76DrGNJTA1KJ0LePKBw/vznBX1EHbAZX8mwjR82nI= +github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= +github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/OpenPeeDeeP/depguard/v2 v2.2.0 h1:vDfG60vDtIuf0MEOhmLlLLSzqaRM8EMcgJPdp74zmpA= +github.com/OpenPeeDeeP/depguard/v2 v2.2.0/go.mod h1:CIzddKRvLBC4Au5aYP/i3nyaWQ+ClszLIuVocRiCYFQ= +github.com/alecthomas/assert/v2 v2.2.2 h1:Z/iVC0xZfWTaFNE6bA3z07T86hd45Xe2eLt6WVy2bbk= +github.com/alecthomas/assert/v2 v2.2.2/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ= +github.com/alecthomas/go-check-sumtype v0.1.4 h1:WCvlB3l5Vq5dZQTFmodqL2g68uHiSwwlWcT5a2FGK0c= +github.com/alecthomas/go-check-sumtype v0.1.4/go.mod h1:WyYPfhfkdhyrdaligV6svFopZV8Lqdzn5pyVBaV6jhQ= +github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk= +github.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= +github.com/alexkohler/nakedret/v2 v2.0.4 h1:yZuKmjqGi0pSmjGpOC016LtPJysIL0WEUiaXW5SUnNg= +github.com/alexkohler/nakedret/v2 v2.0.4/go.mod h1:bF5i0zF2Wo2o4X4USt9ntUWve6JbFv02Ff4vlkmS/VU= +github.com/alexkohler/prealloc v1.0.0 h1:Hbq0/3fJPQhNkN0dR95AVrr6R7tou91y0uHG5pOcUuw= +github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE= +github.com/alingse/asasalint v0.0.11 h1:SFwnQXJ49Kx/1GghOFz1XGqHYKp21Kq1nHad/0WQRnw= +github.com/alingse/asasalint v0.0.11/go.mod h1:nCaoMhw7a9kSJObvQyVzNTPBDbNpdocqrSP7t/cW5+I= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/ashanbrown/forbidigo v1.6.0 h1:D3aewfM37Yb3pxHujIPSpTf6oQk9sc9WZi8gerOIVIY= +github.com/ashanbrown/forbidigo v1.6.0/go.mod h1:Y8j9jy9ZYAEHXdu723cUlraTqbzjKF1MUyfOKL+AjcU= +github.com/ashanbrown/makezero v1.1.1 h1:iCQ87C0V0vSyO+M9E/FZYbu65auqH0lnsOkf5FcB28s= +github.com/ashanbrown/makezero v1.1.1/go.mod h1:i1bJLCRSCHOcOa9Y6MyF2FTfMZMFdHvxKHxgO5Z1axI= 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/bkielbasa/cyclop v1.2.1 h1:AeF71HZDob1P2/pRm1so9cd1alZnrpyc4q2uP2l0gJY= +github.com/bkielbasa/cyclop v1.2.1/go.mod h1:K/dT/M0FPAiYjBgQGau7tz+3TMh4FWAEqlMhzFWCrgM= +github.com/blizzy78/varnamelen v0.8.0 h1:oqSblyuQvFsW1hbBHh1zfwrKe3kcSj0rnXkKzsQ089M= +github.com/blizzy78/varnamelen v0.8.0/go.mod h1:V9TzQZ4fLJ1DSrjVDfl89H7aMnTvKkApdHeyESmyR7k= github.com/bmatcuk/doublestar/v4 v4.0.2 h1:X0krlUVAVmtr2cRoTqR8aDMrDqnB36ht8wpWTiQ3jsA= github.com/bmatcuk/doublestar/v4 v4.0.2/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/bombsimon/wsl/v4 v4.2.1 h1:Cxg6u+XDWff75SIFFmNsqnIOgob+Q9hG6y/ioKbRFiM= +github.com/bombsimon/wsl/v4 v4.2.1/go.mod h1:Xu/kDxGZTofQcDGCtQe9KCzhHphIe0fDuyWTxER9Feo= +github.com/breml/bidichk v0.2.7 h1:dAkKQPLl/Qrk7hnP6P+E0xOodrq8Us7+U0o4UBOAlQY= +github.com/breml/bidichk v0.2.7/go.mod h1:YodjipAGI9fGcYM7II6wFvGhdMYsC5pHDlGzqvEW3tQ= +github.com/breml/errchkjson v0.3.6 h1:VLhVkqSBH96AvXEyclMR37rZslRrY2kcyq+31HCsVrA= +github.com/breml/errchkjson v0.3.6/go.mod h1:jhSDoFheAF2RSDOlCfhHO9KqhZgAYLyvHe7bRCX8f/U= +github.com/butuzov/ireturn v0.3.0 h1:hTjMqWw3y5JC3kpnC5vXmFJAWI/m31jaCYQqzkS6PL0= +github.com/butuzov/ireturn v0.3.0/go.mod h1:A09nIiwiqzN/IoVo9ogpa0Hzi9fex1kd9PSD6edP5ZA= +github.com/butuzov/mirror v1.2.0 h1:9YVK1qIjNspaqWutSv8gsge2e/Xpq1eqEkslEUHy5cs= +github.com/butuzov/mirror v1.2.0/go.mod h1:DqZZDtzm42wIAIyHXeN8W/qb1EPlb9Qn/if9icBOpdQ= +github.com/catenacyber/perfsprint v0.7.1 h1:PGW5G/Kxn+YrN04cRAZKC+ZuvlVwolYMrIyyTJ/rMmc= +github.com/catenacyber/perfsprint v0.7.1/go.mod h1:/wclWYompEyjUD2FuIIDVKNkqz7IgBIWXIH3V0Zol50= +github.com/ccojocar/zxcvbn-go v1.0.2 h1:na/czXU8RrhXO4EZme6eQJLR4PzcGsahsBOAwU6I3Vg= +github.com/ccojocar/zxcvbn-go v1.0.2/go.mod h1:g1qkXtUSvHP8lhHp5GrSmTz6uWALGRMQdw6Qnz/hi60= +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/charithe/durationcheck v0.0.10 h1:wgw73BiocdBDQPik+zcEoBG/ob8uyBHf2iyoHGPf5w4= +github.com/charithe/durationcheck v0.0.10/go.mod h1:bCWXb7gYRysD1CU3C+u4ceO49LoGOY1C1L6uouGNreQ= +github.com/chavacava/garif v0.1.0 h1:2JHa3hbYf5D9dsgseMKAmc/MZ109otzgNFk5s87H9Pc= +github.com/chavacava/garif v0.1.0/go.mod h1:XMyYCkEL58DF0oyW4qDjjnPWONs2HBqYKI+UIPD+Gww= +github.com/ckaznocha/intrange v0.1.2 h1:3Y4JAxcMntgb/wABQ6e8Q8leMd26JbX2790lIss9MTI= +github.com/ckaznocha/intrange v0.1.2/go.mod h1:RWffCw/vKBwHeOEwWdCikAtY0q4gGt8VhJZEEA5n+RE= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= +github.com/curioswitch/go-reassign v0.2.0 h1:G9UZyOcpk/d7Gd6mqYgd8XYWFMw/znxwGDUstnC9DIo= +github.com/curioswitch/go-reassign v0.2.0/go.mod h1:x6OpXuWvgfQaMGks2BZybTngWjT84hqJfKoO8Tt/Roc= +github.com/daixiang0/gci v0.13.4 h1:61UGkmpoAcxHM2hhNkZEf5SzwQtWJXTSws7jaPyqwlw= +github.com/daixiang0/gci v0.13.4/go.mod h1:12etP2OniiIdP4q+kjUGrC/rUagga7ODbqsom5Eo5Yk= 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.2 h1:1onLa9DcsMYO9P+CXaL0dStDqQ2EHHXLiz+BtnqkLAU= -github.com/emicklei/go-restful/v3 v3.11.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lShz4oaXpDTX2bLe7ls= -github.com/evanphx/json-patch v5.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/denis-tingaikin/go-header v0.5.0 h1:SRdnP5ZKvcO9KKRP1KJrhFR3RrlGuD+42t4429eC9k8= +github.com/denis-tingaikin/go-header v0.5.0/go.mod h1:mMenU5bWrok6Wl2UsZjy+1okegmwQ3UgWl4V1D8gjlY= +github.com/emicklei/go-restful/v3 v3.12.0 h1:y2DdzBAURM29NFF94q6RaY4vjIH1rtwDapwQtU84iWk= +github.com/emicklei/go-restful/v3 v3.12.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/ettle/strcase v0.2.0 h1:fGNiVF21fHXpX1niBgk0aROov1LagYsOwV/xqKDKR/Q= +github.com/ettle/strcase v0.2.0/go.mod h1:DajmHElDSaX76ITe3/VHVyMin4LWSJN5Z909Wp+ED1A= +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/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= +github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= +github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= +github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= +github.com/firefart/nonamedreturns v1.0.5 h1:tM+Me2ZaXs8tfdDw3X6DOX++wMCOqzYUho6tUTYIdRA= +github.com/firefart/nonamedreturns v1.0.5/go.mod h1:gHJjDqhGM4WyPt639SOZs+G89Ko7QKH5R5BhnO6xJhw= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= 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/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk= -github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo= +github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA= +github.com/ghostiam/protogetter v0.3.6 h1:R7qEWaSgFCsy20yYHNIJsU9ZOb8TziSRRxuAOTVKeOk= +github.com/ghostiam/protogetter v0.3.6/go.mod h1:7lpeDnEJ1ZjL/YtyoN99ljO4z0pd3H0d18/t2dPBxHw= +github.com/go-critic/go-critic v0.11.4 h1:O7kGOCx0NDIni4czrkRIXTnit0mkyKOCePh3My6OyEU= +github.com/go-critic/go-critic v0.11.4/go.mod h1:2QAdo4iuLik5S9YG0rT4wcZ8QxwHYkrr6/2MWAiv/vc= +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-logr/zerologr v1.2.3 h1:up5N9vcH9Xck3jJkXzgyOxozT14R47IyDODz8LM1KSs= github.com/go-logr/zerologr v1.2.3/go.mod h1:BxwGo7y5zgSHYR1BjbnHPyF/5ZjVKfKxAZANVu6E8Ho= -github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q= -github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs= -github.com/go-openapi/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdXSSgNeAhojU= -github.com/go-openapi/jsonreference v0.20.4/go.mod h1:5pZJyJP2MnYCpoeoMAql78cCHauHj0V9Lhc506VOpw4= -github.com/go-openapi/swag v0.22.9 h1:XX2DssF+mQKM2DHsbgZK74y/zj4mo9I99+89xUmuZCE= -github.com/go-openapi/swag v0.22.9/go.mod h1:3/OXnFfnMAwBD099SwYRk7GD3xOrr1iL7d/XNLXVVwE= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +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/go-toolsmith/astcast v1.1.0 h1:+JN9xZV1A+Re+95pgnMgDboWNVnIMMQXwfBwLRPgSC8= +github.com/go-toolsmith/astcast v1.1.0/go.mod h1:qdcuFWeGGS2xX5bLM/c3U9lewg7+Zu4mr+xPwZIB4ZU= +github.com/go-toolsmith/astcopy v1.1.0 h1:YGwBN0WM+ekI/6SS6+52zLDEf8Yvp3n2seZITCUBt5s= +github.com/go-toolsmith/astcopy v1.1.0/go.mod h1:hXM6gan18VA1T/daUEHCFcYiW8Ai1tIwIzHY6srfEAw= +github.com/go-toolsmith/astequal v1.0.3/go.mod h1:9Ai4UglvtR+4up+bAD4+hCj7iTo4m/OXVTSLnCyTAx4= +github.com/go-toolsmith/astequal v1.1.0/go.mod h1:sedf7VIdCL22LD8qIvv7Nn9MuWJruQA/ysswh64lffQ= +github.com/go-toolsmith/astequal v1.2.0 h1:3Fs3CYZ1k9Vo4FzFhwwewC3CHISHDnVUPC4x0bI2+Cw= +github.com/go-toolsmith/astequal v1.2.0/go.mod h1:c8NZ3+kSFtFY/8lPso4v8LuJjdJiUFVnSuU3s0qrrDY= +github.com/go-toolsmith/astfmt v1.1.0 h1:iJVPDPp6/7AaeLJEruMsBUlOYCmvg0MoCfJprsOmcco= +github.com/go-toolsmith/astfmt v1.1.0/go.mod h1:OrcLlRwu0CuiIBp/8b5PYF9ktGVZUjlNMV634mhwuQ4= +github.com/go-toolsmith/astp v1.1.0 h1:dXPuCl6u2llURjdPLLDxJeZInAeZ0/eZwFJmqZMnpQA= +github.com/go-toolsmith/astp v1.1.0/go.mod h1:0T1xFGz9hicKs8Z5MfAqSUitoUYS30pDMsRVIDHs8CA= +github.com/go-toolsmith/pkgload v1.2.2 h1:0CtmHq/02QhxcF7E9N5LIFcYFsMR5rdovfqTtRKkgIk= +github.com/go-toolsmith/pkgload v1.2.2/go.mod h1:R2hxLNRKuAsiXCo2i5J6ZQPhnPMOVtU+f0arbFPWCus= +github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= +github.com/go-toolsmith/strparse v1.1.0 h1:GAioeZUK9TGxnLS+qfdqNbA4z0SSm5zVNtCQiyP2Bvw= +github.com/go-toolsmith/strparse v1.1.0/go.mod h1:7ksGy58fsaQkGQlY8WVoBFNyEPMGuJin1rfoPS4lBSQ= +github.com/go-toolsmith/typep v1.1.0 h1:fIRYDyF+JywLfqzyhdiHzRop/GQDxxNhLGQ6gFUNHus= +github.com/go-toolsmith/typep v1.1.0/go.mod h1:fVIw+7zjdsMxDA3ITWnH1yOiw1rnTQKCsF/sk2H/qig= +github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1 h1:TQcrn6Wq+sKGkpyPvppOz99zsMBaUOKXq6HSv655U1c= +github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-xmlfmt/xmlfmt v1.1.2 h1:Nea7b4icn8s57fTx1M5AI4qQT5HEM3rVUO8MuE6g80U= +github.com/go-xmlfmt/xmlfmt v1.1.2/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= +github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= +github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= +github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= 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.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9uMCefW1WDie15eSP/4MssdenaM= +github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= +github.com/golangci/gofmt v0.0.0-20231018234816-f50ced29576e h1:ULcKCDV1LOZPFxGZaA6TlQbiM3J2GCPnkx/bGF6sX/g= +github.com/golangci/gofmt v0.0.0-20231018234816-f50ced29576e/go.mod h1:Pm5KhLPA8gSnQwrQ6ukebRcapGb/BG9iUkdaiCcGHJM= +github.com/golangci/golangci-lint v1.59.0 h1:st69YDnAH/v2QXDcgUaZ0seQajHScPALBVkyitYLXEk= +github.com/golangci/golangci-lint v1.59.0/go.mod h1:QNA32UWdUdHXnu+Ap5/ZU4WVwyp2tL94UxEXrSErjg0= +github.com/golangci/misspell v0.5.1 h1:/SjR1clj5uDjNLwYzCahHwIOPmQgoH04AyQIiWGbhCM= +github.com/golangci/misspell v0.5.1/go.mod h1:keMNyY6R9isGaSAu+4Q8NMBwMPkh15Gtc8UCVoDtAWo= +github.com/golangci/modinfo v0.3.4 h1:oU5huX3fbxqQXdfspamej74DFX0kyGLkw1ppvXoJ8GA= +github.com/golangci/modinfo v0.3.4/go.mod h1:wytF1M5xl9u0ij8YSvhkEVPP3M5Mc7XLl1pxH3B2aUM= +github.com/golangci/plugin-module-register v0.1.1 h1:TCmesur25LnyJkpsVrupv1Cdzo+2f7zX0H6Jkw1Ol6c= +github.com/golangci/plugin-module-register v0.1.1/go.mod h1:TTpqoB6KkwOJMV8u7+NyXMrkwwESJLOkfl9TxR1DGFc= +github.com/golangci/revgrep v0.5.3 h1:3tL7c1XBMtWHHqVpS5ChmiAAoe4PF/d5+ULzV9sLAzs= +github.com/golangci/revgrep v0.5.3/go.mod h1:U4R/s9dlXZsg8uJmaR1GrloUr14D7qDl8gi2iPXJH8k= +github.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed h1:IURFTjxeTfNFP0hTEi1YKjB/ub8zkpaOqFFMApi2EAs= +github.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed/go.mod h1:XLXN8bNw4CGRPaqgl3bv/lhz7bsGPh4/xSaMTbo2vkQ= github.com/google/addlicense v1.1.1 h1:jpVf9qPbU8rz5MxKo7d+RMcNHkqxi4YJi/laauX4aAE= github.com/google/addlicense v1.1.1/go.mod h1:Sm/DHu7Jk+T5miFHHehdIjbi4M5+dJDRS3Cq0rncIxA= 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.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 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-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= 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/gordonklaus/ineffassign v0.1.0 h1:y2Gd/9I7MdY1oEIt+n+rowjBNDcLQq3RsH5hwJd0f9s= +github.com/gordonklaus/ineffassign v0.1.0/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gostaticanalysis/analysisutil v0.7.1 h1:ZMCjoue3DtDWQ5WyU16YbjbQEQ3VuzwxALrpYd+HeKk= +github.com/gostaticanalysis/analysisutil v0.7.1/go.mod h1:v21E3hY37WKMGSnbsw2S/ojApNWb6C1//mXO48CXbVc= +github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado= +github.com/gostaticanalysis/comment v1.4.2 h1:hlnx5+S2fY9Zo9ePo4AhgYsYHbM2+eAv8m/s1JiCd6Q= +github.com/gostaticanalysis/comment v1.4.2/go.mod h1:KLUTGDv6HOCotCH8h2erHKmpci2ZoR8VPu34YA2uzdM= +github.com/gostaticanalysis/forcetypeassert v0.1.0 h1:6eUflI3DiGusXGK6X7cCcIgVCpZ2CiZ1Q7jl6ZxNV70= +github.com/gostaticanalysis/forcetypeassert v0.1.0/go.mod h1:qZEedyP/sY1lTGV1uJ3VhWZ2mqag3IkWsDHVbplHXak= +github.com/gostaticanalysis/nilerr v0.1.1 h1:ThE+hJP0fEp4zWLkWHWcRyI2Od0p7DlgYG3Uqrmrcpk= +github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW0HU0GPE3+5PWN4A= +github.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4/go.mod h1:D+FIZ+7OahH3ePw/izIEeH5I06eKs1IKI4Xr64/Am3M= +github.com/gostaticanalysis/testutil v0.4.0 h1:nhdCmubdmDF6VEatUNjgUZBJKWRqugoISdUv3PPQgHY= +github.com/gostaticanalysis/testutil v0.4.0/go.mod h1:bLIoPefWXrRi/ssLFWX1dx7Repi5x3CuviD3dgAZaBU= +github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= +github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= +github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= 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/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/ironcore-dev/ironcore v0.1.2-0.20240305221731-20d84f49d48d h1:EO40sEkv3ZBGKWjRMUr46Jy3Fn8i4stp+CnG4uf5pR4= -github.com/ironcore-dev/ironcore v0.1.2-0.20240305221731-20d84f49d48d/go.mod h1:mYLxdENCUfGiAKqo8rlc+o0Uwi/kQYZjOTrJNe4f5k4= -github.com/ironcore-dev/metal v0.11.2 h1:1FGbc3XASJDokUNSr3tMBwcro+IPX4Y66rL7CsbxgBQ= -github.com/ironcore-dev/metal v0.11.2/go.mod h1:CYbi/cR6M+GjBhJfgU5oMKBUpa11Y3NL45K4HDVrL5Y= +github.com/ironcore-dev/ironcore v0.1.2 h1:zYxKEZ+xXeQ7KVBPgYj+W3D4mlR6sCVJaFKUzfuR204= +github.com/ironcore-dev/ironcore v0.1.2/go.mod h1:ircFIizjXLGUU2r5utcYe/feMnwMZVJuyFZGAWmsmLQ= +github.com/ironcore-dev/metal v0.0.0-20240604143639-2360012c7845 h1:LnFO7bDmLrqxK7TvJ6flXijwddj/G8QB34mShfAShHo= +github.com/ironcore-dev/metal v0.0.0-20240604143639-2360012c7845/go.mod h1:SiXTSeentoJ4RFk7Pbnw5595DWXQInDDNtELxvnNBqw= +github.com/jgautheron/goconst v1.7.1 h1:VpdAG7Ca7yvvJk5n8dMwQhfEZJh95kl/Hl9S1OI5Jkk= +github.com/jgautheron/goconst v1.7.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= +github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjzq7gFzUs= +github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c= +github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af h1:KA9BjwUk7KlCh6S9EAGWBt1oExIUv9WyNCiRz5amv48= +github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= +github.com/jjti/go-spancheck v0.6.1 h1:ZK/wE5Kyi1VX3PJpUO2oEgeoI4FWOUm7Shb2Gbv5obI= +github.com/jjti/go-spancheck v0.6.1/go.mod h1:vF1QkOO159prdo6mHRxak2CpzDpHAfKiPUDP/NeRnX8= 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/julz/importas v0.1.0 h1:F78HnrsjY3cR7j0etXy5+TU1Zuy7Xt08X/1aJnH5xXY= +github.com/julz/importas v0.1.0/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSXO0DV0= +github.com/karamaru-alpha/copyloopvar v1.1.0 h1:x7gNyKcC2vRBO1H2Mks5u1VxQtYvFiym7fCjIP8RPos= +github.com/karamaru-alpha/copyloopvar v1.1.0/go.mod h1:u7CIfztblY0jZLOQZgH3oYsJzpC2A7S6u/lfgSXHy0k= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/errcheck v1.7.0 h1:+SbscKmWJ5mOK/bO1zS60F5I9WwZDWOfRsC4RwfwRV0= +github.com/kisielk/errcheck v1.7.0/go.mod h1:1kLL+jV4e+CFfueBmI1dSK2ADDyQnlrnrY/FqKluHJQ= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkHAIKE/contextcheck v1.1.5 h1:CdnJh63tcDe53vG+RebdpdXJTc9atMgGqdx8LXxiilg= +github.com/kkHAIKE/contextcheck v1.1.5/go.mod h1:O930cpht4xb1YQpK+1+AgoM3mFsvxr7uyFptcnWTYUA= 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/kulti/thelper v0.6.3 h1:ElhKf+AlItIu+xGnI990no4cE2+XaSu1ULymV2Yulxs= +github.com/kulti/thelper v0.6.3/go.mod h1:DsqKShOvP40epevkFrvIwkCMNYxMeTNjdWL4dqWHZ6I= +github.com/kunwardeep/paralleltest v1.0.10 h1:wrodoaKYzS2mdNVnc4/w31YaXFtsc21PCTdvWJ/lDDs= +github.com/kunwardeep/paralleltest v1.0.10/go.mod h1:2C7s65hONVqY7Q5Efj5aLzRCNLjw2h4eMc9EcypGjcY= +github.com/kyoh86/exportloopref v0.1.11 h1:1Z0bcmTypkL3Q4k+IDHMWTcnCliEZcaPiIe0/ymEyhQ= +github.com/kyoh86/exportloopref v0.1.11/go.mod h1:qkV4UF1zGl6EkF1ox8L5t9SwyeBAZ3qLMd6up458uqA= +github.com/lasiar/canonicalheader v1.1.1 h1:wC+dY9ZfiqiPwAexUApFush/csSPXeIi4QqyxXmng8I= +github.com/lasiar/canonicalheader v1.1.1/go.mod h1:cXkb3Dlk6XXy+8MVQnF23CYKWlyA7kfQhSw2CcZtZb0= +github.com/ldez/gomoddirectives v0.2.4 h1:j3YjBIjEBbqZ0NKtBNzr8rtMHTOrLPeiwTkfUJZ3alg= +github.com/ldez/gomoddirectives v0.2.4/go.mod h1:oWu9i62VcQDYp9EQ0ONTfqLNh+mDLWWDO+SO0qSQw5g= +github.com/ldez/tagliatelle v0.5.0 h1:epgfuYt9v0CG3fms0pEgIMNPuFf/LpPIfjk4kyqSioo= +github.com/ldez/tagliatelle v0.5.0/go.mod h1:rj1HmWiL1MiKQuOONhd09iySTEkUuE/8+5jtPYz9xa4= +github.com/leonklingele/grouper v1.1.2 h1:o1ARBDLOmmasUaNDesWqWCIFH3u7hoFlM84YrjT3mIY= +github.com/leonklingele/grouper v1.1.2/go.mod h1:6D0M/HVkhs2yRKRFZUoGjeDy7EZTfFBE9gl4kjmIGkA= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= +github.com/lufeee/execinquery v1.2.1 h1:hf0Ems4SHcUGBxpGN7Jz78z1ppVkP/837ZlETPCEtOM= +github.com/lufeee/execinquery v1.2.1/go.mod h1:EC7DrEKView09ocscGHC+apXMIaorh4xqSxS/dy8SbM= +github.com/macabu/inamedparam v0.1.3 h1:2tk/phHkMlEL/1GNe/Yf6kkR/hkcUdAEY3L0hjYV1Mk= +github.com/macabu/inamedparam v0.1.3/go.mod h1:93FLICAIk/quk7eaPPQvbzihUdn/QkGDwIZEoLtpH6I= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/maratori/testableexamples v1.0.0 h1:dU5alXRrD8WKSjOUnmJZuzdxWOEQ57+7s93SLMxb2vI= +github.com/maratori/testableexamples v1.0.0/go.mod h1:4rhjL1n20TUTT4vdh3RDqSizKLyXp7K2u6HgraZCGzE= +github.com/maratori/testpackage v1.1.1 h1:S58XVV5AD7HADMmD0fNnziNHqKvSdDuEKdPD1rNTU04= +github.com/maratori/testpackage v1.1.1/go.mod h1:s4gRK/ym6AMrqpOa/kEbQTV4Q4jb7WeLZzVhVVVOQMc= +github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26 h1:gWg6ZQ4JhDfJPqlo2srm/LN17lpybq15AryXIRcWYLE= +github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= +github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= +github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mgechev/revive v1.3.7 h1:502QY0vQGe9KtYJ9FpxMz9rL+Fc/P13CI5POL4uHCcE= +github.com/mgechev/revive v1.3.7/go.mod h1:RJ16jUbF0OWC3co/+XTxmFNgEpUPwnnA0BRllX2aDNA= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= @@ -120,43 +310,102 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w 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/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0= -github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= +github.com/moricho/tparallel v0.3.1 h1:fQKD4U1wRMAYNngDonW5XupoB/ZGJHdpzrWqgyg9krA= +github.com/moricho/tparallel v0.3.1/go.mod h1:leENX2cUv7Sv2qDgdi0D0fCftN8fRC67Bcn8pqzeYNI= 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/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/onsi/ginkgo/v2 v2.16.0 h1:7q1w9frJDzninhXxjZd+Y/x54XNjG/UlRLIYPZafsPM= -github.com/onsi/ginkgo/v2 v2.16.0/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs= -github.com/onsi/gomega v1.31.1 h1:KYppCUK+bUgAZwHOu7EXVBKyQA6ILvOESHkn/tgoqvo= -github.com/onsi/gomega v1.31.1/go.mod h1:y40C95dwAD1Nz36SsEnxvfFe8FFfNxzI5eJ0EYGyAy0= -github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI= -github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/nakabonne/nestif v0.3.1 h1:wm28nZjhQY5HyYPx+weN3Q65k6ilSBxDb8v5S81B81U= +github.com/nakabonne/nestif v0.3.1/go.mod h1:9EtoZochLn5iUprVDmDjqGKPofoUEBL8U4Ngq6aY7OE= +github.com/nishanths/exhaustive v0.12.0 h1:vIY9sALmw6T/yxiASewa4TQcFsVYZQQRUQJhKRf3Swg= +github.com/nishanths/exhaustive v0.12.0/go.mod h1:mEZ95wPIZW+x8kC4TgC+9YCUgiST7ecevsVDTgc2obs= +github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk= +github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c= +github.com/nunnatsa/ginkgolinter v0.16.2 h1:8iLqHIZvN4fTLDC0Ke9tbSZVcyVHoBs0HIbnVSxfHJk= +github.com/nunnatsa/ginkgolinter v0.16.2/go.mod h1:4tWRinDN1FeJgU+iJANW/kz7xKN5nYRAOfJDQUS9dOQ= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +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/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw= +github.com/otiai10/copy v1.14.0 h1:dCI/t1iTdYGtkvCuBG2BgR6KZa83PTclw4U5n2wAllU= +github.com/otiai10/copy v1.14.0/go.mod h1:ECfuL02W+/FkTWZWgQqXPWZgW9oeKCSQ5qVfSc4qc4w= +github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= +github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= +github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= +github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= +github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= +github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= 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.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= -github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= -github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= -github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= -github.com/prometheus/common v0.46.0 h1:doXzt5ybi1HBKpsZOL0sSkaNHJJqkyfEWZGGqqScV0Y= -github.com/prometheus/common v0.46.0/go.mod h1:Tp0qkxpb9Jsg54QMe+EAmqXkSV7Evdy1BTn+g2pa/hQ= -github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= -github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/polyfloyd/go-errorlint v1.5.1 h1:5gHxDjLyyWij7fhfrjYNNlHsUNQeyx0LFQKUelO3RBo= +github.com/polyfloyd/go-errorlint v1.5.1/go.mod h1:sH1QC1pxxi0fFecsVIzBmxtrgd9IF/SkJpA6wqyKAJs= +github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= +github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= +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.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+aLCE= +github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U= +github.com/prometheus/procfs v0.15.0 h1:A82kmvXJq2jTu5YUhSGNlYoxh85zLnKgPz4bMZgI5Ek= +github.com/prometheus/procfs v0.15.0/go.mod h1:Y0RJ/Y5g5wJpkTisOtqwDSo4HwhGmLB4VQSw2sQJLHk= +github.com/quasilyte/go-ruleguard v0.4.2 h1:htXcXDK6/rO12kiTHKfHuqR4kr3Y4M0J0rOL6CH/BYs= +github.com/quasilyte/go-ruleguard v0.4.2/go.mod h1:GJLgqsLeo4qgavUoL8JeGFNS7qcisx3awV/w9eWTmNI= +github.com/quasilyte/go-ruleguard/dsl v0.3.22 h1:wd8zkOhSNr+I+8Qeciml08ivDt1pSXe60+5DqOpCjPE= +github.com/quasilyte/go-ruleguard/dsl v0.3.22/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= +github.com/quasilyte/gogrep v0.5.0 h1:eTKODPXbI8ffJMN+W2aE0+oL0z/nh8/5eNdiO34SOAo= +github.com/quasilyte/gogrep v0.5.0/go.mod h1:Cm9lpz9NZjEoL1tgZ2OgeUKPIxL1meE7eo60Z6Sk+Ng= +github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 h1:TCg2WBOl980XxGFEZSS6KlBGIV0diGdySzxATTWoqaU= +github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= +github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4lu7Gd+PU1fV2/qnDNfzT635KRSObncs= +github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ= +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/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= -github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= +github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryancurrah/gomodguard v1.3.2 h1:CuG27ulzEB1Gu5Dk5gP8PFxSOZ3ptSdP5iI/3IXxM18= +github.com/ryancurrah/gomodguard v1.3.2/go.mod h1:LqdemiFomEjcxOqirbQCb3JFvSxH2JUYMerTFd3sF2o= +github.com/ryanrolds/sqlclosecheck v0.5.1 h1:dibWW826u0P8jNLsLN+En7+RqWWTYrjCB9fJfSfdyCU= +github.com/ryanrolds/sqlclosecheck v0.5.1/go.mod h1:2g3dUjoS6AL4huFdv6wn55WpLIDjY7ZgUR4J8HOO/XQ= github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= +github.com/sanposhiho/wastedassign/v2 v2.0.7 h1:J+6nrY4VW+gC9xFzUc+XjPD3g3wF3je/NsJFwFK7Uxc= +github.com/sanposhiho/wastedassign/v2 v2.0.7/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI= +github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4= +github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= +github.com/sashamelentyev/interfacebloat v1.1.0 h1:xdRdJp0irL086OyW1H/RTZTr1h/tMEOsumirXcOJqAw= +github.com/sashamelentyev/interfacebloat v1.1.0/go.mod h1:+Y9yU5YdTkrNvoX0xHc84dxiN1iBi9+G8zZIhPVoNjQ= +github.com/sashamelentyev/usestdlibvars v1.25.0 h1:IK8SI2QyFzy/2OD2PYnhy84dpfNo9qADrRt6LH8vSzU= +github.com/sashamelentyev/usestdlibvars v1.25.0/go.mod h1:9nl0jgOfHKWNFS43Ojw0i7aRoS4j6EBye3YBhmAIRF8= +github.com/securego/gosec/v2 v2.20.1-0.20240525090044-5f0084eb01a9 h1:rnO6Zp1YMQwv8AyxzuwsVohljJgp4L0ZqiCgtACsPsc= +github.com/securego/gosec/v2 v2.20.1-0.20240525090044-5f0084eb01a9/go.mod h1:dg7lPlu/xK/Ut9SedURCoZbVCR4yC7fM65DtH9/CDHs= +github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU= +github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= +github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= +github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sivchari/containedctx v1.0.3 h1:x+etemjbsh2fB5ewm5FeLNi5bUjK0V8n0RB+Wwfd0XE= +github.com/sivchari/containedctx v1.0.3/go.mod h1:c1RDvCbnJLtH4lLcYD/GqwiBSSf4F5Qk0xld2rBqzJ4= +github.com/sivchari/tenv v1.7.1 h1:PSpuD4bu6fSmtWMxSGWcvqUUgIn7k3yOJhOIzVWn8Ak= +github.com/sivchari/tenv v1.7.1/go.mod h1:64yStXKSOxDfX47NlhVwND4dHwfZDdbp2Lyl018Icvg= +github.com/sonatard/noctx v0.0.2 h1:L7Dz4De2zDQhW8S0t+KUjY0MAQJd6SgVwhzNIc4ok00= +github.com/sonatard/noctx v0.0.2/go.mod h1:kzFz+CzWSjQ2OzIm46uJZoXuBpa2+0y3T36U18dWqIo= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= +github.com/sourcegraph/go-diff v0.7.0 h1:9uLlrd5T46OXs5qpp8L/MTltk0zikUGi0sNNyCpA8G0= +github.com/sourcegraph/go-diff v0.7.0/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= @@ -165,151 +414,261 @@ github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= 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/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= -github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= +github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= +github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= +github.com/ssgreg/nlreturn/v2 v2.2.1 h1:X4XDI7jstt3ySqGU86YGAURbxw3oTDPK9sPEi6YEwQ0= +github.com/ssgreg/nlreturn/v2 v2.2.1/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I= +github.com/stbenjam/no-sprintf-host-port v0.1.1 h1:tYugd/yrm1O0dV+ThCbaKZh195Dfm07ysF0U6JQXczc= +github.com/stbenjam/no-sprintf-host-port v0.1.1/go.mod h1:TLhvtIvONRzdmkFiio4O8LHsN9N74I+PhRquPsxpL0I= 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/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.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 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.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= -github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= +github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c h1:+aPplBwWcHBo6q9xrfWdMrT9o4kltkmmvpemgIjep/8= +github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c/go.mod h1:SbErYREK7xXdsRiigaQiQkI9McGRzYMvlKYaP3Nimdk= +github.com/tdakkota/asciicheck v0.2.0 h1:o8jvnUANo0qXtnslk2d3nMKTFNlOnJjRrNcj0j9qkHM= +github.com/tdakkota/asciicheck v0.2.0/go.mod h1:Qb7Y9EgjCLJGup51gDHFzbI08/gbGhL/UVhYIPWG2rg= +github.com/tenntenn/modver v1.0.1 h1:2klLppGhDgzJrScMpkj9Ujy3rXPUspSjAcev9tSEBgA= +github.com/tenntenn/modver v1.0.1/go.mod h1:bePIyQPb7UeioSRkw3Q0XeMhYZSMx9B8ePqg6SAMGH0= +github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3 h1:f+jULpRQGxTSkNYKJ51yaw6ChIqO+Je8UqsTKN/cDag= +github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY= +github.com/tetafro/godot v1.4.16 h1:4ChfhveiNLk4NveAZ9Pu2AN8QZ2nkUGFuadM9lrr5D0= +github.com/tetafro/godot v1.4.16/go.mod h1:2oVxTBSftRTh4+MVfUaUXR6bn2GDXCaMcOG4Dk3rfio= +github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966 h1:quvGphlmUVU+nhpFa4gg4yJyTRJ13reZMDHrKwYw53M= +github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966/go.mod h1:27bSVNWSBOHm+qRp1T9qzaIpsWEP6TbUnei/43HK+PQ= +github.com/timonwong/loggercheck v0.9.4 h1:HKKhqrjcVj8sxL7K77beXh0adEm6DLjV/QOGeMXEVi4= +github.com/timonwong/loggercheck v0.9.4/go.mod h1:caz4zlPcgvpEkXgVnAJGowHAMW2NwHaNlpS8xDbVhTg= +github.com/tomarrell/wrapcheck/v2 v2.8.3 h1:5ov+Cbhlgi7s/a42BprYoxsr73CbdMUTzE3bRDFASUs= +github.com/tomarrell/wrapcheck/v2 v2.8.3/go.mod h1:g9vNIyhb5/9TQgumxQyOEqDHsmGYcGsVMOx/xGkqdMo= +github.com/tommy-muehle/go-mnd/v2 v2.5.1 h1:NowYhSdyE/1zwK9QCLeRb6USWdoif80Ie+v+yU8u1Zw= +github.com/tommy-muehle/go-mnd/v2 v2.5.1/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw= +github.com/ultraware/funlen v0.1.0 h1:BuqclbkY6pO+cvxoq7OsktIXZpgBSkYTQtmwhAK81vI= +github.com/ultraware/funlen v0.1.0/go.mod h1:XJqmOQja6DpxarLj6Jj1U7JuoS8PvL4nEqDaQhy22p4= +github.com/ultraware/whitespace v0.1.1 h1:bTPOGejYFulW3PkcrqkeQwOd6NKOOXvmGD9bo/Gk8VQ= +github.com/ultraware/whitespace v0.1.1/go.mod h1:XcP1RLD81eV4BW8UhQlpaR+SDc2givTvyI8a586WjW8= +github.com/uudashr/gocognit v1.1.2 h1:l6BAEKJqQH2UpKAPKdMfZf5kE4W/2xk8pfU1OVLvniI= +github.com/uudashr/gocognit v1.1.2/go.mod h1:aAVdLURqcanke8h3vg35BC++eseDm66Z7KmchI5et4k= +github.com/xen0n/gosmopolitan v1.2.2 h1:/p2KTnMzwRexIW8GlKawsTWOxn7UHA+jCMF/V8HHtvU= +github.com/xen0n/gosmopolitan v1.2.2/go.mod h1:7XX7Mj61uLYrj0qmeN0zi7XDon9JRAEhYQqAPLVNTeg= +github.com/yagipy/maintidx v1.0.0 h1:h5NvIsCz+nRDapQ0exNv4aJ0yXSI0420omVANTv3GJM= +github.com/yagipy/maintidx v1.0.0/go.mod h1:0qNf/I/CCZXSMhsRsrEPDZ+DkekpKLXAJfsTACwgXLk= +github.com/yeya24/promlinter v0.3.0 h1:JVDbMp08lVCP7Y6NP3qHroGAO6z2yGKQtS5JsjqtoFs= +github.com/yeya24/promlinter v0.3.0/go.mod h1:cDfJQQYv9uYciW60QT0eeHlFodotkYZlL+YcPQN+mW4= +github.com/ykadowak/zerologlint v0.1.5 h1:Gy/fMz1dFQN9JZTPjv1hxEk+sRWm05row04Yoolgdiw= +github.com/ykadowak/zerologlint v0.1.5/go.mod h1:KaUskqF3e/v59oPmdq1U1DnKcuHokl2/K1U4pmIELKg= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY= -go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= +gitlab.com/bosi/decorder v0.4.2 h1:qbQaV3zgwnBZ4zPMhGLW4KZe7A7NwxEhJx39R3shffo= +gitlab.com/bosi/decorder v0.4.2/go.mod h1:muuhHoaJkA9QLcYHq4Mj8FJUwDZ+EirSHRiaTcTf6T8= +go-simpler.org/assert v0.9.0 h1:PfpmcSvL7yAnWyChSjOz6Sp6m9j5lyK8Ok9pEL31YkQ= +go-simpler.org/assert v0.9.0/go.mod h1:74Eqh5eI6vCK6Y5l3PI8ZYFXG4Sa+tkr70OIPJAUr28= +go-simpler.org/musttag v0.12.2 h1:J7lRc2ysXOq7eM8rwaTYnNrHd5JwjppzB6mScysB2Cs= +go-simpler.org/musttag v0.12.2/go.mod h1:uN1DVIasMTQKk6XSik7yrJoEysGtR2GRqvWnI9S7TYM= +go-simpler.org/sloglint v0.7.0 h1:rMZRxD9MbaGoRFobIOicMxZzum7AXNFDlez6xxJs5V4= +go-simpler.org/sloglint v0.7.0/go.mod h1:g9SXiSWY0JJh4LS39/Q0GxzP/QX2cVcbTOYhDpXrJEs= +go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= +go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= 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= -go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M= -go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y= +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/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3 h1:/RIbNt/Zr7rVhIkQhooTxCxFcdWLGIKnZA4IXNFSrvo= -golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= +golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= +golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= +golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f h1:phY1HzDcf18Aq9A8KkmRtY9WvOFIxN8wgfvy6Zm1DV8= +golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= 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.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 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-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ= -golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= +golang.org/x/oauth2 v0.20.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-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.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-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211105183446-c75c47738b0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220702020025-31831981b65f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= 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/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190321232350-e250d351ecad/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200324003944-a576cf524670/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200329025819-fd4102a86c65/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200820010801-b793a1359eac/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1-0.20210205202024-ef80cdb6ec6d/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU= +golang.org/x/tools v0.1.1-0.20210302220138-2ac05c832e1a/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= -golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= +golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= +golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= +golang.org/x/tools v0.21.0/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/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= -google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240205150955-31a09d347014 h1:FSL3lRCkhaPFxqi0s9o+V4UI2WTzAVOvkgbd4kVV4Wg= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240205150955-31a09d347014/go.mod h1:SaPjaZGWb0lPqs6Ittu0spdfrOArqji4ZdeP5IC/9N4= -google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk= -google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 h1:NnYq6UN9ReLM9/Y01KWNOWyI5xQ9kbIms5GGJVwS/Yc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= +google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= 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.v5 v5.6.0 h1:BMT6KIwBD9CaU91PJCZIe46bDmBWa9ynTQgJIOpfQBk= -gopkg.in/evanphx/json-patch.v5 v5.6.0/go.mod h1:/kvTRh1TVm5wuM6OkHxqXtE/1nUZZpihg29RtuIyfvk= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +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.29.2 h1:hBC7B9+MU+ptchxEqTNW2DkUosJpp1P+Wn6YncZ474A= -k8s.io/api v0.29.2/go.mod h1:sdIaaKuU7P44aoyyLlikSLayT6Vb7bvJNCX105xZXY0= -k8s.io/apiextensions-apiserver v0.29.1 h1:S9xOtyk9M3Sk1tIpQMu9wXHm5O2MX6Y1kIpPMimZBZw= -k8s.io/apiextensions-apiserver v0.29.1/go.mod h1:zZECpujY5yTW58co8V2EQR4BD6A9pktVgHhvc0uLfeU= -k8s.io/apimachinery v0.29.2 h1:EWGpfJ856oj11C52NRCHuU7rFDwxev48z+6DSlGNsV8= -k8s.io/apimachinery v0.29.2/go.mod h1:6HVkd1FwxIagpYrHSwJlQqZI3G9LfYWRPAkUvLnXTKU= -k8s.io/cli-runtime v0.29.2 h1:smfsOcT4QujeghsNjECKN3lwyX9AwcFU0nvJ7sFN3ro= -k8s.io/cli-runtime v0.29.2/go.mod h1:KLisYYfoqeNfO+MkTWvpqIyb1wpJmmFJhioA0xd4MW8= -k8s.io/client-go v0.29.2 h1:FEg85el1TeZp+/vYJM7hkDlSTFZ+c5nnK44DJ4FyoRg= -k8s.io/client-go v0.29.2/go.mod h1:knlvFZE58VpqbQpJNbCbctTVXcd35mMyAAwBdpt4jrA= -k8s.io/component-base v0.29.2 h1:lpiLyuvPA9yV1aQwGLENYyK7n/8t6l3nn3zAtFTJYe8= -k8s.io/component-base v0.29.2/go.mod h1:BfB3SLrefbZXiBfbM+2H1dlat21Uewg/5qtKOl8degM= +honnef.co/go/tools v0.4.7 h1:9MDAWxMoSnB6QoSqiVr7P5mtkT9pOc1kSxchzPCnqJs= +honnef.co/go/tools v0.4.7/go.mod h1:+rnGS1THNh8zMwnd2oVOTL9QF6vmfyG6ZXBULae2uc0= +k8s.io/api v0.30.1 h1:kCm/6mADMdbAxmIh0LBjS54nQBE+U4KmbCfIkF5CpJY= +k8s.io/api v0.30.1/go.mod h1:ddbN2C0+0DIiPntan/bye3SW3PdwLa11/0yqwvuRrJM= +k8s.io/apiextensions-apiserver v0.30.1 h1:4fAJZ9985BmpJG6PkoxVRpXv9vmPUOVzl614xarePws= +k8s.io/apiextensions-apiserver v0.30.1/go.mod h1:R4GuSrlhgq43oRY9sF2IToFh7PVlF1JjfWdoG3pixk4= +k8s.io/apimachinery v0.30.1 h1:ZQStsEfo4n65yAdlGTfP/uSHMQSoYzU/oeEbkmF7P2U= +k8s.io/apimachinery v0.30.1/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc= +k8s.io/cli-runtime v0.29.4 h1:QvUrddBxVX6XFJ6z64cGpEk7e4bQduKweqbqq+qBd9g= +k8s.io/cli-runtime v0.29.4/go.mod h1:NmklYuZ4DLfOr2XEIT8Nzl883KMZUCv7KMj3wMHayCA= +k8s.io/client-go v0.30.1 h1:uC/Ir6A3R46wdkgCV3vbLyNOYyCJ8oZnjtJGKfytl/Q= +k8s.io/client-go v0.30.1/go.mod h1:wrAqLNs2trwiCH/wxxmT/x3hKVH9PuV0GGW0oDoHVqc= k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20240126223410-2919ad4fcfec h1:iGTel2aR8vCZdxJDgmbeY0zrlXy9Qcvyw4R2sB4HLrA= -k8s.io/kube-openapi v0.0.0-20240126223410-2919ad4fcfec/go.mod h1:Pa1PvrP7ACSkuX6I7KYomY6cmMA0Tx86waBhDUgoKPw= -k8s.io/kubectl v0.29.2 h1:uaDYaBhumvkwz0S2XHt36fK0v5IdNgL7HyUniwb2IUo= -k8s.io/kubectl v0.29.2/go.mod h1:BhizuYBGcKaHWyq+G7txGw2fXg576QbPrrnQdQDZgqI= -k8s.io/utils v0.0.0-20240102154912-e7106e64919e h1:eQ/4ljkx21sObifjzXwlPKpdGLrCfRziVtos3ofG/sQ= -k8s.io/utils v0.0.0-20240102154912-e7106e64919e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/controller-runtime v0.17.2 h1:FwHwD1CTUemg0pW2otk7/U5/i5m2ymzvOXdbeGOUvw0= -sigs.k8s.io/controller-runtime v0.17.2/go.mod h1:+MngTvIQQQhfXtwfdGw/UOQ/aIaqsYywfCINOtwMO/s= +k8s.io/kube-openapi v0.0.0-20240430033511-f0e62f92d13f h1:0LQagt0gDpKqvIkAMPaRGcXawNMouPECM1+F9BVxEaM= +k8s.io/kube-openapi v0.0.0-20240430033511-f0e62f92d13f/go.mod h1:S9tOR0FxgyusSNR+MboCuiDpVWkAifZvaYI1Q2ubgro= +k8s.io/kubectl v0.29.4 h1:2LFrAznoDZjN8JFMSUcuhER5o+yjTLzWWbOiDzVjmd8= +k8s.io/kubectl v0.29.4/go.mod h1:YTKRF9y1/ccqZ2bnpOWaJD8V7johKqZR/qOMq+0pfxU= +k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 h1:jgGTlFYnhF1PM1Ax/lAlxUPE+KfCIXHaathvJg1C3ak= +k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +mvdan.cc/gofumpt v0.6.0 h1:G3QvahNDmpD+Aek/bNOLrFR2XC6ZAdo62dZu65gmwGo= +mvdan.cc/gofumpt v0.6.0/go.mod h1:4L0wf+kgIPZtcCWXynNS2e6bhmj73umwnuXSZarixzA= +mvdan.cc/unparam v0.0.0-20240427195214-063aff900ca1 h1:Nykk7fggxChwLK4rUPYESzeIwqsuxXXlFEAh5YhaMRo= +mvdan.cc/unparam v0.0.0-20240427195214-063aff900ca1/go.mod h1:ZzZjEpJDOmx8TdVU6umamY3Xy0UAQUI2DHbf05USVbI= +sigs.k8s.io/controller-runtime v0.18.3 h1:B5Wmmo8WMWK7izei+2LlXLVDGzMwAHBNLX68lwtlSR4= +sigs.k8s.io/controller-runtime v0.18.3/go.mod h1:TVoGrfdpbA9VRFaRnKgk9P5/atA0pMwq+f+msb9M8Sg= 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/kustomize/api v0.16.0 h1:/zAR4FOQDCkgSDmVzV2uiFbuy9bhu3jEzthrHCuvm1g= -sigs.k8s.io/kustomize/api v0.16.0/go.mod h1:MnFZ7IP2YqVyVwMWoRxPtgl/5hpA+eCCrQR/866cm5c= -sigs.k8s.io/kustomize/kyaml v0.16.0 h1:6J33uKSoATlKZH16unr2XOhDI+otoe2sR3M8PDzW3K0= -sigs.k8s.io/kustomize/kyaml v0.16.0/go.mod h1:xOK/7i+vmE14N2FdFyugIshB8eF6ALpy7jI87Q2nRh4= 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= diff --git a/internal/namespace/namespace.go b/internal/namespace/namespace.go new file mode 100644 index 0000000..f812501 --- /dev/null +++ b/internal/namespace/namespace.go @@ -0,0 +1,16 @@ +// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and IronCore contributors +// SPDX-License-Identifier: Apache-2.0 + +package namespace + +import ( + "os" +) + +func InClusterNamespace() string { + ns, err := os.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace") + if err != nil { + return "" + } + return string(ns) +} diff --git a/internal/patch/patch.go b/internal/patch/patch.go deleted file mode 100644 index 32f0e3c..0000000 --- a/internal/patch/patch.go +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and IronCore contributors -// SPDX-License-Identifier: Apache-2.0 - -package patch - -import ( - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/json" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -func ApplyConfiguration(applyConf interface{}) client.Patch { - return applyConfPatch{ - applyConf: applyConf, - } -} - -type applyConfPatch struct { - applyConf interface{} -} - -func (p applyConfPatch) Type() types.PatchType { - return types.ApplyPatchType -} - -func (p applyConfPatch) Data(_ client.Object) ([]byte, error) { - return json.Marshal(p.applyConf) -} diff --git a/internal/server/metal_provider_server.go b/internal/server/metal_provider_server.go new file mode 100644 index 0000000..98b88ee --- /dev/null +++ b/internal/server/metal_provider_server.go @@ -0,0 +1,655 @@ +// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and IronCore contributors +// SPDX-License-Identifier: Apache-2.0 + +package server + +import ( + "context" + "fmt" + "strings" + + "github.com/go-logr/logr" + "github.com/google/uuid" + computev1alpha1 "github.com/ironcore-dev/ironcore/api/compute/v1alpha1" + irimachinev1alpha1 "github.com/ironcore-dev/ironcore/iri/apis/machine/v1alpha1" + irimetav1alpha1 "github.com/ironcore-dev/ironcore/iri/apis/meta/v1alpha1" + metalv1alpha1 "github.com/ironcore-dev/metal/api/v1alpha1" + metalv1alpha1apply "github.com/ironcore-dev/metal/client/applyconfiguration/api/v1alpha1" + "golang.org/x/sync/errgroup" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1apply "k8s.io/client-go/applyconfigurations/core/v1" + metav1apply "k8s.io/client-go/applyconfigurations/meta/v1" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + + "github.com/ironcore-dev/metal-provider/internal/log" + "github.com/ironcore-dev/metal-provider/internal/ssa" + "github.com/ironcore-dev/metal-provider/internal/unix" +) + +const ( + MetalProviderFieldManager = "metal.ironcore.dev/provider" + MetalProviderIRIPrefix = "iri-" + MetalProviderSizePrefix = "metal.ironcore.dev/size-" +) + +func NewMetalProviderServer(addr string, namespace string) (*MetalProviderServer, error) { + return &MetalProviderServer{ + addr: addr, + namespace: namespace, + }, nil +} + +type MetalProviderServer struct { + client.Client + addr string + namespace string +} + +// SetupWithManager sets up the server with the Manager. +func (s *MetalProviderServer) SetupWithManager(mgr ctrl.Manager) error { + s.Client = mgr.GetClient() + + return mgr.Add(s) +} + +func (s *MetalProviderServer) Start(ctx context.Context) error { + ctx = log.WithValues(ctx, "server", "MetalProvider") + log.Info(ctx, "Starting server") + + ln, err := unix.Listen(ctx, s.addr) + if err != nil { + return fmt.Errorf("could not listen to socket %s: %w", s.addr, err) + } + + srv := grpc.NewServer(grpc.UnaryInterceptor(s.unaryInterceptor(logr.FromContextOrDiscard(ctx)))) + irimachinev1alpha1.RegisterMachineRuntimeServer(srv, s) + + var g *errgroup.Group + g, ctx = errgroup.WithContext(ctx) + g.Go(func() error { + log.Info(ctx, "Listening", "bindAddr", s.addr) + return srv.Serve(ln) + }) + g.Go(func() error { + <-ctx.Done() + log.Info(ctx, "Stopping server") + srv.GracefulStop() + log.Info(ctx, "Server finished") + return nil + }) + return g.Wait() +} + +func (s *MetalProviderServer) unaryInterceptor(logger logr.Logger) grpc.UnaryServerInterceptor { + return func(ctx context.Context, req any, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) { + return handler(logr.NewContext(ctx, logger), req) + } +} + +func (s *MetalProviderServer) Version(ctx context.Context, _ *irimachinev1alpha1.VersionRequest) (*irimachinev1alpha1.VersionResponse, error) { + ctx = log.WithValues(ctx, "request", "ListMachines") + log.Debug(ctx, "Serving") + + return &irimachinev1alpha1.VersionResponse{ + RuntimeName: "metal-provider", + RuntimeVersion: "0.0.0", + }, nil +} + +func (s *MetalProviderServer) ListMachines(ctx context.Context, req *irimachinev1alpha1.ListMachinesRequest) (*irimachinev1alpha1.ListMachinesResponse, error) { + ctx = log.WithValues(ctx, "request", "ListMachines") + log.Debug(ctx, "Serving") + + err := status.Errorf(codes.Unimplemented, "DeleteMachine() has not been implemented yet") + log.Error(ctx, err) + return nil, err + + // + // filter := req.GetFilter() + // id := filter.GetId() + // selector := filter.GetLabelSelector() + // if id != "" && selector != nil { + // err := status.Errorf(codes.InvalidArgument, "machine id and label selectors cannot both be set") + // log.Error(ctx, err) + // return nil, err + // } + // + // var machines []metalv1alpha4.Machine + // if id == "" { + // pselector, _ := overlayOntoPrefixed(IriLabelPrefix, selector, map[string]string{}) + // log.Debug(ctx, "Listing machines", "selector", selector) + // var machineList metalv1alpha4.MachineList + // err := s.List(ctx, &machineList, client.InNamespace(s.namespace), client.MatchingLabels(pselector)) + // if err != nil { + // return nil, internalError(ctx, fmt.Errorf("could not list machines: %w", err)) + // } + // + // for _, m := range machineList.Items { + // if m.Status.Reservation.Status == "Reserved" { + // machines = append(machines, m) + // } + // } + // } else { + // ctx = log.WithValues(ctx, "machine", id) + // + // log.Debug(ctx, "Getting machine") + // var machine metalv1alpha4.Machine + // err := s.Get(ctx, client.ObjectKey{Namespace: s.namespace, Name: id}, &machine) + // if err != nil { + // if kerrors.IsNotFound(err) { + // err = status.Errorf(codes.NotFound, "machine does not exist") + // log.Error(ctx, err) + // return nil, err + // } + // return nil, internalError(ctx, fmt.Errorf("cannot get machine: %w", err)) + // } + // + // if machine.Status.Reservation.Status != "Reserved" { + // err = status.Errorf(codes.NotFound, "machine is not reserved") + // log.Error(ctx, err) + // return nil, err + // } + // + // machines = append(machines, machine) + // } + // + // resMachines := make([]*irimachinev1alpha1.Machine, 0, len(machines)) + // for _, m := range machines { + // var bootMap v1.ConfigMap + // err := s.Get(ctx, client.ObjectKey{Namespace: m.Namespace, Name: fmt.Sprintf("ipxe-%s", m.Name)}, &bootMap) + // if err != nil { + // _ = internalError(ctx, fmt.Errorf("reserved machine has no boot configmap: %w", err)) + // continue + // } + // image, ok := bootMap.Data["image"] + // if !ok { + // _ = internalError(ctx, fmt.Errorf("reserved machine has no image in boot configmap")) + // continue + // } + // var ignition []byte + // ignition, ok = bootMap.BinaryData["ignition-custom"] + // if !ok { + // _ = internalError(ctx, fmt.Errorf("reserved machine has no ignition-custom in boot configmap")) + // continue + // } + // + // resMachines = append(resMachines, &irimachinev1alpha1.Machine{ + // Metadata: kMetaToMeta(&m.ObjectMeta), + // Spec: &irimachinev1alpha1.MachineSpec{ + // // TODO: Power + // Image: &irimachinev1alpha1.ImageSpec{ + // Image: image, + // }, + // Class: m.Status.Reservation.Class, + // IgnitionData: ignition, + // // TODO: Volumes + // // TODO: Network + // }, + // Status: &irimachinev1alpha1.MachineStatus{ + // // TODO: ObservedGeneration + // State: irimachinev1alpha1.MachineState_MACHINE_PENDING, + // ImageRef: image, + // // TODO: Volumes + // // TODO: Network + // }, + // }) + // } + // + //return &irimachinev1alpha1.ListMachinesResponse{ + // // Machines: resMachines, + //}, nil +} + +func (s *MetalProviderServer) CreateMachine(ctx context.Context, req *irimachinev1alpha1.CreateMachineRequest) (*irimachinev1alpha1.CreateMachineResponse, error) { + ctx = log.WithValues(ctx, "request", "CreateMachine") + log.Debug(ctx, "Serving") + + reqMachine := req.GetMachine() + reqMetadata := reqMachine.GetMetadata() + if reqMetadata.GetId() != "" { + err := status.Errorf(codes.InvalidArgument, "machine id must be empty") + log.Error(ctx, err) + return nil, err + } + if reqMetadata.GetGeneration() != 0 || reqMetadata.GetCreatedAt() != 0 || reqMetadata.GetDeletedAt() != 0 { + err := status.Errorf(codes.InvalidArgument, "machine generation, created_at, and deleted_at must all be empty") + log.Error(ctx, err) + return nil, err + } + + reqSpec := reqMachine.GetSpec() + power, err := iriPowerToPower(reqSpec.Power) + if err != nil { + err = status.Errorf(codes.InvalidArgument, "invalid power: %v", reqSpec.Power) + log.Error(ctx, err) + return nil, err + } + image := reqSpec.GetImage().GetImage() + class := reqSpec.GetClass() + if class == "" { + err = status.Errorf(codes.InvalidArgument, "machine class must be set") + log.Error(ctx, err) + return nil, err + } + if len(reqSpec.GetVolumes()) != 0 { + log.Error(ctx, status.Errorf(codes.Unimplemented, "volumes are not supported yet")) + } + if len(reqSpec.GetNetworkInterfaces()) != 0 { + log.Error(ctx, status.Errorf(codes.Unimplemented, "network_interfaces are not supported yet")) + } + ctx = log.WithValues(ctx, "power", power, "image", image, "class", class) + + log.Debug(ctx, "Getting machine class") + var c computev1alpha1.MachineClass + err = s.Get(ctx, client.ObjectKey{ + Name: class, + }, &c) + if err != nil { + if errors.IsNotFound(err) { + err = status.Errorf(codes.NotFound, "MachineClass does not exist") + log.Error(ctx, err) + return nil, err + } + return nil, internalError(ctx, fmt.Errorf("cannot get MachineClass: %w", err)) + } + + var cid uuid.UUID + cid, err = uuid.NewRandom() + if err != nil { + err = status.Errorf(codes.InvalidArgument, "cannot generate UUID: %s", err) + log.Error(ctx, err) + return nil, err + } + + iriAnnotations := addPrefix(MetalProviderIRIPrefix, reqMetadata.Annotations) + iriLabels := addPrefix(MetalProviderIRIPrefix, reqMetadata.Labels) + + log.Debug(ctx, "Creating ConfigMap") + cm := v1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: cid.String(), + Namespace: s.namespace, + }, + } + cmApply := v1apply.ConfigMap(cm.Name, cm.Namespace). // FIXME - correct? + WithAnnotations(iriAnnotations). + WithLabels(iriLabels). + WithData(map[string]string{ + "image": image, + }). + WithBinaryData(map[string][]byte{ + "ignition-custom": reqSpec.GetIgnitionData(), + }) + err = s.Patch(ctx, &cm, ssa.Apply(cmApply), client.FieldOwner(MetalProviderFieldManager), client.ForceOwnership) + if err != nil { + return nil, internalError(ctx, fmt.Errorf("cannot apply ConfigMap: %w", err)) + } + + log.Debug(ctx, "Creating MachineClaim") + claim := metalv1alpha1.MachineClaim{ + ObjectMeta: metav1.ObjectMeta{ + Name: cid.String(), + Namespace: s.namespace, + }, + } + apply := metalv1alpha1apply.MachineClaim(claim.Name, claim.Namespace). + WithAnnotations(iriAnnotations). + WithLabels(iriLabels). + WithSpec(metalv1alpha1apply.MachineClaimSpec(). + WithMachineSelector(metav1apply.LabelSelector(). + WithMatchLabels(map[string]string{ + MetalProviderSizePrefix + class: "true", + })). + WithImage(image). + WithPower(power). + WithIgnitionSecretRef(v1.LocalObjectReference{ + Name: cm.Name, + })) + // TODO: Volumes + // TODO: Network + err = s.Patch(ctx, &claim, ssa.Apply(apply), client.FieldOwner(MetalProviderFieldManager), client.ForceOwnership) + if err != nil { + return nil, internalError(ctx, fmt.Errorf("cannot apply MachineClaim: %w", err)) + } + + log.Info(ctx, "Reserved machine") + return &irimachinev1alpha1.CreateMachineResponse{ + Machine: &irimachinev1alpha1.Machine{ + Metadata: &irimetav1alpha1.ObjectMetadata{ + Id: claim.Name, + Annotations: reqMetadata.Annotations, + Labels: reqMetadata.Labels, + }, + Spec: reqSpec, + Status: &irimachinev1alpha1.MachineStatus{ + State: irimachinev1alpha1.MachineState_MACHINE_PENDING, + ImageRef: image, + // TODO: Volumes + // TODO: Network + }, + }, + }, nil +} + +func (s *MetalProviderServer) DeleteMachine(ctx context.Context, req *irimachinev1alpha1.DeleteMachineRequest) (*irimachinev1alpha1.DeleteMachineResponse, error) { + ctx = log.WithValues(ctx, "request", "DeleteMachine") + log.Debug(ctx, "Serving") + + err := status.Errorf(codes.Unimplemented, "DeleteMachine() has not been implemented yet") + log.Error(ctx, err) + return nil, err + + // id := req.GetMachineId() + // if id == "" { + // err := status.Errorf(codes.InvalidArgument, "machine id must be specified") + // log.Error(ctx, err) + // return nil, err + // } + // ctx = log.WithValues(ctx, "machine", id) + // + // log.Debug(ctx, "Getting machine") + // var machine metalv1alpha4.Machine + // err := s.Get(ctx, client.ObjectKey{Namespace: s.namespace, Name: id}, &machine) + // if err != nil { + // if kerrors.IsNotFound(err) { + // err = status.Errorf(codes.NotFound, "machine does not exist") + // log.Error(ctx, err) + // return nil, err + // } + // return nil, internalError(ctx, fmt.Errorf("cannot get machine: %w", err)) + // } + // + // if machine.Status.Reservation.Status != "Reserved" { + // err = status.Errorf(codes.NotFound, "machine is not reserved") + // log.Error(ctx, err) + // return nil, err + // } + // + // // TODO: Power + // + // bootMapApply := v1apply.ConfigMap(fmt.Sprintf("ipxe-%s", machine.Name), machine.Namespace) + // bootMap := &v1.ConfigMap{ + // TypeMeta: metav1.TypeMeta{ + // APIVersion: *bootMapApply.APIVersion, + // Kind: *bootMapApply.Kind, + // }, + // ObjectMeta: metav1.ObjectMeta{ + // Namespace: *bootMapApply.Namespace, + // Name: *bootMapApply.Name, + // }, + // } + // err = s.Delete(ctx, bootMap) + // if err != nil && !kerrors.IsNotFound(err) { + // return nil, internalError(ctx, fmt.Errorf("could not delete boot configmap: %w", err)) + // } + // + // machineApply := metalv1alpha4apply.Machine(machine.Name, machine.Namespace) + // annotations, moda := overlayOntoPrefixed(IRILabelPrefix, map[string]string{}, machine.Annotations) + // if moda { + // machineApply = machineApply.WithAnnotations(annotations) + // } + // labels, modl := overlayOntoPrefixed(IriLabelPrefix, map[string]string{}, machine.Labels) + // if modl { + // machineApply = machineApply.WithLabels(labels) + // } + // if moda || modl { + // machine = metalv1alpha4.Machine{ + // TypeMeta: metav1.TypeMeta{ + // APIVersion: *machineApply.APIVersion, + // Kind: *machineApply.Kind, + // }, + // ObjectMeta: metav1.ObjectMeta{ + // Namespace: *machineApply.Namespace, + // Name: *machineApply.Name, + // }, + // } + // log.Debug(ctx, "Applying machine annotations and labels") + // err = s.Patch(ctx, &machine, patch.ApplyConfiguration(machineApply), client.FieldOwner("metal-provider.ironcore.dev"), client.ForceOwnership) + // if err != nil { + // return nil, internalError(ctx, fmt.Errorf("could not apply machine: %w", err)) + // } + // } + // + // machineApply = metalv1alpha4apply.Machine(machine.Name, machine.Namespace).WithStatus(metalv1alpha4apply.MachineStatus().WithReservation(metalv1alpha4apply.Reservation().WithStatus("Available"))) + // machine = metalv1alpha4.Machine{ + // TypeMeta: metav1.TypeMeta{ + // APIVersion: *machineApply.APIVersion, + // Kind: *machineApply.Kind, + // }, + // ObjectMeta: metav1.ObjectMeta{ + // Namespace: *machineApply.Namespace, + // Name: *machineApply.Name, + // }, + // } + // log.Debug(ctx, "Applying machine status") + // err = s.Client.Status().Patch(ctx, &machine, patch.ApplyConfiguration(machineApply), client.FieldOwner("metal-provider.ironcore.dev"), client.ForceOwnership) + // if err != nil { + // return nil, internalError(ctx, fmt.Errorf("could not apply machine status: %w", err)) + // } + // + //log.Info(ctx, "Released machine") + //return &irimachinev1alpha1.DeleteMachineResponse{}, nil +} + +func (s *MetalProviderServer) UpdateMachineAnnotations(ctx context.Context, _ *irimachinev1alpha1.UpdateMachineAnnotationsRequest) (*irimachinev1alpha1.UpdateMachineAnnotationsResponse, error) { + ctx = log.WithValues(ctx, "request", "UpdateMachineAnnotations") + log.Debug(ctx, "Serving") + + err := status.Errorf(codes.Unimplemented, "UpdateMachineAnnotations() has not been implemented yet") + log.Error(ctx, err) + return nil, err +} + +func (s *MetalProviderServer) UpdateMachinePower(ctx context.Context, _ *irimachinev1alpha1.UpdateMachinePowerRequest) (*irimachinev1alpha1.UpdateMachinePowerResponse, error) { + ctx = log.WithValues(ctx, "request", "UpdateMachinePower") + log.Debug(ctx, "Serving") + + err := status.Errorf(codes.Unimplemented, "UpdateMachinePower() has not been implemented yet") + log.Error(ctx, err) + return nil, err +} + +func (s *MetalProviderServer) AttachVolume(ctx context.Context, _ *irimachinev1alpha1.AttachVolumeRequest) (*irimachinev1alpha1.AttachVolumeResponse, error) { + ctx = log.WithValues(ctx, "request", "AttachVolume") + log.Debug(ctx, "Serving") + + err := status.Errorf(codes.Unimplemented, "AttachVolume() has not been implemented yet") + log.Error(ctx, err) + return nil, err +} + +func (s *MetalProviderServer) DetachVolume(ctx context.Context, _ *irimachinev1alpha1.DetachVolumeRequest) (*irimachinev1alpha1.DetachVolumeResponse, error) { + ctx = log.WithValues(ctx, "request", "DetachVolume") + log.Debug(ctx, "Serving") + + err := status.Errorf(codes.Unimplemented, "DetachVolume() has not been implemented yet") + log.Error(ctx, err) + return nil, err +} + +func (s *MetalProviderServer) AttachNetworkInterface(ctx context.Context, _ *irimachinev1alpha1.AttachNetworkInterfaceRequest) (*irimachinev1alpha1.AttachNetworkInterfaceResponse, error) { + ctx = log.WithValues(ctx, "request", "AttachNetworkInterface") + log.Debug(ctx, "Serving") + + err := status.Errorf(codes.Unimplemented, "AttachNetworkInterface() has not been implemented yet") + log.Error(ctx, err) + return nil, err +} + +func (s *MetalProviderServer) DetachNetworkInterface(ctx context.Context, _ *irimachinev1alpha1.DetachNetworkInterfaceRequest) (*irimachinev1alpha1.DetachNetworkInterfaceResponse, error) { + ctx = log.WithValues(ctx, "request", "DetachNetworkInterface") + log.Debug(ctx, "Serving") + + err := status.Errorf(codes.Unimplemented, "DetachNetworkInterface() has not been implemented yet") + log.Error(ctx, err) + return nil, err +} + +func (s *MetalProviderServer) Status(ctx context.Context, _ *irimachinev1alpha1.StatusRequest) (*irimachinev1alpha1.StatusResponse, error) { + ctx = log.WithValues(ctx, "request", "Status") + log.Debug(ctx, "Serving") + + log.Debug(ctx, "Listing machines") + var machines metalv1alpha1.MachineList + err := s.List(ctx, &machines) + if err != nil { + return nil, internalError(ctx, fmt.Errorf("cannot list Machines: %w", err)) + } + + classes := make(map[string]*irimachinev1alpha1.MachineClassStatus) + for _, m := range machines.Items { + for l, v := range m.Labels { + sz, ok := strings.CutPrefix(l, MetalProviderSizePrefix) + if !ok || v != "true" { + continue + } + ctxx := log.WithValues(ctx, "size", sz) + + var c *irimachinev1alpha1.MachineClassStatus + c, ok = classes[sz] + if !ok { + classes[sz] = nil + + log.Debug(ctxx, "Getting machine class") + var class computev1alpha1.MachineClass + err = s.Get(ctx, client.ObjectKey{ + Name: sz, + }, &class) + if err != nil { + if errors.IsNotFound(err) { + log.Debug(ctxx, "MachineClass does not exist, ignoring") + continue + } + return nil, internalError(ctxx, fmt.Errorf("cannot get MachineClass: %w", err)) + } + + //cpum := class.Capabilities.CPU().MilliValue() + //var mem int64 + //mem, ok = class.Capabilities.Memory().AsInt64() + //if !ok { + // mem = 0 + //} + c = &irimachinev1alpha1.MachineClassStatus{ + MachineClass: &irimachinev1alpha1.MachineClass{ + Name: sz, + // FIXME: check if it is ok to skip this + //Capabilities: &irimachinev1alpha1.MachineClassCapabilities{ + // CpuMillis: cpum, + // MemoryBytes: mem, + //}, + }, + } + classes[sz] = c + } + if c != nil && m.Status.State == "Available" { + c.Quantity++ + } + } + } + + r := &irimachinev1alpha1.StatusResponse{} + for _, c := range classes { + if c != nil { + log.Debug(ctx, "Machine class", "name", c.MachineClass.Name, "quantity", c.Quantity) + r.MachineClassStatus = append(r.MachineClassStatus, c) + } + } + return r, nil +} + +func (s *MetalProviderServer) Exec(ctx context.Context, _ *irimachinev1alpha1.ExecRequest) (*irimachinev1alpha1.ExecResponse, error) { + err := status.Errorf(codes.Unimplemented, "Exec() has not been implemented yet") + log.Error(ctx, err) + return nil, err +} + +func internalError(ctx context.Context, err error) error { + err = status.Errorf(codes.Internal, "%s", err) + log.Error(ctx, err) + return err +} + +func addPrefix(p string, m map[string]string) map[string]string { + pm := make(map[string]string, len(m)) + for k, v := range m { + pm[p+k] = v + } + return pm +} + +func iriPowerToPower(p irimachinev1alpha1.Power) (metalv1alpha1.Power, error) { + switch p { + case irimachinev1alpha1.Power_POWER_OFF: + return metalv1alpha1.PowerOff, nil + case irimachinev1alpha1.Power_POWER_ON: + return metalv1alpha1.PowerOn, nil + default: + return "", fmt.Errorf("invalid power value: %v", p) + } +} + +//func overlayOntoPrefixed(prefix string, overlay, prefixed map[string]string) (map[string]string, bool) { +// mod := false +// +// for k, v := range overlay { +// pk := fmt.Sprintf("%s%s", prefix, k) +// vv, ok := prefixed[pk] +// if !ok || vv != v { +// if prefixed == nil { +// prefixed = make(map[string]string) +// } +// prefixed[pk] = v +// mod = true +// } +// } +// +// lenp := len(prefix) +// for pk := range prefixed { +// if !strings.HasPrefix(pk, prefix) { +// continue +// } +// k := pk[lenp:] +// _, ok := overlay[k] +// if !ok { +// delete(prefixed, pk) +// mod = true +// } +// } +// +// return prefixed, mod +//} + +//func extractFromPrefixed(prefix string, prefixed map[string]string) map[string]string { +// var extracted map[string]string +// lenp := len(prefix) +// for pk, v := range prefixed { +// if !strings.HasPrefix(pk, prefix) { +// continue +// } +// if extracted == nil { +// extracted = make(map[string]string) +// } +// extracted[pk[lenp:]] = v +// } +// return extracted +//} + +//func kMetaToMeta(meta *metav1.ObjectMeta) *irimetav1alpha1.ObjectMetadata { +// iriMeta := &irimetav1alpha1.ObjectMetadata{ +// Id: meta.Name, +// Annotations: extractFromPrefixed(IriLabelPrefix, meta.Annotations), +// Labels: extractFromPrefixed(IriLabelPRefix, meta.Labels), +// Generation: meta.Generation, +// CreatedAt: meta.CreationTimestamp.Unix(), +// } +// if meta.DeletionTimestamp != nil { +// iriMeta.DeletedAt = meta.DeletionTimestamp.Unix() +// } +// return iriMeta +//} diff --git a/servers/servers_test.go b/internal/server/server_test.go similarity index 53% rename from servers/servers_test.go rename to internal/server/server_test.go index d47de0d..cc05b37 100644 --- a/servers/servers_test.go +++ b/internal/server/server_test.go @@ -1,20 +1,15 @@ // SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and IronCore contributors // SPDX-License-Identifier: Apache-2.0 -package servers +package server import ( "testing" - "time" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" ) func TestAPIs(t *testing.T) { - SetDefaultConsistentlyPollingInterval(200 * time.Millisecond) - SetDefaultEventuallyPollingInterval(200 * time.Millisecond) - SetDefaultConsistentlyDuration(3 * time.Second) - SetDefaultEventuallyTimeout(7 * time.Second) RegisterFailHandler(Fail) } diff --git a/internal/ssa/ssa.go b/internal/ssa/ssa.go new file mode 100644 index 0000000..481417f --- /dev/null +++ b/internal/ssa/ssa.go @@ -0,0 +1,28 @@ +// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and IronCore contributors +// SPDX-License-Identifier: Apache-2.0 + +package ssa + +import ( + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/json" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +func Apply(applyConfig interface{}) client.Patch { + return applyPatch{ + applyConfig: applyConfig, + } +} + +type applyPatch struct { + applyConfig interface{} +} + +func (p applyPatch) Type() types.PatchType { + return types.ApplyPatchType +} + +func (p applyPatch) Data(_ client.Object) ([]byte, error) { + return json.Marshal(p.applyConfig) +} diff --git a/tools.go b/internal/tools.go similarity index 79% rename from tools.go rename to internal/tools.go index 2a7be29..45276c4 100644 --- a/tools.go +++ b/internal/tools.go @@ -4,9 +4,10 @@ //go:build tools // +build tools -package main +package internal import ( + _ "github.com/golangci/golangci-lint/cmd/golangci-lint" _ "github.com/google/addlicense" _ "github.com/ironcore-dev/ironcore/irictl-machine/cmd/irictl-machine" ) diff --git a/main.go b/main.go deleted file mode 100644 index cda4bc6..0000000 --- a/main.go +++ /dev/null @@ -1,217 +0,0 @@ -// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and IronCore contributors -// SPDX-License-Identifier: Apache-2.0 - -package main - -import ( - "context" - "fmt" - "os" - "os/signal" - "path/filepath" - "strings" - "syscall" - - "github.com/go-logr/logr" - "github.com/spf13/pflag" - "github.com/spf13/viper" - "k8s.io/apimachinery/pkg/runtime" - kscheme "k8s.io/client-go/kubernetes/scheme" - "k8s.io/klog/v2" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/healthz" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/metrics/server" - - computev1alpha1 "github.com/ironcore-dev/ironcore/api/compute/v1alpha1" - "github.com/ironcore-dev/metal-provider/internal/log" - "github.com/ironcore-dev/metal-provider/servers" - metalv1alpha4 "github.com/ironcore-dev/metal/apis/metal/v1alpha4" -) - -func usage() { - name := filepath.Base(os.Args[0]) - _, _ = fmt.Fprintf(os.Stderr, "Usage: %s [--option]...\n", name) - _, _ = fmt.Fprintf(os.Stderr, "Options:\n") - pflag.PrintDefaults() -} - -func exitUsage(err error) { - if err != nil { - _, _ = fmt.Fprintf(os.Stderr, "%s: %s\n", filepath.Base(os.Args[0]), err) - } - pflag.Usage() - os.Exit(2) -} - -type params struct { - dev bool - leaderElect bool - healthProbeBindAddress string - metricsBindAddress string - kubeconfig string - namespace string - gRPCAddr string -} - -func parseCmdLine() params { - pflag.Usage = usage - pflag.ErrHelp = nil - pflag.CommandLine = pflag.NewFlagSet(os.Args[0], pflag.ContinueOnError) - - pflag.Bool("dev", false, "Log human-readable messages at debug level.") - pflag.Bool("leader-elect", false, "Enable leader election for controller manager to ensure there is only one active controller manager.") - pflag.String("health-probe-bind-address", "", "The address that the health probe server will listen on.") - pflag.String("metrics-bind-address", "0", "The address that the metrics server will listen on.") - pflag.String("kubeconfig", "", "Use a kubeconfig to run out of cluster.") - pflag.String("namespace", "", "Limit monitoring to a specific namespace.") - pflag.String("grpc-address", "/run/metal-provider.sock", "The address that the gRPC server will listen on.") - - var help bool - pflag.BoolVarP(&help, "help", "h", false, "Show this help message.") - err := viper.BindPFlags(pflag.CommandLine) - if err != nil { - exitUsage(err) - } - viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_")) - viper.AutomaticEnv() - err = pflag.CommandLine.Parse(os.Args[1:]) - if err != nil { - exitUsage(err) - } - if help { - exitUsage(nil) - } - - return params{ - dev: viper.GetBool("dev"), - leaderElect: viper.GetBool("leader-elect"), - healthProbeBindAddress: viper.GetString("health-probe-bind-address"), - metricsBindAddress: viper.GetString("metrics-bind-address"), - kubeconfig: viper.GetString("kubeconfig"), - namespace: viper.GetString("namespace"), - gRPCAddr: viper.GetString("grpc-address"), - } -} - -func main() { - p := parseCmdLine() - - var exitCode int - defer func() { os.Exit(exitCode) }() - - ctx, stop := signal.NotifyContext(log.Setup(context.Background(), p.dev, false, os.Stderr), syscall.SIGTERM, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGHUP) - defer stop() - log.Info(ctx, "Starting ORI machine provider") - - defer func() { log.Info(ctx, "Exiting", "exitCode", exitCode) }() - - l := logr.FromContextOrDiscard(ctx) - klog.SetLogger(l) - ctrl.SetLogger(l) - - if p.namespace == "" { - ns, err := os.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace") - if err != nil && !os.IsNotExist(err) { - log.Error(ctx, fmt.Errorf("cannot determine in-cluster namespace: %w", err)) - exitCode = 1 - return - } - p.namespace = string(ns) - if p.namespace == "" { - log.Error(ctx, fmt.Errorf("namespace must be specified when running outside of a Kubernetes cluster")) - exitCode = 1 - return - } - log.Debug(ctx, "Using in-cluster namespace", "namespace", p.namespace) - } - - log.Debug(ctx, "Loading kubeconfig") - kcfg, err := ctrl.GetConfig() - if err != nil { - log.Error(ctx, fmt.Errorf("cannot load kubeconfig: %w", err)) - exitCode = 1 - return - } - - scheme := runtime.NewScheme() - err = kscheme.AddToScheme(scheme) - if err != nil { - log.Error(ctx, fmt.Errorf("cannot create type scheme: %w", err)) - exitCode = 1 - return - } - err = computev1alpha1.AddToScheme(scheme) - if err != nil { - log.Error(ctx, fmt.Errorf("cannot create type scheme: %w", err)) - exitCode = 1 - return - } - err = metalv1alpha4.AddToScheme(scheme) - if err != nil { - log.Error(ctx, fmt.Errorf("cannot create type scheme: %w", err)) - exitCode = 1 - return - } - err = metalv1alpha4.AddToScheme(scheme) - if err != nil { - log.Error(ctx, fmt.Errorf("cannot create type scheme: %w", err)) - exitCode = 1 - return - } - - var mgr manager.Manager - mgr, err = ctrl.NewManager(kcfg, ctrl.Options{ - BaseContext: func() context.Context { - return ctx - }, - Scheme: scheme, - LeaderElection: p.leaderElect, - LeaderElectionID: "metal-provider.ironcore.dev", - HealthProbeBindAddress: p.healthProbeBindAddress, - Metrics: server.Options{ - BindAddress: p.metricsBindAddress, - }, - }) - if err != nil { - log.Error(ctx, fmt.Errorf("cannot create manager: %w", err)) - exitCode = 1 - return - } - - err = mgr.AddHealthzCheck("health", healthz.Ping) - if err != nil { - log.Error(ctx, fmt.Errorf("cannot set up health check: %w", err)) - exitCode = 1 - return - } - - err = mgr.AddReadyzCheck("check", healthz.Ping) - if err != nil { - log.Error(ctx, fmt.Errorf("cannot set up ready check: %w", err)) - exitCode = 1 - return - } - - var grpcServer *servers.GRPCServer - grpcServer, err = servers.NewGRPCServer(p.gRPCAddr, p.namespace) - if err != nil { - log.Error(ctx, fmt.Errorf("cannot create server: %w", err), "server", "gRPC") - exitCode = 1 - return - } - err = grpcServer.SetupWithManager(mgr) - if err != nil { - log.Error(ctx, fmt.Errorf("cannot create server: %w", err), "server", "gRPC") - exitCode = 1 - return - } - - log.Info(ctx, "Starting manager") - err = mgr.Start(ctx) - if err != nil { - log.Error(ctx, err) - exitCode = 1 - return - } -} diff --git a/servers/grpc_server.go b/servers/grpc_server.go deleted file mode 100644 index 041dd2c..0000000 --- a/servers/grpc_server.go +++ /dev/null @@ -1,656 +0,0 @@ -// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and IronCore contributors -// SPDX-License-Identifier: Apache-2.0 - -package servers - -import ( - "context" - "fmt" - "strings" - - "github.com/go-logr/logr" - "golang.org/x/sync/errgroup" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - v1 "k8s.io/api/core/v1" - kerrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - v1apply "k8s.io/client-go/applyconfigurations/core/v1" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - - computev1alpha1 "github.com/ironcore-dev/ironcore/api/compute/v1alpha1" - irimachinev1alpha1 "github.com/ironcore-dev/ironcore/iri/apis/machine/v1alpha1" - irimetav1alpha1 "github.com/ironcore-dev/ironcore/iri/apis/meta/v1alpha1" - - "github.com/ironcore-dev/metal-provider/internal/log" - "github.com/ironcore-dev/metal-provider/internal/patch" - "github.com/ironcore-dev/metal-provider/internal/unix" - metalv1alpha4 "github.com/ironcore-dev/metal/apis/metal/v1alpha4" - metalv1alpha4apply "github.com/ironcore-dev/metal/client/applyconfiguration/metal/v1alpha4" -) - -func NewGRPCServer(addr string, namespace string) (*GRPCServer, error) { - return &GRPCServer{ - addr: addr, - namespace: namespace, - }, nil -} - -type GRPCServer struct { - addr string - namespace string - logger logr.Logger - client.Client -} - -// SetupWithManager sets up the server with the Manager. -func (s *GRPCServer) SetupWithManager(mgr ctrl.Manager) error { - s.Client = mgr.GetClient() - - return mgr.Add(s) -} - -func (s *GRPCServer) Start(ctx context.Context) error { - s.logger = logr.FromContextOrDiscard(ctx) - - ctx = log.WithValues(ctx, "server", "gRPC") - log.Info(ctx, "Starting server") - - ln, err := unix.Listen(ctx, s.addr) - if err != nil { - return fmt.Errorf("could not listen to socket %s: %w", s.addr, err) - } - - srv := grpc.NewServer(grpc.UnaryInterceptor(s.addLogger)) - irimachinev1alpha1.RegisterMachineRuntimeServer(srv, s) - - var g *errgroup.Group - g, ctx = errgroup.WithContext(ctx) - g.Go(func() error { - log.Info(ctx, "Listening", "bindAddr", s.addr) - return srv.Serve(ln) - }) - g.Go(func() error { - <-ctx.Done() - log.Info(ctx, "Stopping server") - srv.GracefulStop() - log.Info(ctx, "Server finished") - return nil - }) - return g.Wait() -} - -func (s *GRPCServer) addLogger(ctx context.Context, req interface{}, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { - return handler(logr.NewContext(ctx, s.logger), req) -} - -func (s *GRPCServer) Version(ctx context.Context, _ *irimachinev1alpha1.VersionRequest) (*irimachinev1alpha1.VersionResponse, error) { - ctx = log.WithValues(ctx, "request", "ListMachines") - log.Debug(ctx, "Serving") - - return &irimachinev1alpha1.VersionResponse{ - RuntimeName: "metal-provider", - RuntimeVersion: "0.0.0", - }, nil -} - -func (s *GRPCServer) ListMachines(ctx context.Context, req *irimachinev1alpha1.ListMachinesRequest) (*irimachinev1alpha1.ListMachinesResponse, error) { - ctx = log.WithValues(ctx, "request", "ListMachines") - log.Debug(ctx, "Serving") - - filter := req.GetFilter() - id := filter.GetId() - selector := filter.GetLabelSelector() - if id != "" && selector != nil { - err := status.Errorf(codes.InvalidArgument, "machine id and label selectors cannot both be set") - log.Error(ctx, err) - return nil, err - } - - var machines []metalv1alpha4.Machine - if id == "" { - pselector, _ := overlayOntoPrefixed("iri-", selector, map[string]string{}) - log.Debug(ctx, "Listing machines", "selector", selector) - var machineList metalv1alpha4.MachineList - err := s.List(ctx, &machineList, client.InNamespace(s.namespace), client.MatchingLabels(pselector)) - if err != nil { - return nil, internalError(ctx, fmt.Errorf("could not list machines: %w", err)) - } - - for _, m := range machineList.Items { - if m.Status.Reservation.Status == "Reserved" { - machines = append(machines, m) - } - } - } else { - ctx = log.WithValues(ctx, "machine", id) - - log.Debug(ctx, "Getting machine") - var machine metalv1alpha4.Machine - err := s.Get(ctx, client.ObjectKey{Namespace: s.namespace, Name: id}, &machine) - if err != nil { - if kerrors.IsNotFound(err) { - err = status.Errorf(codes.NotFound, "machine does not exist") - log.Error(ctx, err) - return nil, err - } - return nil, internalError(ctx, fmt.Errorf("cannot get machine: %w", err)) - } - - if machine.Status.Reservation.Status != "Reserved" { - err = status.Errorf(codes.NotFound, "machine is not reserved") - log.Error(ctx, err) - return nil, err - } - - machines = append(machines, machine) - } - - resMachines := make([]*irimachinev1alpha1.Machine, 0, len(machines)) - for _, m := range machines { - var bootMap v1.ConfigMap - err := s.Get(ctx, client.ObjectKey{Namespace: m.Namespace, Name: fmt.Sprintf("ipxe-%s", m.Name)}, &bootMap) - if err != nil { - _ = internalError(ctx, fmt.Errorf("reserved machine has no boot configmap: %w", err)) - continue - } - image, ok := bootMap.Data["image"] - if !ok { - _ = internalError(ctx, fmt.Errorf("reserved machine has no image in boot configmap")) - continue - } - var ignition []byte - ignition, ok = bootMap.BinaryData["ignition-custom"] - if !ok { - _ = internalError(ctx, fmt.Errorf("reserved machine has no ignition-custom in boot configmap")) - continue - } - - resMachines = append(resMachines, &irimachinev1alpha1.Machine{ - Metadata: kMetaToMeta(&m.ObjectMeta), - Spec: &irimachinev1alpha1.MachineSpec{ - // TODO: Power - Image: &irimachinev1alpha1.ImageSpec{ - Image: image, - }, - Class: m.Status.Reservation.Class, - IgnitionData: ignition, - // TODO: Volumes - // TODO: Network - }, - Status: &irimachinev1alpha1.MachineStatus{ - // TODO: ObservedGeneration - State: irimachinev1alpha1.MachineState_MACHINE_PENDING, - ImageRef: image, - // TODO: Volumes - // TODO: Network - }, - }) - } - - return &irimachinev1alpha1.ListMachinesResponse{ - Machines: resMachines, - }, nil -} - -func (s *GRPCServer) CreateMachine(ctx context.Context, req *irimachinev1alpha1.CreateMachineRequest) (*irimachinev1alpha1.CreateMachineResponse, error) { - ctx = log.WithValues(ctx, "request", "CreateMachine") - log.Debug(ctx, "Serving") - - reqMachine := req.GetMachine() - reqMetadata := reqMachine.GetMetadata() - if reqMetadata.GetId() != "" { - err := status.Errorf(codes.InvalidArgument, "machine id must be empty") - log.Error(ctx, err) - return nil, err - } - if reqMetadata.GetGeneration() != 0 || reqMetadata.GetCreatedAt() != 0 || reqMetadata.GetDeletedAt() != 0 { - err := status.Errorf(codes.InvalidArgument, "machine generation, created_at, and deleted_at must all be empty") - log.Error(ctx, err) - return nil, err - } - - reqSpec := reqMachine.GetSpec() - if len(reqSpec.GetVolumes()) != 0 { - log.Error(ctx, status.Errorf(codes.Unimplemented, "volumes are not supported yet")) - } - if len(reqSpec.GetNetworkInterfaces()) != 0 { - log.Error(ctx, status.Errorf(codes.Unimplemented, "network_interfaces are not supported yet")) - } - class := reqSpec.GetClass() - if class == "" { - err := status.Errorf(codes.InvalidArgument, "machine class must be set") - log.Error(ctx, err) - return nil, err - } - image := reqSpec.GetImage().GetImage() - ctx = log.WithValues(ctx, "class", class, "image", image) - log.Debug(ctx, "Getting machine class") - var machineClass computev1alpha1.MachineClass - err := s.Get(ctx, client.ObjectKey{Name: class}, &machineClass) - if err != nil { - if kerrors.IsNotFound(err) { - err = status.Errorf(codes.NotFound, "machine class does not exist") - log.Error(ctx, err) - return nil, err - } - return nil, internalError(ctx, fmt.Errorf("cannot get machine class: %w", err)) - } - - szl := map[string]string{ - fmt.Sprintf("metal.ironcore.dev/size-%s", class): "true", - } - log.Debug(ctx, "Listing machines") - var machineList metalv1alpha4.MachineList - err = s.List(ctx, &machineList, client.InNamespace(s.namespace), client.MatchingLabels(szl)) - if err != nil { - return nil, internalError(ctx, fmt.Errorf("could not list machines: %w", err)) - } - - var machine *metalv1alpha4.Machine - for _, m := range machineList.Items { - if m.Status.Reservation.Status == "Available" && m.Status.Health == "Healthy" { - machine = &m - break - } - } - if machine == nil { - err = status.Errorf(codes.ResourceExhausted, "no machine is available") - log.Error(ctx, err) - return nil, err - } - ctx = log.WithValues(ctx, "machine", machine.Name) - - machineApply := metalv1alpha4apply.Machine(machine.Name, machine.Namespace).WithStatus(metalv1alpha4apply.MachineStatus().WithReservation(metalv1alpha4apply.Reservation().WithStatus("Reserved").WithClass(class))) - machine = &metalv1alpha4.Machine{ - TypeMeta: metav1.TypeMeta{ - APIVersion: *machineApply.APIVersion, - Kind: *machineApply.Kind, - }, - ObjectMeta: metav1.ObjectMeta{ - Namespace: *machineApply.Namespace, - Name: *machineApply.Name, - }, - } - log.Debug(ctx, "Applying machine status") - err = s.Client.Status().Patch(ctx, machine, patch.ApplyConfiguration(machineApply), client.FieldOwner("metal-provider.ironcore.dev"), client.ForceOwnership) - if err != nil { - return nil, internalError(ctx, fmt.Errorf("could not apply machine status: %w", err)) - } - - machineApply = metalv1alpha4apply.Machine(machine.Name, machine.Namespace) - annotations, moda := overlayOntoPrefixed("iri-", reqMetadata.Annotations, machine.Annotations) - if moda { - machineApply = machineApply.WithAnnotations(annotations) - } - labels, modl := overlayOntoPrefixed("iri-", reqMetadata.Labels, machine.Labels) - if modl { - machineApply = machineApply.WithLabels(labels) - } - if moda || modl { - machine = &metalv1alpha4.Machine{ - TypeMeta: metav1.TypeMeta{ - APIVersion: *machineApply.APIVersion, - Kind: *machineApply.Kind, - }, - ObjectMeta: metav1.ObjectMeta{ - Namespace: *machineApply.Namespace, - Name: *machineApply.Name, - }, - } - log.Debug(ctx, "Applying machine annotations and labels") - err = s.Patch(ctx, machine, patch.ApplyConfiguration(machineApply), client.FieldOwner("metal-provider.ironcore.dev"), client.ForceOwnership) - if err != nil { - return nil, internalError(ctx, fmt.Errorf("could not apply machine: %w", err)) - } - } - - bootMapData := map[string]string{ - "image": image, - } - bootMapBinaryData := map[string][]byte{ - "ignition-custom": reqSpec.GetIgnitionData(), - } - bootMapApply := v1apply.ConfigMap(fmt.Sprintf("ipxe-%s", machine.Name), machine.Namespace).WithData(bootMapData).WithBinaryData(bootMapBinaryData) - bootMap := &v1.ConfigMap{ - TypeMeta: metav1.TypeMeta{ - APIVersion: *bootMapApply.APIVersion, - Kind: *bootMapApply.Kind, - }, - ObjectMeta: metav1.ObjectMeta{ - Namespace: *bootMapApply.Namespace, - Name: *bootMapApply.Name, - }, - } - err = s.Delete(ctx, bootMap) - if err != nil && !kerrors.IsNotFound(err) { - return nil, internalError(ctx, fmt.Errorf("could not delete boot configmap: %w", err)) - } - - bootMap = &v1.ConfigMap{ - TypeMeta: metav1.TypeMeta{ - APIVersion: *bootMapApply.APIVersion, - Kind: *bootMapApply.Kind, - }, - ObjectMeta: metav1.ObjectMeta{ - Namespace: *bootMapApply.Namespace, - Name: *bootMapApply.Name, - }, - } - log.Debug(ctx, "Applying boot configmap") - err = s.Patch(ctx, bootMap, patch.ApplyConfiguration(bootMapApply), client.FieldOwner("metal-provider.ironcore.dev"), client.ForceOwnership) - if err != nil && !kerrors.IsNotFound(err) { - return nil, internalError(ctx, fmt.Errorf("could not apply boot configmap: %w", err)) - } - - // TODO: Power - - log.Info(ctx, "Reserved machine") - return &irimachinev1alpha1.CreateMachineResponse{ - Machine: &irimachinev1alpha1.Machine{ - Metadata: kMetaToMeta(&machine.ObjectMeta), - Spec: &irimachinev1alpha1.MachineSpec{ - // TODO: Power - Image: reqSpec.Image, - Class: reqSpec.Class, - IgnitionData: reqSpec.IgnitionData, - // TODO: Volumes - // TODO: Network - }, - Status: &irimachinev1alpha1.MachineStatus{ - // TODO: ObservedGeneration - State: irimachinev1alpha1.MachineState_MACHINE_PENDING, - ImageRef: image, - // TODO: Volumes - // TODO: Network - }, - }, - }, nil -} - -func (s *GRPCServer) DeleteMachine(ctx context.Context, req *irimachinev1alpha1.DeleteMachineRequest) (*irimachinev1alpha1.DeleteMachineResponse, error) { - ctx = log.WithValues(ctx, "request", "DeleteMachine") - log.Debug(ctx, "Serving") - - id := req.GetMachineId() - if id == "" { - err := status.Errorf(codes.InvalidArgument, "machine id must be specified") - log.Error(ctx, err) - return nil, err - } - ctx = log.WithValues(ctx, "machine", id) - - log.Debug(ctx, "Getting machine") - var machine metalv1alpha4.Machine - err := s.Get(ctx, client.ObjectKey{Namespace: s.namespace, Name: id}, &machine) - if err != nil { - if kerrors.IsNotFound(err) { - err = status.Errorf(codes.NotFound, "machine does not exist") - log.Error(ctx, err) - return nil, err - } - return nil, internalError(ctx, fmt.Errorf("cannot get machine: %w", err)) - } - - if machine.Status.Reservation.Status != "Reserved" { - err = status.Errorf(codes.NotFound, "machine is not reserved") - log.Error(ctx, err) - return nil, err - } - - // TODO: Power - - bootMapApply := v1apply.ConfigMap(fmt.Sprintf("ipxe-%s", machine.Name), machine.Namespace) - bootMap := &v1.ConfigMap{ - TypeMeta: metav1.TypeMeta{ - APIVersion: *bootMapApply.APIVersion, - Kind: *bootMapApply.Kind, - }, - ObjectMeta: metav1.ObjectMeta{ - Namespace: *bootMapApply.Namespace, - Name: *bootMapApply.Name, - }, - } - err = s.Delete(ctx, bootMap) - if err != nil && !kerrors.IsNotFound(err) { - return nil, internalError(ctx, fmt.Errorf("could not delete boot configmap: %w", err)) - } - - machineApply := metalv1alpha4apply.Machine(machine.Name, machine.Namespace) - annotations, moda := overlayOntoPrefixed("iri-", map[string]string{}, machine.Annotations) - if moda { - machineApply = machineApply.WithAnnotations(annotations) - } - labels, modl := overlayOntoPrefixed("iri-", map[string]string{}, machine.Labels) - if modl { - machineApply = machineApply.WithLabels(labels) - } - if moda || modl { - machine = metalv1alpha4.Machine{ - TypeMeta: metav1.TypeMeta{ - APIVersion: *machineApply.APIVersion, - Kind: *machineApply.Kind, - }, - ObjectMeta: metav1.ObjectMeta{ - Namespace: *machineApply.Namespace, - Name: *machineApply.Name, - }, - } - log.Debug(ctx, "Applying machine annotations and labels") - err = s.Patch(ctx, &machine, patch.ApplyConfiguration(machineApply), client.FieldOwner("metal-provider.ironcore.dev"), client.ForceOwnership) - if err != nil { - return nil, internalError(ctx, fmt.Errorf("could not apply machine: %w", err)) - } - } - - machineApply = metalv1alpha4apply.Machine(machine.Name, machine.Namespace).WithStatus(metalv1alpha4apply.MachineStatus().WithReservation(metalv1alpha4apply.Reservation().WithStatus("Available"))) - machine = metalv1alpha4.Machine{ - TypeMeta: metav1.TypeMeta{ - APIVersion: *machineApply.APIVersion, - Kind: *machineApply.Kind, - }, - ObjectMeta: metav1.ObjectMeta{ - Namespace: *machineApply.Namespace, - Name: *machineApply.Name, - }, - } - log.Debug(ctx, "Applying machine status") - err = s.Client.Status().Patch(ctx, &machine, patch.ApplyConfiguration(machineApply), client.FieldOwner("metal-provider.ironcore.dev"), client.ForceOwnership) - if err != nil { - return nil, internalError(ctx, fmt.Errorf("could not apply machine status: %w", err)) - } - - log.Info(ctx, "Released machine") - return &irimachinev1alpha1.DeleteMachineResponse{}, nil -} - -func (s *GRPCServer) UpdateMachineAnnotations(ctx context.Context, _ *irimachinev1alpha1.UpdateMachineAnnotationsRequest) (*irimachinev1alpha1.UpdateMachineAnnotationsResponse, error) { - err := status.Errorf(codes.Unimplemented, "UpdateMachineAnnotations() has not been implemented yet") - log.Error(ctx, err) - return nil, err -} - -func (s *GRPCServer) UpdateMachinePower(ctx context.Context, _ *irimachinev1alpha1.UpdateMachinePowerRequest) (*irimachinev1alpha1.UpdateMachinePowerResponse, error) { - err := status.Errorf(codes.Unimplemented, "UpdateMachinePower() has not been implemented yet") - log.Error(ctx, err) - return nil, err -} - -func (s *GRPCServer) AttachVolume(ctx context.Context, _ *irimachinev1alpha1.AttachVolumeRequest) (*irimachinev1alpha1.AttachVolumeResponse, error) { - err := status.Errorf(codes.Unimplemented, "AttachVolume() has not been implemented yet") - log.Error(ctx, err) - return nil, err -} - -func (s *GRPCServer) DetachVolume(ctx context.Context, _ *irimachinev1alpha1.DetachVolumeRequest) (*irimachinev1alpha1.DetachVolumeResponse, error) { - err := status.Errorf(codes.Unimplemented, "DetachVolume() has not been implemented yet") - log.Error(ctx, err) - return nil, err -} - -func (s *GRPCServer) AttachNetworkInterface(ctx context.Context, _ *irimachinev1alpha1.AttachNetworkInterfaceRequest) (*irimachinev1alpha1.AttachNetworkInterfaceResponse, error) { - err := status.Errorf(codes.Unimplemented, "AttachNetworkInterface() has not been implemented yet") - log.Error(ctx, err) - return nil, err -} - -func (s *GRPCServer) DetachNetworkInterface(ctx context.Context, _ *irimachinev1alpha1.DetachNetworkInterfaceRequest) (*irimachinev1alpha1.DetachNetworkInterfaceResponse, error) { - err := status.Errorf(codes.Unimplemented, "DetachNetworkInterface() has not been implemented yet") - log.Error(ctx, err) - return nil, err -} - -func (s *GRPCServer) Status(ctx context.Context, _ *irimachinev1alpha1.StatusRequest) (*irimachinev1alpha1.StatusResponse, error) { - ctx = log.WithValues(ctx, "request", "Status") - log.Debug(ctx, "Serving") - - classes := make(map[string]*irimachinev1alpha1.MachineClassStatus) - - log.Debug(ctx, "Listing machines") - var machines metalv1alpha4.MachineList - err := s.List(ctx, &machines, client.InNamespace(s.namespace)) - if err != nil { - return nil, internalError(ctx, fmt.Errorf("cannot list machines: %w", err)) - } - for _, m := range machines.Items { - for l, v := range m.Labels { - sz, ok := strings.CutPrefix(l, "metal.ironcore.dev/size-") - if !ok || v != "true" { - continue - } - ctxx := log.WithValues(ctx, "size", sz) - - var c *irimachinev1alpha1.MachineClassStatus - c, ok = classes[sz] - if !ok { - classes[sz] = nil - - log.Debug(ctxx, "Getting size") - var size metalv1alpha4.Size - err = s.Get(ctx, client.ObjectKey{Namespace: s.namespace, Name: sz}, &size) - if err != nil { - if kerrors.IsNotFound(err) { - log.Debug(ctxx, "Size does not exist, ignoring") - continue - } - return nil, internalError(ctxx, fmt.Errorf("cannot get size: %w", err)) - } - - log.Debug(ctxx, "Getting machine class") - var machineClass computev1alpha1.MachineClass - err = s.Get(ctx, client.ObjectKey{Name: sz}, &machineClass) - if err != nil { - if kerrors.IsNotFound(err) { - log.Debug(ctxx, "Machine class does not exist, ignoring") - continue - } - return nil, internalError(ctxx, fmt.Errorf("cannot get machine class: %w", err)) - } - - cpum := machineClass.Capabilities.CPU().MilliValue() - var mem int64 - mem, ok = machineClass.Capabilities.Memory().AsInt64() - if !ok { - mem = 0 - } - c = &irimachinev1alpha1.MachineClassStatus{ - MachineClass: &irimachinev1alpha1.MachineClass{ - Name: sz, - Capabilities: &irimachinev1alpha1.MachineClassCapabilities{ - CpuMillis: cpum, - MemoryBytes: mem, - }, - }, - } - classes[sz] = c - } - if c != nil && m.Status.Reservation.Status == "Available" && m.Status.Health == "Healthy" { - c.Quantity++ - } - } - } - - r := &irimachinev1alpha1.StatusResponse{} - for _, c := range classes { - if c != nil { - log.Debug(ctx, "Machine class", "name", c.MachineClass.Name, "quantity", c.Quantity) - r.MachineClassStatus = append(r.MachineClassStatus, c) - } - } - return r, nil -} - -func (s *GRPCServer) Exec(ctx context.Context, _ *irimachinev1alpha1.ExecRequest) (*irimachinev1alpha1.ExecResponse, error) { - err := status.Errorf(codes.Unimplemented, "Exec() has not been implemented yet") - log.Error(ctx, err) - return nil, err -} - -func internalError(ctx context.Context, err error) error { - err = status.Errorf(codes.Internal, "%s", err) - log.Error(ctx, err) - return err -} - -//nolint:unparam -func overlayOntoPrefixed(prefix string, overlay, prefixed map[string]string) (map[string]string, bool) { - mod := false - - for k, v := range overlay { - pk := fmt.Sprintf("%s%s", prefix, k) - vv, ok := prefixed[pk] - if !ok || vv != v { - if prefixed == nil { - prefixed = make(map[string]string) - } - prefixed[pk] = v - mod = true - } - } - - lenp := len(prefix) - for pk := range prefixed { - if !strings.HasPrefix(pk, prefix) { - continue - } - k := pk[lenp:] - _, ok := overlay[k] - if !ok { - delete(prefixed, pk) - mod = true - } - } - - return prefixed, mod -} - -func extractFromPrefixed(prefix string, prefixed map[string]string) map[string]string { - var extracted map[string]string - lenp := len(prefix) - for pk, v := range prefixed { - if !strings.HasPrefix(pk, prefix) { - continue - } - if extracted == nil { - extracted = make(map[string]string) - } - extracted[pk[lenp:]] = v - } - return extracted -} - -func kMetaToMeta(meta *metav1.ObjectMeta) *irimetav1alpha1.ObjectMetadata { - iriMeta := &irimetav1alpha1.ObjectMetadata{ - Id: meta.Name, - Annotations: extractFromPrefixed("iri-", meta.Annotations), - Labels: extractFromPrefixed("iri-", meta.Labels), - Generation: meta.Generation, - CreatedAt: meta.CreationTimestamp.Unix(), - } - if meta.DeletionTimestamp != nil { - iriMeta.DeletedAt = meta.DeletionTimestamp.Unix() - } - return iriMeta -}