diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 1bcc643c..ff167396 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -7,7 +7,7 @@ on: env: CGO_ENABLED: 0 - GO_VERSION: '1.23' + GO_VERSION: '1.24' REGISTRY: ghcr.io # github.repository as / IMAGE_NAME: ${{ github.repository }} diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index b4669f93..04546e19 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -7,7 +7,7 @@ on: env: REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }} - GO_VERSION: '1.23' + GO_VERSION: '1.24' jobs: manager-image: diff --git a/.golangci.yml b/.golangci.yml index cfe4df8b..c2ac49ba 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,23 +1,21 @@ -# List for enabled linters can be generated for updates using the following command. -# golangci-lint linters | grep -E '^\S+:' | cut -d: -f1 | sort | sed 's/^/ - /g' | grep -v -E "($(grep '^ disable:' -A 100 .golangci.yml | grep -E ' - \S+$' | awk '{print $2}' | tr \\n '|' | sed 's/|$//g'))" +version: "2" +run: + allow-parallel-runners: true linters: enable: - asciicheck - bodyclose + - copyloopvar - cyclop - #- depguard - dogsled - dupl - durationcheck - - errcheck + - err113 - errorlint - exhaustive - # - exhaustivestruct - - copyloopvar - forbidigo - forcetypeassert - funlen - # - gci - gochecknoglobals - gochecknoinits - gocognit @@ -25,22 +23,13 @@ linters: - gocritic - gocyclo - godot - # - godox - - err113 - - gofmt - - gofumpt - goheader - - goimports - gomodguard - goprintffuncname - gosec - - gosimple - importas - - ineffassign - # - interfacer - lll - makezero - # - maligned - misspell - nakedret - nestif @@ -53,124 +42,102 @@ linters: - predeclared - revive - rowserrcheck - # - scopelint - sqlclosecheck - staticcheck - - stylecheck - testpackage - thelper - tparallel - - typecheck - unconvert - unparam - - unused - wastedassign - whitespace - wrapcheck - - wsl - -output: - sort-results: true - + - wsl_v5 + settings: + exhaustive: + default-signifies-exhaustive: true + gomoddirectives: + replace-allow-list: + - sigs.k8s.io/cluster-api + replace-local: false + exclude-forbidden: false + retract-allow-no-explanation: false + importas: + alias: + - pkg: k8s.io/api/core/v1 + alias: corev1 + - pkg: k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1 + alias: apiextensionsv1 + - pkg: k8s.io/apimachinery/pkg/apis/meta/v1 + alias: metav1 + - pkg: k8s.io/apimachinery/pkg/api/errors + alias: apierrors + - pkg: k8s.io/apimachinery/pkg/util/errors + alias: kerrors + - pkg: sigs.k8s.io/controller-runtime + alias: ctrl + no-unaliased: true + nolintlint: + require-explanation: false + require-specific: true + allow-unused: false + staticcheck: + checks: + - all + tagliatelle: + case: + rules: + json: goCamel + unused: + field-writes-are-uses: true + lll: + # Max line length, lines longer will be reported. + # '\t' is counted as 1 character by default, and can be changed with the tab-width option. + # Default: 120. + line-length: 160 + exclusions: + generated: lax + rules: + - linters: + - lll + - wsl_v5 + source: '^// \+kubebuilder:' + - linters: + - lll + path: controller/*/(.+)_test.go + paths: + - zz_generated.*\.go$ + - .*conversion.*\.go$ + - third_party$ + - builtin$ + - examples$ issues: - exclude-use-default: false - max-same-issues: 0 max-issues-per-linter: 0 - exclude-rules: - # Ignore long kubebuilder lines as there is no way to break them down. - - linters: - - lll - - wsl - source: "^// \\+kubebuilder:" - - linters: - - lll - path: "controller/*/(.+)_test.go" - exclude-files: - - "zz_generated.*\\.go$" - - ".*conversion.*\\.go$" - -linters-settings: - importas: - no-unaliased: true - alias: - # Kubernetes - - pkg: k8s.io/api/core/v1 - alias: corev1 - - pkg: k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1 - alias: apiextensionsv1 - - pkg: k8s.io/apimachinery/pkg/apis/meta/v1 - alias: metav1 - - pkg: k8s.io/apimachinery/pkg/api/errors - alias: apierrors - - pkg: k8s.io/apimachinery/pkg/util/errors - alias: kerrors - # Controller Runtime - - pkg: sigs.k8s.io/controller-runtime - alias: ctrl - gosimple: - checks: ["all"] - staticcheck: - checks: ["all"] - stylecheck: - checks: ["all"] - unused: - # Mark all struct fields that have been written to as used. - # Default: true - field-writes-are-uses: true - tagliatelle: - case: - # use-field-name: true - rules: - json: goCamel - gomoddirectives: - # Allow local `replace` directives. Default is false. - replace-local: false - # List of allowed `replace` directives. Default is empty. - replace-allow-list: - - sigs.k8s.io/cluster-api - # Allow to not explain why the version has been retracted in the `retract` directives. Default is false. - retract-allow-no-explanation: false - # Forbid the use of the `exclude` directives. Default is false. - exclude-forbidden: false - gci: - # Section configuration to compare against. - # Section names are case-insensitive and may contain parameters in (). - # The default order of sections is `standard > default > custom > blank > dot > alias > localmodule`, - # If `custom-order` is `true`, it follows the order of `sections` option. - # Default: ["standard", "default"] - sections: - - standard # Standard section: captures all standard packages. - - default # Default section: contains all imports that could not be matched to another section type. - - prefix(github.com/tinkerbell/cluster-api-provider-tinkerbell) # Custom section: groups all imports with the specified Prefix. - - blank # Blank section: contains all blank imports. This section is not present unless explicitly enabled. - - dot # Dot section: contains all dot imports. This section is not present unless explicitly enabled. - - alias # Alias section: contains all alias imports. This section is not present unless explicitly enabled. - - localmodule # Local module section: contains all local packages. This section is not present unless explicitly enabled. - # Skip generated files. - # Default: true - skip-generated: false - # Enable custom order of sections. - # If `true`, make the section order the same as the order of `sections`. - # Default: false - custom-order: true - goimports: - # put imports beginning with prefix after 3rd-party packages; - # it's a comma-separated list of prefixes - local-prefixes: github.com/tinkerbell/cluster-api-provider-tinkerbell - nolintlint: - # Enable to ensure that nolint directives are all used. Default is true. - allow-unused: false - # Disable to ensure that nolint directives don't have a leading space. Default is true. - allow-leading-space: true - # Exclude following linters from requiring an explanation. Default is []. - allow-no-explanation: [] - # Enable to require an explanation of nonzero length after each nolint directive. Default is false. - require-explanation: false - # Enable to require nolint directives to mention the specific linter being suppressed. Default is false. - require-specific: true - exhaustive: - default-signifies-exhaustive: true - -run: - timeout: 10m - allow-parallel-runners: true \ No newline at end of file + max-same-issues: 0 +formatters: + enable: + - gofmt + - gofumpt + - goimports + settings: + gci: + sections: + - standard + - default + - prefix(github.com/tinkerbell/cluster-api-provider-tinkerbell) + - blank + - dot + - alias + - localmodule + custom-order: true + goimports: + local-prefixes: + - github.com/tinkerbell/cluster-api-provider-tinkerbell + exclusions: + generated: lax + paths: + - zz_generated.*\.go$ + - .*conversion.*\.go$ + - third_party$ + - builtin$ + - examples$ diff --git a/Dockerfile b/Dockerfile index 890eb987..5898c166 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,7 +13,7 @@ # limitations under the License. # Build the manager binary -ARG GOVER=1.23 +ARG GOVER=1.24 FROM golang:${GOVER} AS builder WORKDIR /workspace @@ -35,9 +35,7 @@ COPY ./ ./ # Build ARG ARCH ARG LDFLAGS -RUN CGO_ENABLED=0 GOOS=linux GOARCH=${ARCH} \ - go build -a -ldflags "${LDFLAGS} -extldflags '-static'" \ - -o manager . +RUN CGO_ENABLED=0 GOOS=linux GOARCH=${ARCH} go build -a -ldflags "${LDFLAGS} -extldflags '-static'" -o manager . # Use distroless as minimal base image to package the manager binary # Refer to https://github.com/GoogleContainerTools/distroless for more details diff --git a/Makefile b/Makefile index d85e46c7..138216af 100644 --- a/Makefile +++ b/Makefile @@ -49,20 +49,20 @@ BIN_DIR := $(abspath $(ROOT_DIR)/bin) GO_INSTALL = ./scripts/go_install.sh # Binaries. -CONTROLLER_GEN := go run sigs.k8s.io/controller-tools/cmd/controller-gen@v0.16.2 +CONTROLLER_GEN := go run sigs.k8s.io/controller-tools/cmd/controller-gen@v0.18.0 -GOLANGCI_LINT_VER := v1.63.4 +GOLANGCI_LINT_VER := v2.3.0 GOLANGCI_LINT_BIN := golangci-lint GOLANGCI_LINT := $(TOOLS_BIN_DIR)/$(GOLANGCI_LINT_BIN)-$(GOLANGCI_LINT_VER) KUSTOMIZE_BIN := kustomize KUSTOMIZE := $(TOOLS_BIN_DIR)/$(KUSTOMIZE_BIN) -KUBECTL_VER := v1.31.0 +KUBECTL_VER := v1.33.0 KUBECTL_BIN := kubectl KUBECTL := $(TOOLS_BIN_DIR)/$(KUBECTL_BIN)-$(KUBECTL_VER) -KIND_VER := v0.24.0 +KIND_VER := v0.29.0 KIND_BIN := kind KIND := $(TOOLS_BIN_DIR)/$(KIND_BIN)-$(KIND_VER) @@ -107,7 +107,7 @@ endif # Build time versioning details. LDFLAGS := $(shell hack/version.sh) -GOLANG_VERSION := 1.23 +GOLANG_VERSION := 1.24 ## -------------------------------------- ## Help @@ -166,7 +166,7 @@ $(GOLANGCI_LINT): LINTERS += golangci-lint-lint golangci-lint-lint: $(GOLANGCI_LINT) - find . -name go.mod -execdir "$(GOLANGCI_LINT)" run -c "$(GOLANGCI_LINT_CONFIG)" \; + find . -name go.mod -execdir sh -c '"$(GOLANGCI_LINT)" run -c "$(GOLANGCI_LINT_CONFIG)"' '{}' '+' FIXERS += golangci-lint-fix golangci-lint-fix: $(GOLANGCI_LINT) diff --git a/README.md b/README.md index b24ccd1d..dd8b5294 100644 --- a/README.md +++ b/README.md @@ -7,11 +7,11 @@ -Kubernetes-native declarative infrastructure for Kubernetes clusters on Tinkerbell. +Kubernetes-native declarative infrastructure for Kubernetes clusters using Tinkerbell. ## What is the Cluster API Provider Tinkerbell -The [Cluster API][cluster_api] brings declarative, Kubernetes-style APIs to Kubernetes +The [Cluster API](https://cluster-api.sigs.k8s.io) brings declarative, Kubernetes-style APIs to Kubernetes cluster creation, configuration and management. The API itself is shared across multiple cloud providers allowing for true hybrid @@ -19,28 +19,7 @@ deployments of Kubernetes, both on-premises and off. ## Quick Start -See the [Quick Start](docs/QUICK-START.md) - -## Compatibility with Cluster API and Kubernetes Versions - -This provider's versions are compatible with the following versions of Cluster API: - -| | v1beta1 (v1.2) | v1beta1 (v1.6) | -| ---------------------------------- | -------------- | -------------- | -| Tinkerbell Provider v1beta1 (v0.4) | ✓ | | -| Tinkerbell Provider v1beta1 (v0.5) | | ✓ | - -This provider's versions are able to install and manage the following versions of Kubernetes: - -| | v1.20 | v1.21 | v1.22 | v1.23 | v1.24 | v1.25 | v1.26 | v1.27 | v1.28 | v1.29 | -| ----------------------------------- | ----- | ----- | ----- | ----- | ----- | ----- | ----- | ----- | ----- | ----- | -| Tinkerbell Provider v1beta1 (v0.4) | ✓ | ✓ | ✓ | ✓ | | | | | | | -| Tinkerbell Provider v1beta1 (v0.5) | | | | | | ✓ | ✓ | ✓ | ✓ | ✓ | - -Each version of Cluster API for Tinkerbell will attempt to support all community supported Kubernetes versions during it's maintenance cycle; e.g., Cluster API for Tinkerbell `v0.5` supports Kubernetes 1.25, 1.26, 1.27, 1.28, 1.29. - -**NOTE:** As the versioning for this project is tied to the versioning of Cluster API, future modifications to this -policy may be made to more closely align with other providers in the Cluster API ecosystem. See https://cluster-api.sigs.k8s.io/reference/versions +See the [Quick Start](docs/QUICK-START.md). ## Kubernetes versions with published Images @@ -48,11 +27,7 @@ Pre-built images are pushed to the [GitHub Container Registry](https://github.co ## Current state -Currently, it is possible to bootstrap both single instance and multiple instance Control Plane -workload clusters using hardware managed by Tinkerbell. +See the [release docs](https://github.com/tinkerbell/cluster-api-provider-tinkerbell/releases) for each version to find details on features and CAPI compatibility. See [docs/README.md](docs/README.md) for more information on setting up a development environment. - - -[cluster_api]: https://cluster-api.sigs.k8s.io diff --git a/api/v1beta1/tinkerbellcluster_webhook.go b/api/v1beta1/tinkerbellcluster_webhook.go index cd43631f..57ecd4f3 100644 --- a/api/v1beta1/tinkerbellcluster_webhook.go +++ b/api/v1beta1/tinkerbellcluster_webhook.go @@ -17,10 +17,12 @@ limitations under the License. package v1beta1 import ( + "context" "strings" "k8s.io/apimachinery/pkg/runtime" ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/webhook" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" ) @@ -29,28 +31,31 @@ const ( defaultUbuntuVersion = "20.04" ) -var _ admission.Validator = &TinkerbellCluster{} +var ( + _ webhook.CustomValidator = &TinkerbellCluster{} + _ webhook.CustomDefaulter = &TinkerbellCluster{} +) // SetupWebhookWithManager sets up and registers the webhook with the manager. func (c *TinkerbellCluster) SetupWebhookWithManager(mgr ctrl.Manager) error { - return ctrl.NewWebhookManagedBy(mgr).For(c).Complete() //nolint:wrapcheck + return ctrl.NewWebhookManagedBy(mgr).WithDefaulter(c).WithValidator(c).For(c).Complete() //nolint:wrapcheck } // +kubebuilder:webhook:verbs=create;update,path=/validate-infrastructure-cluster-x-k8s-io-v1beta1-tinkerbellcluster,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=infrastructure.cluster.x-k8s.io,resources=tinkerbellclusters,versions=v1beta1,name=validation.tinkerbellcluster.infrastructure.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1;v1beta1 // +kubebuilder:webhook:verbs=create;update,path=/mutate-infrastructure-cluster-x-k8s-io-v1beta1-tinkerbellcluster,mutating=true,failurePolicy=fail,matchPolicy=Equivalent,groups=infrastructure.cluster.x-k8s.io,resources=tinkerbellclusters,versions=v1beta1,name=default.tinkerbellcluster.infrastructure.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1;v1beta1 // ValidateCreate implements webhook.Validator so a webhook will be registered for the type. -func (c *TinkerbellCluster) ValidateCreate() (admission.Warnings, error) { +func (c *TinkerbellCluster) ValidateCreate(context.Context, runtime.Object) (admission.Warnings, error) { return nil, nil } // ValidateUpdate implements webhook.Validator so a webhook will be registered for the type. -func (c *TinkerbellCluster) ValidateUpdate(_ runtime.Object) (admission.Warnings, error) { +func (c *TinkerbellCluster) ValidateUpdate(context.Context, runtime.Object, runtime.Object) (admission.Warnings, error) { return nil, nil } // ValidateDelete implements webhook.Validator so a webhook will be registered for the type. -func (c *TinkerbellCluster) ValidateDelete() (admission.Warnings, error) { +func (c *TinkerbellCluster) ValidateDelete(context.Context, runtime.Object) (admission.Warnings, error) { return nil, nil } @@ -63,7 +68,7 @@ func defaultVersionForOSDistro(distro string) string { } // Default implements webhookutil.defaulter so a webhook will be registered for the type. -func (c *TinkerbellCluster) Default() { +func (c *TinkerbellCluster) Default(context.Context, runtime.Object) error { if c.Spec.ImageLookupFormat == "" { c.Spec.ImageLookupFormat = "{{.BaseRegistry}}/{{.OSDistro}}-{{.OSVersion}}:{{.KubernetesVersion}}.gz" } @@ -71,4 +76,6 @@ func (c *TinkerbellCluster) Default() { if c.Spec.ImageLookupOSVersion == "" { c.Spec.ImageLookupOSVersion = defaultVersionForOSDistro(c.Spec.ImageLookupOSDistro) } + + return nil } diff --git a/api/v1beta1/tinkerbellmachine_types.go b/api/v1beta1/tinkerbellmachine_types.go index e84ce0d8..15eb2576 100644 --- a/api/v1beta1/tinkerbellmachine_types.go +++ b/api/v1beta1/tinkerbellmachine_types.go @@ -19,7 +19,6 @@ package v1beta1 import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - capierrors "sigs.k8s.io/cluster-api/errors" ) const ( @@ -101,9 +100,9 @@ type BootOptions struct { ISOURL string `json:"isoURL,omitempty"` // BootMode is the type of booting that will be done. - // Must be one of "none", "netboot", or "iso". + // Must be one of "none", "netboot", or "isoboot". // +optional - // +kubebuilder:validation:Enum=none;netboot;iso + // +kubebuilder:validation:Enum=none;netboot;isoboot BootMode BootMode `json:"bootMode,omitempty"` } @@ -156,7 +155,7 @@ type TinkerbellMachineStatus struct { // can be added as events to the Machine object and/or logged in the // controller's output. // +optional - ErrorReason *capierrors.MachineStatusError `json:"errorReason,omitempty"` + ErrorReason *string `json:"errorReason,omitempty"` // ErrorMessage will be set in the event that there is a terminal problem // reconciling the Machine and will contain a more verbose string suitable diff --git a/api/v1beta1/tinkerbellmachine_webhook.go b/api/v1beta1/tinkerbellmachine_webhook.go index 3d490c53..c3106d27 100644 --- a/api/v1beta1/tinkerbellmachine_webhook.go +++ b/api/v1beta1/tinkerbellmachine_webhook.go @@ -17,47 +17,50 @@ limitations under the License. package v1beta1 import ( + "context" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/validation/field" ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/webhook" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" ) -var _ admission.Validator = &TinkerbellMachine{} +var _ webhook.CustomValidator = &TinkerbellMachine{} // SetupWebhookWithManager sets up and registers the webhook with the manager. func (m *TinkerbellMachine) SetupWebhookWithManager(mgr ctrl.Manager) error { - return ctrl.NewWebhookManagedBy(mgr).For(m).Complete() //nolint:wrapcheck + return ctrl.NewWebhookManagedBy(mgr).WithValidator(m).For(m).Complete() //nolint:wrapcheck } // +kubebuilder:webhook:verbs=create;update,path=/validate-infrastructure-cluster-x-k8s-io-v1beta1-tinkerbellmachine,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=infrastructure.cluster.x-k8s.io,resources=tinkerbellmachines,versions=v1beta1,name=validation.tinkerbellmachine.infrastructure.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1;v1beta1 // ValidateCreate implements webhook.Validator so a webhook will be registered for the type. -func (m *TinkerbellMachine) ValidateCreate() (admission.Warnings, error) { +func (m *TinkerbellMachine) ValidateCreate(context.Context, runtime.Object) (admission.Warnings, error) { allErrs := m.validateSpec() return nil, aggregateObjErrors(m.GroupVersionKind().GroupKind(), m.Name, allErrs) } // ValidateUpdate implements webhook.Validator so a webhook will be registered for the type. -func (m *TinkerbellMachine) ValidateUpdate(oldRaw runtime.Object) (admission.Warnings, error) { - allErrs := m.validateSpec() - +func (m *TinkerbellMachine) ValidateUpdate(_ context.Context, oldRaw runtime.Object, newRaw runtime.Object) (admission.Warnings, error) { old, _ := oldRaw.(*TinkerbellMachine) + newTM, _ := newRaw.(*TinkerbellMachine) + allErrs := newTM.validateSpec() - if old.Spec.HardwareName != "" && m.Spec.HardwareName != old.Spec.HardwareName { + if old.Spec.HardwareName != "" && newTM.Spec.HardwareName != old.Spec.HardwareName { allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "hardwareName"), "is immutable once set")) } - if old.Spec.ProviderID != "" && m.Spec.ProviderID != old.Spec.ProviderID { + if old.Spec.ProviderID != "" && newTM.Spec.ProviderID != old.Spec.ProviderID { allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "providerID"), "is immutable once set")) } - return nil, aggregateObjErrors(m.GroupVersionKind().GroupKind(), m.Name, allErrs) + return nil, aggregateObjErrors(newTM.GroupVersionKind().GroupKind(), newTM.Name, allErrs) } // ValidateDelete implements webhook.Validator so a webhook will be registered for the type. -func (m *TinkerbellMachine) ValidateDelete() (admission.Warnings, error) { +func (m *TinkerbellMachine) ValidateDelete(context.Context, runtime.Object) (admission.Warnings, error) { return nil, nil } diff --git a/api/v1beta1/tinkerbellmachine_webhook_test.go b/api/v1beta1/tinkerbellmachine_webhook_test.go index af1b89c7..b69fb255 100644 --- a/api/v1beta1/tinkerbellmachine_webhook_test.go +++ b/api/v1beta1/tinkerbellmachine_webhook_test.go @@ -17,6 +17,7 @@ limitations under the License. package v1beta1_test import ( + "context" "testing" . "github.com/onsi/gomega" //nolint:revive // one day we will remove gomega @@ -81,9 +82,9 @@ func Test_valid_tinkerbell_machine(t *testing.T) { }, }, } { - _, err := machine.ValidateCreate() + _, err := machine.ValidateCreate(context.Background(), nil) g.Expect(err).ToNot(HaveOccurred()) - _, err = machine.ValidateUpdate(existingValidMachine) + _, err = machine.ValidateUpdate(context.Background(), existingValidMachine, &machine) g.Expect(err).ToNot(HaveOccurred()) } } @@ -129,9 +130,9 @@ func Test_invalid_tinkerbell_machine(t *testing.T) { }, }, } { - _, err := machine.ValidateCreate() + _, err := machine.ValidateCreate(context.Background(), nil) g.Expect(err).To(HaveOccurred()) - _, err = machine.ValidateUpdate(existingValidMachine) + _, err = machine.ValidateUpdate(context.Background(), existingValidMachine, &machine) g.Expect(err).To(HaveOccurred()) } } diff --git a/api/v1beta1/tinkerbellmachinetemplate_webhook.go b/api/v1beta1/tinkerbellmachinetemplate_webhook.go index 80d7e2e6..0d545a9c 100644 --- a/api/v1beta1/tinkerbellmachinetemplate_webhook.go +++ b/api/v1beta1/tinkerbellmachinetemplate_webhook.go @@ -17,29 +17,33 @@ limitations under the License. package v1beta1 import ( + "context" "reflect" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/validation/field" ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/webhook" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" ) -var _ admission.Validator = &TinkerbellMachineTemplate{} +var _ webhook.CustomValidator = &TinkerbellMachineTemplate{} // SetupWebhookWithManager sets up and registers the webhook with the manager. func (m *TinkerbellMachineTemplate) SetupWebhookWithManager(mgr ctrl.Manager) error { - return ctrl.NewWebhookManagedBy(mgr).For(m).Complete() //nolint:wrapcheck + return ctrl.NewWebhookManagedBy(mgr).WithValidator(m).For(m).Complete() //nolint:wrapcheck } // +kubebuilder:webhook:verbs=create;update,path=/validate-infrastructure-cluster-x-k8s-io-v1beta1-tinkerbellmachinetemplate,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=infrastructure.cluster.x-k8s.io,resources=tinkerbellmachinetemplates,versions=v1beta1,name=validation.tinkerbellmachinetemplate.infrastructure.x-k8s.io,sideEffects=None,admissionReviewVersions=v1;v1beta1 // ValidateCreate implements webhook.Validator so a webhook will be registered for the type. -func (m *TinkerbellMachineTemplate) ValidateCreate() (admission.Warnings, error) { +func (m *TinkerbellMachineTemplate) ValidateCreate(_ context.Context, obj runtime.Object) (admission.Warnings, error) { var allErrs field.ErrorList - spec := m.Spec.Template.Spec + tmt, _ := obj.(*TinkerbellMachineTemplate) + + spec := tmt.Spec.Template.Spec fieldBasePath := field.NewPath("spec", "template", "spec") if spec.ProviderID != "" { @@ -50,14 +54,15 @@ func (m *TinkerbellMachineTemplate) ValidateCreate() (admission.Warnings, error) allErrs = append(allErrs, field.Forbidden(fieldBasePath.Child("hardwareName"), "cannot be set in templates")) } - return nil, aggregateObjErrors(m.GroupVersionKind().GroupKind(), m.Name, allErrs) + return nil, aggregateObjErrors(tmt.GroupVersionKind().GroupKind(), tmt.Name, allErrs) } // ValidateUpdate implements webhook.Validator so a webhook will be registered for the type. -func (m *TinkerbellMachineTemplate) ValidateUpdate(old runtime.Object) (admission.Warnings, error) { - oldTinkerbellMachineTemplate, _ := old.(*TinkerbellMachineTemplate) +func (m *TinkerbellMachineTemplate) ValidateUpdate(_ context.Context, old runtime.Object, newObj runtime.Object) (admission.Warnings, error) { + oldTMT, _ := old.(*TinkerbellMachineTemplate) + newTMT, _ := newObj.(*TinkerbellMachineTemplate) - if !reflect.DeepEqual(m.Spec, oldTinkerbellMachineTemplate.Spec) { + if !reflect.DeepEqual(newTMT.Spec, oldTMT.Spec) { return nil, apierrors.NewBadRequest("TinkerbellMachineTemplate.Spec is immutable") } @@ -65,6 +70,6 @@ func (m *TinkerbellMachineTemplate) ValidateUpdate(old runtime.Object) (admissio } // ValidateDelete implements webhook.Validator so a webhook will be registered for the type. -func (m *TinkerbellMachineTemplate) ValidateDelete() (admission.Warnings, error) { +func (m *TinkerbellMachineTemplate) ValidateDelete(context.Context, runtime.Object) (admission.Warnings, error) { return nil, nil } diff --git a/api/v1beta1/types.go b/api/v1beta1/types.go index 95525575..abe06e7c 100644 --- a/api/v1beta1/types.go +++ b/api/v1beta1/types.go @@ -19,7 +19,7 @@ package v1beta1 // TinkerbellResourceStatus describes the status of a Tinkerbell resource. type TinkerbellResourceStatus int -//nolint:gomnd,gochecknoglobals +//nolint:gochecknoglobals,revive var ( TinkerbellResourceStatusPending = TinkerbellResourceStatus(0) TinkerbellResourceStatusRunning = TinkerbellResourceStatus(1) diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index 06b8f184..171ab132 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -23,7 +23,6 @@ package v1beta1 import ( "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" - "sigs.k8s.io/cluster-api/errors" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -271,7 +270,7 @@ func (in *TinkerbellMachineStatus) DeepCopyInto(out *TinkerbellMachineStatus) { } if in.ErrorReason != nil { in, out := &in.ErrorReason, &out.ErrorReason - *out = new(errors.MachineStatusError) + *out = new(string) **out = **in } if in.ErrorMessage != nil { diff --git a/config/certmanager/certificate.yaml b/config/certmanager/certificate.yaml index d903877f..d44a92e0 100644 --- a/config/certmanager/certificate.yaml +++ b/config/certmanager/certificate.yaml @@ -14,11 +14,11 @@ metadata: name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml namespace: system spec: - # $(SERVICE_NAME) and $(SERVICE_NAMESPACE) will be substituted by kustomize + # SERVICE_NAME_PLACEHOLDER and SERVICE_NAMESPACE_PLACEHOLDER will be substituted by kustomize dnsNames: - - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc - - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc.cluster.local + - SERVICE_NAME_PLACEHOLDER.SERVICE_NAMESPACE_PLACEHOLDER.svc + - SERVICE_NAME_PLACEHOLDER.SERVICE_NAMESPACE_PLACEHOLDER.svc.cluster.local issuerRef: kind: Issuer name: selfsigned-issuer - secretName: $(SERVICE_NAME)-cert # this secret will not be prefixed, since it's not managed by kustomize + secretName: SERVICE_NAME_PLACEHOLDER-cert # this secret will not be prefixed, since it's not managed by kustomize diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_tinkerbellclusters.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_tinkerbellclusters.yaml index 2a5794b4..ffba1a2f 100644 --- a/config/crd/bases/infrastructure.cluster.x-k8s.io_tinkerbellclusters.yaml +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_tinkerbellclusters.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.2 + controller-gen.kubebuilder.io/version: v0.18.0 name: tinkerbellclusters.infrastructure.cluster.x-k8s.io spec: group: infrastructure.cluster.x-k8s.io @@ -58,10 +58,11 @@ spec: for more details. properties: host: - description: The hostname on which the API server is serving. + description: host is the hostname on which the API server is serving. + maxLength: 512 type: string port: - description: The port on which the API server is serving. + description: port is the port on which the API server is serving. format: int32 type: integer required: diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_tinkerbellmachines.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_tinkerbellmachines.yaml index 80688288..691f320b 100644 --- a/config/crd/bases/infrastructure.cluster.x-k8s.io_tinkerbellmachines.yaml +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_tinkerbellmachines.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.2 + controller-gen.kubebuilder.io/version: v0.18.0 name: tinkerbellmachines.infrastructure.cluster.x-k8s.io spec: group: infrastructure.cluster.x-k8s.io @@ -68,11 +68,11 @@ spec: bootMode: description: |- BootMode is the type of booting that will be done. - Must be one of "none", "netboot", or "iso". + Must be one of "none", "netboot", or "isoboot". enum: - none - netboot - - iso + - isoboot type: string isoURL: description: |- diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_tinkerbellmachinetemplates.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_tinkerbellmachinetemplates.yaml index 182f9399..2e6a1e0b 100644 --- a/config/crd/bases/infrastructure.cluster.x-k8s.io_tinkerbellmachinetemplates.yaml +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_tinkerbellmachinetemplates.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.2 + controller-gen.kubebuilder.io/version: v0.18.0 name: tinkerbellmachinetemplates.infrastructure.cluster.x-k8s.io spec: group: infrastructure.cluster.x-k8s.io @@ -58,11 +58,11 @@ spec: bootMode: description: |- BootMode is the type of booting that will be done. - Must be one of "none", "netboot", or "iso". + Must be one of "none", "netboot", or "isoboot". enum: - none - netboot - - iso + - isoboot type: string isoURL: description: |- diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index 6d2e594e..a24f10ba 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -1,29 +1,33 @@ # This kustomization.yaml is not intended to be run by itself, # since it depends on service name and namespace that are out of this kustomize package. # It should be run by config/default -commonLabels: - cluster.x-k8s.io/v1beta1: v1beta1 resources: - bases/infrastructure.cluster.x-k8s.io_tinkerbellclusters.yaml - bases/infrastructure.cluster.x-k8s.io_tinkerbellmachines.yaml - bases/infrastructure.cluster.x-k8s.io_tinkerbellmachinetemplates.yaml # +kubebuilder:scaffold:crdkustomizeresource -patchesStrategicMerge: # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. # patches here are for enabling the conversion webhook for each CRD -- patches/webhook_in_tinkerbellclusters.yaml -- patches/webhook_in_tinkerbellmachines.yaml -- patches/webhook_in_tinkerbellmachinetemplates.yaml # +kubebuilder:scaffold:crdkustomizewebhookpatch # [CERTMANAGER] To enable webhook, uncomment all the sections with [CERTMANAGER] prefix. # patches here are for enabling the CA injection for each CRD -- patches/cainjection_in_tinkerbellclusters.yaml -- patches/cainjection_in_tinkerbellmachines.yaml -- patches/cainjection_in_tinkerbellmachinetemplates.yaml # +kubebuilder:scaffold:crdkustomizecainjectionpatch # the following config is for teaching kustomize how to do kustomization for CRDs. configurations: - kustomizeconfig.yaml +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +labels: +- includeSelectors: true + pairs: + cluster.x-k8s.io/v1beta1: v1beta1 +patches: +- path: patches/webhook_in_tinkerbellclusters.yaml +- path: patches/webhook_in_tinkerbellmachines.yaml +- path: patches/webhook_in_tinkerbellmachinetemplates.yaml +- path: patches/cainjection_in_tinkerbellclusters.yaml +- path: patches/cainjection_in_tinkerbellmachines.yaml +- path: patches/cainjection_in_tinkerbellmachinetemplates.yaml diff --git a/config/default/kustomization.yaml b/config/default/kustomization.yaml index ff5ca84d..37200154 100644 --- a/config/default/kustomization.yaml +++ b/config/default/kustomization.yaml @@ -7,51 +7,156 @@ namePrefix: capt- namespace: capt-system # Labels to add to all resources and selectors. -commonLabels: - cluster.x-k8s.io/provider: infrastructure-tinkerbell resources: - namespace.yaml - -bases: - ../crd - ../rbac - ../manager - ../webhook - ../certmanager -patchesStrategicMerge: - - manager_image_patch.yaml - - manager_webhook_patch.yaml - - webhookcainjection_patch.yaml +configurations: + - kustomizeconfig.yaml +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +labels: + - includeSelectors: true + pairs: + cluster.x-k8s.io/provider: infrastructure-tinkerbell +patches: + - path: manager_image_patch.yaml + - path: manager_webhook_patch.yaml + - path: webhookcainjection_patch1.yaml + - path: webhookcainjection_patch2.yaml -vars: - - name: CERTIFICATE_NAMESPACE # namespace of the certificate CR - objref: +replacements: + - source: + kind: Certificate + name: serving-cert + fieldPath: metadata.name # Use the certificate's name + targets: + - select: + kind: MutatingWebhookConfiguration + fieldPaths: + - metadata.annotations.[cert-manager.io/inject-ca-from] + options: + delimiter: / + index: 1 + - select: + kind: ValidatingWebhookConfiguration + fieldPaths: + - metadata.annotations.[cert-manager.io/inject-ca-from] + options: + delimiter: / + index: 1 + - source: + fieldPath: metadata.namespace kind: Certificate - group: cert-manager.io - version: v1 - name: serving-cert # this name should match the one in certificate.yaml - fieldref: - fieldpath: metadata.namespace - - name: CERTIFICATE_NAME - objref: + name: serving-cert + targets: + - fieldPaths: + - metadata.annotations.[cert-manager.io/inject-ca-from] + options: + delimiter: / + index: 0 + select: + kind: MutatingWebhookConfiguration + name: mutating-webhook-configuration + - fieldPaths: + - metadata.annotations.[cert-manager.io/inject-ca-from] + options: + delimiter: / + index: 0 + select: + kind: ValidatingWebhookConfiguration + name: validating-webhook-configuration + - source: kind: Certificate - group: cert-manager.io - version: v1 - name: serving-cert # this name should match the one in certificate.yaml - - name: SERVICE_NAMESPACE # namespace of the service - objref: + name: serving-cert + targets: + - fieldPaths: + - metadata.annotations.[cert-manager.io/inject-ca-from] + options: + delimiter: / + index: 1 + select: + kind: ValidatingWebhookConfiguration + name: validating-webhook-configuration + - fieldPaths: + - metadata.annotations.[cert-manager.io/inject-ca-from] + options: + delimiter: / + index: 1 + select: + kind: ValidatingWebhookConfiguration + name: validating-webhook-configuration + - source: + fieldPath: metadata.namespace kind: Service - version: v1 name: webhook-service - fieldref: - fieldpath: metadata.namespace - - name: SERVICE_NAME - objref: + targets: + - fieldPaths: + - spec.dnsNames.0 + options: + delimiter: . + index: 1 + select: + group: cert-manager.io + kind: Certificate + name: serving-cert + namespace: system + version: v1 + - fieldPaths: + - spec.dnsNames.1 + options: + delimiter: . + index: 1 + select: + group: cert-manager.io + kind: Certificate + name: serving-cert + namespace: system + version: v1 + - source: kind: Service - version: v1 name: webhook-service - -configurations: - - kustomizeconfig.yaml + targets: + - fieldPaths: + - spec.dnsNames.0 + options: + delimiter: . + select: + group: cert-manager.io + kind: Certificate + name: serving-cert + namespace: system + version: v1 + - fieldPaths: + - spec.dnsNames.1 + options: + delimiter: . + select: + group: cert-manager.io + kind: Certificate + name: serving-cert + namespace: system + version: v1 + - fieldPaths: + - spec.secretName + options: + delimiter: "-" + select: + group: cert-manager.io + kind: Certificate + name: serving-cert + namespace: system + version: v1 + - fieldPaths: + - spec.template.spec.volumes.0.secret.secretName + options: + delimiter: "-" + select: + kind: Deployment + name: controller-manager + namespace: system diff --git a/config/default/manager_webhook_patch.yaml b/config/default/manager_webhook_patch.yaml index b387eb0e..88159b68 100644 --- a/config/default/manager_webhook_patch.yaml +++ b/config/default/manager_webhook_patch.yaml @@ -20,4 +20,4 @@ spec: - name: cert secret: defaultMode: 420 - secretName: $(SERVICE_NAME)-cert + secretName: SERVICE_NAME_PLACEHOLDER-cert diff --git a/config/default/webhookcainjection_patch.yaml b/config/default/webhookcainjection_patch.yaml deleted file mode 100644 index 02150e47..00000000 --- a/config/default/webhookcainjection_patch.yaml +++ /dev/null @@ -1,17 +0,0 @@ - -# This patch add annotation to admission webhook config and -# the variables $(CERTIFICATE_NAMESPACE) and $(CERTIFICATE_NAME) will be substituted by kustomize. -# uncomment the following lines to enable mutating webhook -apiVersion: admissionregistration.k8s.io/v1 -kind: MutatingWebhookConfiguration -metadata: - name: mutating-webhook-configuration - annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) ---- -apiVersion: admissionregistration.k8s.io/v1 -kind: ValidatingWebhookConfiguration -metadata: - name: validating-webhook-configuration - annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) diff --git a/config/default/webhookcainjection_patch1.yaml b/config/default/webhookcainjection_patch1.yaml new file mode 100644 index 00000000..0b0d4b09 --- /dev/null +++ b/config/default/webhookcainjection_patch1.yaml @@ -0,0 +1,6 @@ +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: mutating-webhook-configuration + annotations: + cert-manager.io/inject-ca-from: CERTIFICATE_NAMESPACE_PLACEHOLDER/CERTIFICATE_NAME_PLACEHOLDER \ No newline at end of file diff --git a/config/default/webhookcainjection_patch2.yaml b/config/default/webhookcainjection_patch2.yaml new file mode 100644 index 00000000..214eed2e --- /dev/null +++ b/config/default/webhookcainjection_patch2.yaml @@ -0,0 +1,6 @@ +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: validating-webhook-configuration + annotations: + cert-manager.io/inject-ca-from: CERTIFICATE_NAMESPACE_PLACEHOLDER/CERTIFICATE_NAME_PLACEHOLDER diff --git a/config/webhook/kustomization.yaml b/config/webhook/kustomization.yaml index 9cf26134..3334392e 100644 --- a/config/webhook/kustomization.yaml +++ b/config/webhook/kustomization.yaml @@ -4,3 +4,5 @@ resources: configurations: - kustomizeconfig.yaml +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization diff --git a/controller/cluster/tinkerbellcluster.go b/controller/cluster/tinkerbellcluster.go index fa4de764..eddaecb0 100644 --- a/controller/cluster/tinkerbellcluster.go +++ b/controller/cluster/tinkerbellcluster.go @@ -23,6 +23,7 @@ import ( "github.com/go-logr/logr" apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" "sigs.k8s.io/cluster-api/util" @@ -86,8 +87,6 @@ func (tcr *TinkerbellClusterReconciler) validate() error { // If unexpected case occurs, error is returned. // // If some data is not yet available, nil is returned. -// -//nolint:lll func (tcr *TinkerbellClusterReconciler) newReconcileContext(ctx context.Context, namespacedName types.NamespacedName) (*clusterReconcileContext, error) { log := ctrl.LoggerFrom(ctx) @@ -227,7 +226,7 @@ func (tcr *TinkerbellClusterReconciler) Reconcile(ctx context.Context, req ctrl. return ctrl.Result{}, nil } - if !crc.tinkerbellCluster.ObjectMeta.DeletionTimestamp.IsZero() { + if !crc.tinkerbellCluster.DeletionTimestamp.IsZero() { if annotations.HasPaused(crc.tinkerbellCluster) { crc.log.Info("TinkerbellCluster is marked as paused. Won't reconcile deletion") @@ -256,11 +255,7 @@ func (tcr *TinkerbellClusterReconciler) Reconcile(ctx context.Context, req ctrl. } // SetupWithManager configures reconciler with a given manager. -func (tcr *TinkerbellClusterReconciler) SetupWithManager( - ctx context.Context, - mgr ctrl.Manager, - options controller.Options, -) error { +func (tcr *TinkerbellClusterReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Manager, options controller.Options, sm *runtime.Scheme) error { log := ctrl.LoggerFrom(ctx) mapper := util.ClusterToInfrastructureMapFunc( @@ -273,12 +268,12 @@ func (tcr *TinkerbellClusterReconciler) SetupWithManager( builder := ctrl.NewControllerManagedBy(mgr). WithOptions(options). For(&infrastructurev1.TinkerbellCluster{}). - WithEventFilter(predicates.ResourceNotPausedAndHasFilterLabel(log, tcr.WatchFilterValue)). - WithEventFilter(predicates.ResourceIsNotExternallyManaged(log)). + WithEventFilter(predicates.ResourceNotPausedAndHasFilterLabel(sm, log, tcr.WatchFilterValue)). + WithEventFilter(predicates.ResourceIsNotExternallyManaged(sm, log)). Watches( &clusterv1.Cluster{}, handler.EnqueueRequestsFromMapFunc(mapper), - builder.WithPredicates(predicates.ClusterUnpaused(log)), + builder.WithPredicates(predicates.ClusterUnpaused(sm, log)), ) if err := builder.Complete(tcr); err != nil { diff --git a/controller/cluster/tinkerbellcluster_test.go b/controller/cluster/tinkerbellcluster_test.go index 2009cb05..ce31bb3c 100644 --- a/controller/cluster/tinkerbellcluster_test.go +++ b/controller/cluster/tinkerbellcluster_test.go @@ -32,9 +32,10 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/fake" - tinkv1 "github.com/tinkerbell/tink/api/v1alpha1" + tinkv1 "github.com/tinkerbell/tinkerbell/api/v1alpha1/tinkerbell" infrastructurev1 "github.com/tinkerbell/cluster-api-provider-tinkerbell/api/v1beta1" + "github.com/tinkerbell/cluster-api-provider-tinkerbell/controller" "github.com/tinkerbell/cluster-api-provider-tinkerbell/controller/cluster" ) @@ -42,7 +43,7 @@ import ( func unreadyTinkerbellCluster(name, namespace string) *infrastructurev1.TinkerbellCluster { unreadyTinkerbellCluster := validTinkerbellCluster(name, namespace) unreadyTinkerbellCluster.Status.Ready = false - unreadyTinkerbellCluster.ObjectMeta.Finalizers = nil + unreadyTinkerbellCluster.Finalizers = nil unreadyTinkerbellCluster.Spec.ControlPlaneEndpoint.Host = "" unreadyTinkerbellCluster.Spec.ControlPlaneEndpoint.Port = 0 @@ -199,25 +200,25 @@ func Test_Cluster_reconciliation(t *testing.T) { // This is introduced in v1alpha3 of CAPI even though behavior diagram does not reflect it. // This will be automatically requeued when the tinkerbellCluster is unpaused. - t.Run("tinkerbellcluster_is_paused", clusterReconciliationIsNotRequeuedWhenTinkerbellClusterIsPaused) //nolint:paralleltest + t.Run("tinkerbellcluster_is_paused", clusterReconciliationIsNotRequeuedWhenTinkerbellClusterIsPaused) // This is introduced in v1alpha3 of CAPI even though behavior diagram does not reflect it. // Requeue happens through watch of Cluster. - t.Run("cluster_is_paused", clusterReconciliationIsNotRequeuedWhenClusterIsPaused) //nolint:paralleltest + t.Run("cluster_is_paused", clusterReconciliationIsNotRequeuedWhenClusterIsPaused) // From https://cluster-api.sigs.k8s.io/developer/providers/cluster-infrastructure.html#behavior. // This will be automatically requeued when the ownerRef is set. - t.Run("cluster_has_no_owner_set", clusterReconciliationIsNotRequeuedWhenClusterHasNoOwnerSet) //nolint:paralleltest + t.Run("cluster_has_no_owner_set", clusterReconciliationIsNotRequeuedWhenClusterHasNoOwnerSet) // If reconciliation process started, but we cannot find cluster object anymore, it means object has been // removed in the meanwhile. This means there is nothing to do. - t.Run("cluster_object_is_missing", clusterReconciliationIsNotRequeuedWhenClusterObjectIsMissing) //nolint:paralleltest + t.Run("cluster_object_is_missing", clusterReconciliationIsNotRequeuedWhenClusterObjectIsMissing) }) t.Run("fails_when", func(t *testing.T) { t.Parallel() - t.Run("reconciler_has_no_client_set", clusterReconciliationFailsWhenReconcilerHasNoClientSet) //nolint:paralleltest + t.Run("reconciler_has_no_client_set", clusterReconciliationFailsWhenReconcilerHasNoClientSet) }) } @@ -244,7 +245,7 @@ func kubernetesClientWithObjects(t *testing.T, objects []runtime.Object) client. scheme := runtime.NewScheme() - g.Expect(tinkv1.AddToScheme(scheme)).To(Succeed(), "Adding Tinkerbell objects to scheme should succeed") + g.Expect(controller.AddToSchemeTinkerbell(scheme)).To(Succeed(), "Adding Tinkerbell objects to scheme should succeed") g.Expect(infrastructurev1.AddToScheme(scheme)).To(Succeed(), "Adding Tinkerbell CAPI objects to scheme should succeed") g.Expect(clusterv1.AddToScheme(scheme)).To(Succeed(), "Adding CAPI objects to scheme should succeed") g.Expect(corev1.AddToScheme(scheme)).To(Succeed(), "Adding Core V1 objects to scheme should succeed") @@ -329,7 +330,7 @@ func validTinkerbellCluster(name, namespace string) *infrastructurev1.Tinkerbell }, } - tinkCluster.Default() + _ = tinkCluster.Default(context.TODO(), nil) return tinkCluster } @@ -339,7 +340,7 @@ func clusterReconciliationIsNotRequeuedWhenClusterHasNoOwnerSet(t *testing.T) { g := NewWithT(t) unreadyTinkerbellClusterWithoutOwner := unreadyTinkerbellCluster(clusterName, clusterNamespace) - unreadyTinkerbellClusterWithoutOwner.ObjectMeta.OwnerReferences = nil + unreadyTinkerbellClusterWithoutOwner.OwnerReferences = nil objects := []runtime.Object{ validCluster(clusterName, clusterNamespace), @@ -357,7 +358,7 @@ func clusterReconciliationIsNotRequeuedWhenTinkerbellClusterIsPaused(t *testing. g := NewWithT(t) pausedTinkerbellCluster := validTinkerbellCluster(clusterName, clusterNamespace) - pausedTinkerbellCluster.ObjectMeta.Annotations = map[string]string{ + pausedTinkerbellCluster.Annotations = map[string]string{ clusterv1.PausedAnnotation: "true", } diff --git a/controller/controller.go b/controller/controller.go new file mode 100644 index 00000000..15bf1408 --- /dev/null +++ b/controller/controller.go @@ -0,0 +1,35 @@ +// Package controller provides the controller-runtime scheme for Tinkerbell and BMC resources. +package controller + +import ( + "github.com/tinkerbell/tinkerbell/api/v1alpha1/bmc" + "github.com/tinkerbell/tinkerbell/api/v1alpha1/tinkerbell" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +//nolint:gochecknoglobals +var ( + // SchemeBuilderTinkerbell is used to add go types to the GroupVersionKind scheme. + SchemeBuilderTinkerbell = &scheme.Builder{GroupVersion: tinkerbell.GroupVersion} + + // AddToSchemeTinkerbell adds the types in this group-version to the given scheme. + AddToSchemeTinkerbell = SchemeBuilderTinkerbell.AddToScheme + + // SchemeBuilderBMC is used to add go types to the GroupVersionKind scheme. + SchemeBuilderBMC = &scheme.Builder{GroupVersion: bmc.GroupVersion} + + // AddToSchemeBMC adds the types in this group-version to the given scheme. + AddToSchemeBMC = SchemeBuilderBMC.AddToScheme +) + +//nolint:gochecknoinits +func init() { + SchemeBuilderTinkerbell.Register(&tinkerbell.Hardware{}, &tinkerbell.HardwareList{}) + SchemeBuilderTinkerbell.Register(&tinkerbell.Template{}, &tinkerbell.TemplateList{}) + SchemeBuilderTinkerbell.Register(&tinkerbell.Workflow{}, &tinkerbell.WorkflowList{}) + SchemeBuilderTinkerbell.Register(&tinkerbell.WorkflowRuleSet{}, &tinkerbell.WorkflowRuleSetList{}) + + SchemeBuilderBMC.Register(&bmc.Job{}, &bmc.JobList{}) + SchemeBuilderBMC.Register(&bmc.Machine{}, &bmc.MachineList{}) + SchemeBuilderBMC.Register(&bmc.Task{}, &bmc.TaskList{}) +} diff --git a/controller/machine/bmc.go b/controller/machine/bmc.go index d03bcf1e..eeea9c20 100644 --- a/controller/machine/bmc.go +++ b/controller/machine/bmc.go @@ -3,13 +3,17 @@ package machine import ( "fmt" - rufiov1 "github.com/tinkerbell/rufio/api/v1alpha1" - tinkv1 "github.com/tinkerbell/tink/api/v1alpha1" + rufiov1 "github.com/tinkerbell/tinkerbell/api/v1alpha1/bmc" + tinkv1 "github.com/tinkerbell/tinkerbell/api/v1alpha1/tinkerbell" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" ) +func toPtr[T any](v T) *T { + return &v +} + // createPowerOffJob creates a BMCJob object with the required tasks for hardware power off. func (scope *machineReconcileScope) createPowerOffJob(hw *tinkv1.Hardware) error { controller := true @@ -22,7 +26,7 @@ func (scope *machineReconcileScope) createPowerOffJob(hw *tinkv1.Hardware) error APIVersion: "infrastructure.cluster.x-k8s.io/v1beta1", Kind: "TinkerbellMachine", Name: scope.tinkerbellMachine.Name, - UID: scope.tinkerbellMachine.ObjectMeta.UID, + UID: scope.tinkerbellMachine.UID, Controller: &controller, }, }, @@ -34,7 +38,7 @@ func (scope *machineReconcileScope) createPowerOffJob(hw *tinkv1.Hardware) error }, Tasks: []rufiov1.Action{ { - PowerAction: rufiov1.PowerHardOff.Ptr(), + PowerAction: toPtr(rufiov1.PowerHardOff), }, }, }, @@ -48,7 +52,7 @@ func (scope *machineReconcileScope) createPowerOffJob(hw *tinkv1.Hardware) error "Name", bmcJob.Name, "Namespace", bmcJob.Namespace) - return fmt.Errorf("requeue to wait for job.bmc completion: %s/%s", bmcJob.Namespace, bmcJob.Name) //nolint:goerr113 + return fmt.Errorf("requeue to wait for job.bmc completion: %s/%s", bmcJob.Namespace, bmcJob.Name) //nolint:err113 } // getJob fetches the Job by name. @@ -87,8 +91,8 @@ func (scope *machineReconcileScope) ensureBMCJobCompletionForDelete(hardware *ti } if bmcJob.HasCondition(rufiov1.JobFailed, rufiov1.ConditionTrue) { - return fmt.Errorf("bmc job %s/%s failed", bmcJob.Namespace, bmcJob.Name) //nolint:goerr113 + return fmt.Errorf("bmc job %s/%s failed", bmcJob.Namespace, bmcJob.Name) //nolint:err113 } - return fmt.Errorf("requeue, bmc job %s/%s is not completed", bmcJob.Namespace, bmcJob.Name) //nolint:goerr113 + return fmt.Errorf("requeue, bmc job %s/%s is not completed", bmcJob.Namespace, bmcJob.Name) //nolint:err113 } diff --git a/controller/machine/hardware.go b/controller/machine/hardware.go index 0acf8aae..645e818d 100644 --- a/controller/machine/hardware.go +++ b/controller/machine/hardware.go @@ -5,7 +5,7 @@ import ( "sort" "strings" - tinkv1 "github.com/tinkerbell/tink/api/v1alpha1" + tinkv1 "github.com/tinkerbell/tinkerbell/api/v1alpha1/tinkerbell" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/types" @@ -80,12 +80,12 @@ func (scope *machineReconcileScope) patchHardwareAnnotations(hw *tinkv1.Hardware return fmt.Errorf("initializing patch helper for selected hardware: %w", err) } - if hw.ObjectMeta.Annotations == nil { - hw.ObjectMeta.Annotations = map[string]string{} + if hw.Annotations == nil { + hw.Annotations = map[string]string{} } for k, v := range annotations { - hw.ObjectMeta.Annotations[k] = v + hw.Annotations[k] = v } if err := patchHelper.Patch(scope.ctx, hw); err != nil { @@ -96,12 +96,12 @@ func (scope *machineReconcileScope) patchHardwareAnnotations(hw *tinkv1.Hardware } func (scope *machineReconcileScope) takeHardwareOwnership(hw *tinkv1.Hardware) error { - if len(hw.ObjectMeta.Labels) == 0 { - hw.ObjectMeta.Labels = map[string]string{} + if len(hw.Labels) == 0 { + hw.Labels = map[string]string{} } - hw.ObjectMeta.Labels[HardwareOwnerNameLabel] = scope.tinkerbellMachine.Name - hw.ObjectMeta.Labels[HardwareOwnerNamespaceLabel] = scope.tinkerbellMachine.Namespace + hw.Labels[HardwareOwnerNameLabel] = scope.tinkerbellMachine.Name + hw.Labels[HardwareOwnerNamespaceLabel] = scope.tinkerbellMachine.Namespace // Add finalizer to hardware as well to make sure we release it before Machine object is removed. controllerutil.AddFinalizer(hw, infrastructurev1.MachineFinalizer) @@ -233,7 +233,6 @@ func (scope *machineReconcileScope) assignedHardware() (*tinkv1.Hardware, error) return nil, nil } -//nolint:lll func byHardwareAffinity(hardware []tinkv1.Hardware, preferred []infrastructurev1.WeightedHardwareAffinityTerm) (func(i int, j int) bool, error) { scores := map[client.ObjectKey]int32{} // compute scores for each item based on the preferred term weights @@ -276,9 +275,9 @@ func (scope *machineReconcileScope) releaseHardware(hw *tinkv1.Hardware) error { return fmt.Errorf("initializing patch helper for selected hardware: %w", err) } - delete(hw.ObjectMeta.Labels, HardwareOwnerNameLabel) - delete(hw.ObjectMeta.Labels, HardwareOwnerNamespaceLabel) - delete(hw.ObjectMeta.Annotations, HardwareProvisionedAnnotation) + delete(hw.Labels, HardwareOwnerNameLabel) + delete(hw.Labels, HardwareOwnerNamespaceLabel) + delete(hw.Annotations, HardwareProvisionedAnnotation) controllerutil.RemoveFinalizer(hw, infrastructurev1.MachineFinalizer) diff --git a/controller/machine/scope.go b/controller/machine/scope.go index c004a809..11cc62eb 100644 --- a/controller/machine/scope.go +++ b/controller/machine/scope.go @@ -32,7 +32,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "github.com/go-logr/logr" - tinkv1 "github.com/tinkerbell/tink/api/v1alpha1" + tinkv1 "github.com/tinkerbell/tinkerbell/api/v1alpha1/tinkerbell" infrastructurev1 "github.com/tinkerbell/cluster-api-provider-tinkerbell/api/v1beta1" ) @@ -127,7 +127,7 @@ func (scope *machineReconcileScope) Reconcile() error { func (scope *machineReconcileScope) reconcile(hw *tinkv1.Hardware) error { // If the workflow has completed the TinkerbellMachine is ready. - if v, found := hw.ObjectMeta.GetAnnotations()[HardwareProvisionedAnnotation]; found && v == "true" { + if v, found := hw.GetAnnotations()[HardwareProvisionedAnnotation]; found && v == "true" { scope.log.Info("Marking TinkerbellMachine as Ready") scope.tinkerbellMachine.Status.Ready = true @@ -193,7 +193,7 @@ func (scope *machineReconcileScope) setStatus(hw *tinkv1.Hardware) error { // MachineScheduledForDeletion implements machineReconcileContext interface method // using TinkerbellMachine deletion timestamp. func (scope *machineReconcileScope) MachineScheduledForDeletion() bool { - return !scope.tinkerbellMachine.ObjectMeta.DeletionTimestamp.IsZero() + return !scope.tinkerbellMachine.DeletionTimestamp.IsZero() } // DeleteMachineWithDependencies removes template and workflow objects associated with given machine. @@ -358,7 +358,7 @@ func (scope *machineReconcileScope) getReadyBootstrapCloudConfig(machine *cluste } // getTinkerbellCluster returns associated TinkerbellCluster object for a given machine. -func (scope *machineReconcileScope) getReadyTinkerbellCluster(machine *clusterv1.Machine) (*infrastructurev1.TinkerbellCluster, error) { //nolint:lll +func (scope *machineReconcileScope) getReadyTinkerbellCluster(machine *clusterv1.Machine) (*infrastructurev1.TinkerbellCluster, error) { cluster, err := util.GetClusterFromMetadata(scope.ctx, scope.client, machine.ObjectMeta) if err != nil { return nil, fmt.Errorf("getting cluster from metadata: %w", err) diff --git a/controller/machine/template.go b/controller/machine/template.go index 36d2a843..77b17546 100644 --- a/controller/machine/template.go +++ b/controller/machine/template.go @@ -8,7 +8,7 @@ import ( "strings" "text/template" - tinkv1 "github.com/tinkerbell/tink/api/v1alpha1" + tinkv1 "github.com/tinkerbell/tinkerbell/api/v1alpha1/tinkerbell" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" @@ -196,7 +196,7 @@ func (scope *machineReconcileScope) createTemplate(hw *tinkv1.Hardware) error { APIVersion: "infrastructure.cluster.x-k8s.io/v1beta1", Kind: "TinkerbellMachine", Name: scope.tinkerbellMachine.Name, - UID: scope.tinkerbellMachine.ObjectMeta.UID, + UID: scope.tinkerbellMachine.UID, }, }, }, diff --git a/controller/machine/tinkerbellmachine.go b/controller/machine/tinkerbellmachine.go index aef9885c..fa5c51e4 100644 --- a/controller/machine/tinkerbellmachine.go +++ b/controller/machine/tinkerbellmachine.go @@ -23,6 +23,7 @@ import ( "time" apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" "sigs.k8s.io/cluster-api/util" "sigs.k8s.io/cluster-api/util/annotations" @@ -35,8 +36,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/controller" "sigs.k8s.io/controller-runtime/pkg/handler" - rufiov1 "github.com/tinkerbell/rufio/api/v1alpha1" - tinkv1 "github.com/tinkerbell/tink/api/v1alpha1" + rufiov1 "github.com/tinkerbell/tinkerbell/api/v1alpha1/bmc" + tinkv1 "github.com/tinkerbell/tinkerbell/api/v1alpha1/tinkerbell" infrastructurev1 "github.com/tinkerbell/cluster-api-provider-tinkerbell/api/v1beta1" ) @@ -78,7 +79,7 @@ func (r *TinkerbellMachineReconciler) Reconcile(ctx context.Context, req ctrl.Re client: r.Client, } - if err := r.Client.Get(ctx, req.NamespacedName, scope.tinkerbellMachine); err != nil { + if err := r.Get(ctx, req.NamespacedName, scope.tinkerbellMachine); err != nil { if apierrors.IsNotFound(err) { log.Info("TinkerbellMachine not found") @@ -162,6 +163,7 @@ func (r *TinkerbellMachineReconciler) SetupWithManager( ctx context.Context, mgr ctrl.Manager, options controller.Options, + sm *runtime.Scheme, ) error { log := ctrl.LoggerFrom(ctx) @@ -176,7 +178,7 @@ func (r *TinkerbellMachineReconciler) SetupWithManager( builder := ctrl.NewControllerManagedBy(mgr). WithOptions(options). - WithEventFilter(predicates.ResourceNotPausedAndHasFilterLabel(log, r.WatchFilterValue)). + WithEventFilter(predicates.ResourceNotPausedAndHasFilterLabel(sm, log, r.WatchFilterValue)). For(&infrastructurev1.TinkerbellMachine{}). Watches( &clusterv1.Machine{}, @@ -191,7 +193,7 @@ func (r *TinkerbellMachineReconciler) SetupWithManager( Watches( &clusterv1.Cluster{}, handler.EnqueueRequestsFromMapFunc(clusterToObjectFunc), - builder.WithPredicates(predicates.ClusterUnpausedAndInfrastructureReady(log)), + builder.WithPredicates(predicates.ClusterPausedTransitionsOrInfrastructureReady(sm, log)), ). Watches( &tinkv1.Workflow{}, @@ -228,7 +230,7 @@ func (r *TinkerbellMachineReconciler) TinkerbellClusterToTinkerbellMachines(ctx c, ok := o.(*infrastructurev1.TinkerbellCluster) if !ok { log.Error( - fmt.Errorf("expected a TinkerbellCluster but got a %T", o), //nolint:goerr113 + fmt.Errorf("expected a TinkerbellCluster but got a %T", o), //nolint:err113 "failed to get TinkerbellMachine for TinkerbellCluster", ) @@ -238,8 +240,8 @@ func (r *TinkerbellMachineReconciler) TinkerbellClusterToTinkerbellMachines(ctx log = log.WithValues("TinkerbellCluster", c.Name, "Namespace", c.Namespace) // Don't handle deleted TinkerbellClusters - if !c.ObjectMeta.DeletionTimestamp.IsZero() { - log.V(4).Info("TinkerbellCluster has a deletion timestamp, skipping mapping.") //nolint:gomnd + if !c.DeletionTimestamp.IsZero() { + log.V(4).Info("TinkerbellCluster has a deletion timestamp, skipping mapping.") return nil } diff --git a/controller/machine/tinkerbellmachine_test.go b/controller/machine/tinkerbellmachine_test.go index 1da80132..6fc21c04 100644 --- a/controller/machine/tinkerbellmachine_test.go +++ b/controller/machine/tinkerbellmachine_test.go @@ -34,9 +34,10 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/fake" - tinkv1 "github.com/tinkerbell/tink/api/v1alpha1" + tinkv1 "github.com/tinkerbell/tinkerbell/api/v1alpha1/tinkerbell" infrastructurev1 "github.com/tinkerbell/cluster-api-provider-tinkerbell/api/v1beta1" + "github.com/tinkerbell/cluster-api-provider-tinkerbell/controller" "github.com/tinkerbell/cluster-api-provider-tinkerbell/controller/machine" ) @@ -139,7 +140,7 @@ func validTinkerbellCluster(name, namespace string) *infrastructurev1.Tinkerbell }, } - tinkCluster.Default() + _ = tinkCluster.Default(context.TODO(), nil) return tinkCluster } @@ -265,8 +266,8 @@ func validWorkflow(name, namespace string) *tinkv1.Workflow { Name: name, Actions: []tinkv1.Action{ { - Name: name, - Status: tinkv1.WorkflowStateSuccess, + Name: name, + State: tinkv1.WorkflowStateSuccess, }, }, }, @@ -281,7 +282,7 @@ func kubernetesClientWithObjects(t *testing.T, objects []runtime.Object) client. scheme := runtime.NewScheme() - g.Expect(tinkv1.AddToScheme(scheme)).To(Succeed(), "Adding Tinkerbell objects to scheme should succeed") + g.Expect(controller.AddToSchemeTinkerbell(scheme)).To(Succeed(), "Adding Tinkerbell objects to scheme should succeed") g.Expect(infrastructurev1.AddToScheme(scheme)).To(Succeed(), "Adding Tinkerbell CAPI objects to scheme should succeed") g.Expect(clusterv1.AddToScheme(scheme)).To(Succeed(), "Adding CAPI objects to scheme should succeed") g.Expect(corev1.AddToScheme(scheme)).To(Succeed(), "Adding Core V1 objects to scheme should succeed") @@ -332,7 +333,7 @@ func Test_Machine_reconciliation_with_available_hardware(t *testing.T) { // Owner reference is required to make use of Kubernetes GC for removing dependent objects, so if // machine gets force-removed, template will be cleaned up. - t.Run("with_owner_reference_set", func(t *testing.T) { + t.Run("with_owner_reference_set", func(t *testing.T) { //nolint:paralleltest g := NewWithT(t) g.Expect(template.ObjectMeta.OwnerReferences).NotTo(BeEmpty(), "Expected at least one owner reference to be set") @@ -352,7 +353,7 @@ func Test_Machine_reconciliation_with_available_hardware(t *testing.T) { // Owner reference is required to make use of Kubernetes GC for removing dependent objects, so if // machine gets force-removed, workflow will be cleaned up. - t.Run("with_owner_reference_set", func(t *testing.T) { + t.Run("with_owner_reference_set", func(t *testing.T) { //nolint:paralleltest g := NewWithT(t) g.Expect(workflow.ObjectMeta.OwnerReferences).NotTo(BeEmpty(), "Expected at least one owner reference to be set") @@ -589,49 +590,49 @@ func Test_Machine_reconciliation(t *testing.T) { t.Parallel() // Requeue will be handled when resource is created. - t.Run("is_requeued_when_machine_object_is_missing", //nolint:paralleltest + t.Run("is_requeued_when_machine_object_is_missing", machineReconciliationIsRequeuedWhenTinkerbellMachineObjectIsMissing) // From https://cluster-api.sigs.k8s.io/developer/providers/cluster-infrastructure.html#behavior // Requeue will be handled when ownerRef is set - t.Run("machine_has_no_owner_set", machineReconciliationIsRequeuedWhenTinkerbellMachineHasNoOwnerSet) //nolint:paralleltest + t.Run("machine_has_no_owner_set", machineReconciliationIsRequeuedWhenTinkerbellMachineHasNoOwnerSet) // From https://cluster-api.sigs.k8s.io/developer/providers/cluster-infrastructure.html#behavior // Requeue will be handled when bootstrap secret is set through the Watch on Machines - t.Run("bootstrap_secret_is_not_ready", machineReconciliationIsRequeuedWhenBootstrapSecretIsNotReady) //nolint:paralleltest + t.Run("bootstrap_secret_is_not_ready", machineReconciliationIsRequeuedWhenBootstrapSecretIsNotReady) // From https://cluster-api.sigs.k8s.io/developer/providers/cluster-infrastructure.html#behavior // Requeue will be handled when bootstrap secret is set through the Watch on Clusters - t.Run("cluster_infrastructure_is_not_ready", machineReconciliationIsRequeuedWhenClusterInfrastructureIsNotReady) //nolint:paralleltest + t.Run("cluster_infrastructure_is_not_ready", machineReconciliationIsRequeuedWhenClusterInfrastructureIsNotReady) }) t.Run("fails_when", func(t *testing.T) { t.Parallel() - t.Run("reconciler_is_nil", machineReconciliationPanicsWhenReconcilerIsNil) //nolint:paralleltest - t.Run("reconciler_has_no_client_set", machineReconciliationPanicsWhenReconcilerHasNoClientSet) //nolint:paralleltest + t.Run("reconciler_is_nil", machineReconciliationPanicsWhenReconcilerIsNil) + t.Run("reconciler_has_no_client_set", machineReconciliationPanicsWhenReconcilerHasNoClientSet) // CAPI spec says this is optional, but @detiber says it's effectively required, so treat it as so. - t.Run("machine_has_no_version_set", machineReconciliationFailsWhenMachineHasNoVersionSet) //nolint:paralleltest + t.Run("machine_has_no_version_set", machineReconciliationFailsWhenMachineHasNoVersionSet) - t.Run("associated_cluster_object_does_not_exist", //nolint:paralleltest + t.Run("associated_cluster_object_does_not_exist", machineReconciliationFailsWhenAssociatedClusterObjectDoesNotExist) - t.Run("associated_tinkerbell_cluster_object_does_not_exist", //nolint:paralleltest + t.Run("associated_tinkerbell_cluster_object_does_not_exist", machineReconciliationFailsWhenAssociatedTinkerbellClusterObjectDoesNotExist) // If for example CAPI changes key used to store bootstrap date, we shouldn't try to create machines // with empty bootstrap config, we should fail early instead. - t.Run("bootstrap_config_is_empty", machineReconciliationFailsWhenBootstrapConfigIsEmpty) //nolint:paralleltest - t.Run("bootstrap_config_has_no_value_key", machineReconciliationFailsWhenBootstrapConfigHasNoValueKey) //nolint:paralleltest + t.Run("bootstrap_config_is_empty", machineReconciliationFailsWhenBootstrapConfigIsEmpty) + t.Run("bootstrap_config_has_no_value_key", machineReconciliationFailsWhenBootstrapConfigHasNoValueKey) - t.Run("there_is_no_hardware_available", machineReconciliationFailsWhenThereIsNoHardwareAvailable) //nolint:paralleltest + t.Run("there_is_no_hardware_available", machineReconciliationFailsWhenThereIsNoHardwareAvailable) - t.Run("selected_hardware_has_no_ip_address_set", machineReconciliationFailsWhenSelectedHardwareHasNoIPAddressSet) //nolint:paralleltest + t.Run("selected_hardware_has_no_ip_address_set", machineReconciliationFailsWhenSelectedHardwareHasNoIPAddressSet) }) // Single hardware should only ever be used for a single machine. - t.Run("selects_unique_and_available_hardware_for_each_machine", //nolint:paralleltest + t.Run("selects_unique_and_available_hardware_for_each_machine", machineReconciliationSelectsUniqueAndAvailablehardwareForEachMachine) t.Run("selects_unique_and_available_hardware_for_each_machine_filtering_by_required_hardware_affinity", //nolint:paralleltest @@ -647,17 +648,17 @@ func Test_Machine_reconciliation(t *testing.T) { // misspelling process is aborted in the middle. // // Without that, new Hardware will be selected each time. - t.Run("uses_already_selected_hardware_if_patching_tinkerbell_machine_failed", //nolint:paralleltest + t.Run("uses_already_selected_hardware_if_patching_tinkerbell_machine_failed", machineReconciliationUsesAlreadySelectedHardwareIfPatchingTinkerbellMachineFailed) t.Run("when_machine_is_scheduled_for_removal_it", func(t *testing.T) { t.Parallel() // From https://cluster-api.sigs.k8s.io/developer/providers/machine-infrastructure.html#behavior - t.Run("removes_tinkerbell_finalizer", notImplemented) //nolint:paralleltest + t.Run("removes_tinkerbell_finalizer", notImplemented) // Removing machine should release used hardware. - t.Run("marks_hardware_as_available_for_other_machines", notImplemented) //nolint:paralleltest + t.Run("marks_hardware_as_available_for_other_machines", notImplemented) }) } @@ -800,7 +801,7 @@ func machineReconciliationIsRequeuedWhenTinkerbellMachineHasNoOwnerSet(t *testin g := NewWithT(t) hardwareUUID := uuid.New().String() tinkerbellMachine := validTinkerbellMachine(tinkerbellMachineName, clusterNamespace, machineName, hardwareUUID) - tinkerbellMachine.ObjectMeta.OwnerReferences = nil + tinkerbellMachine.OwnerReferences = nil objects := []runtime.Object{ tinkerbellMachine, @@ -1069,7 +1070,7 @@ func machineReconciliationUsesAlreadySelectedHardwareIfPatchingTinkerbellMachine expectedHardwareName := "alreadyOwnedHardware" alreadyOwnedHardware := validHardware(expectedHardwareName, uuid.New().String(), "2.2.2.2") - alreadyOwnedHardware.ObjectMeta.Labels = map[string]string{ + alreadyOwnedHardware.Labels = map[string]string{ machine.HardwareOwnerNameLabel: tinkerbellMachineName, machine.HardwareOwnerNamespaceLabel: clusterNamespace, } diff --git a/controller/machine/workflow.go b/controller/machine/workflow.go index 7d5269f5..38a556cf 100644 --- a/controller/machine/workflow.go +++ b/controller/machine/workflow.go @@ -9,7 +9,7 @@ import ( "github.com/tinkerbell/cluster-api-provider-tinkerbell/api/v1beta1" - tinkv1 "github.com/tinkerbell/tink/api/v1alpha1" + tinkv1 "github.com/tinkerbell/tinkerbell/api/v1alpha1/tinkerbell" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" @@ -52,7 +52,7 @@ func (scope *machineReconcileScope) createWorkflow(hw *tinkv1.Hardware) error { APIVersion: "infrastructure.cluster.x-k8s.io/v1beta1", Kind: "TinkerbellMachine", Name: scope.tinkerbellMachine.Name, - UID: scope.tinkerbellMachine.ObjectMeta.UID, + UID: scope.tinkerbellMachine.UID, Controller: &c, }, }, @@ -73,7 +73,7 @@ func (scope *machineReconcileScope) createWorkflow(hw *tinkv1.Hardware) error { switch scope.tinkerbellMachine.Spec.BootOptions.BootMode { case v1beta1.BootMode("netboot"): workflow.Spec.BootOptions.BootMode = tinkv1.BootMode("netboot") - case v1beta1.BootMode("iso"): + case v1beta1.BootMode("isoboot"): if scope.tinkerbellMachine.Spec.BootOptions.ISOURL == "" { return errISOBootURLRequired } @@ -87,7 +87,7 @@ func (scope *machineReconcileScope) createWorkflow(hw *tinkv1.Hardware) error { u.Path = path.Join(urlPath, strings.Replace(hw.Spec.Metadata.Instance.ID, ":", "-", 5), file) workflow.Spec.BootOptions.ISOURL = u.String() - workflow.Spec.BootOptions.BootMode = tinkv1.BootMode("iso") + workflow.Spec.BootOptions.BootMode = tinkv1.BootMode("isoboot") } } diff --git a/docs/PLAYGROUND.md b/docs/PLAYGROUND.md index e82f9c3e..03323991 100644 --- a/docs/PLAYGROUND.md +++ b/docs/PLAYGROUND.md @@ -47,3 +47,54 @@ The following repositories are required for the CAPT development setup. ``` 1. Enter `y` in the CAPT Playground prompt and follow the post creation instructions. + +## Pivot the CAPI and CAPT management components to the created Tinkerbell cluster + +To test and play with the CAPI pivot process, move the CAPI and CAPT management components from the KinD cluster to the new Tinkerbell cluster. + +```bash +task pivot +``` + +### Understanding the pivot process + +The pivot process follows the CAPI process defined in the [CAPI documentation](https://cluster-api.sigs.k8s.io/clusterctl/commands/move#bootstrap--pivot). The following are example steps of what the command `task pivot` does. Inspect the playground file `Taskfile-capi-pivot.yaml`, run `task pivot --dry`, and see the output after running `task pivot` to see the actual commands that are executed. + +Example steps: + +1. Create the CAPT Playground cluster: + + ```bash + task create-playground + ``` + +1. Install the Tinkerbell stack in the new cluster: + + ```bash + export KUBECONFIG=output/capt-playground.kubeconfig + TRUSTED_PROXIES=$(kubectl get nodes -o jsonpath='{.items[*].spec.podCIDR}' | tr ' ' ',') + LB_IP=172.18.10.84 + ARTIFACTS_FILE_SERVER=http://172.18.10.85:7173 + helm upgrade --install tinkerbell oci://ghcr.io/tinkerbell/charts/tinkerbell --version v0.19.2-5d22212c --create-namespace --namespace tinkerbell --wait --set "trustedProxies={${TRUSTED_PROXIES}}" --set "publicIP=$LB_IP" --set "artifactsFileServer=$ARTIFACTS_FILE_SERVER" + ``` + +1. Initialize CAPI in the cluster: + + ```bash + export KUBECONFIG=output/capt-playground.kubeconfig + export TINKERBELL_IP=172.18.10.84 + clusterctl --config output/clusterctl.yaml init --infrastructure tinkerbell + ``` + +1. Move the CAPI resources from the KinD cluster to the new cluster: + + ```bash + export KUBECONFIG=output/kind.kubeconfig + clusterctl move --to-kubeconfig="output/capt-playground.kubeconfig" --config output/clusterctl.yaml --kubeconfig output/kind.kubeconfig -n tinkerbell + ``` + +1. Delete the KinD cluster: + + ```bash + kind delete cluster --name capt-playground + ``` diff --git a/go.mod b/go.mod index 7b1b40e2..fb1c2502 100644 --- a/go.mod +++ b/go.mod @@ -1,59 +1,54 @@ module github.com/tinkerbell/cluster-api-provider-tinkerbell -go 1.23.0 - -toolchain go1.23.1 +go 1.24.1 require ( - github.com/go-logr/logr v1.4.2 + github.com/go-logr/logr v1.4.3 github.com/go-logr/zerologr v1.2.3 github.com/google/go-cmp v0.7.0 github.com/google/uuid v1.6.0 github.com/onsi/ginkgo v1.16.5 - github.com/onsi/gomega v1.37.0 + github.com/onsi/gomega v1.38.0 github.com/rs/zerolog v1.34.0 - github.com/spf13/pflag v1.0.6 - github.com/tinkerbell/rufio v0.6.5 - github.com/tinkerbell/tink v0.12.2 - k8s.io/api v0.31.3 - k8s.io/apimachinery v0.31.3 - k8s.io/client-go v0.31.3 - k8s.io/component-base v0.31.3 + github.com/spf13/pflag v1.0.7 + github.com/tinkerbell/tinkerbell/api v0.19.2 + k8s.io/api v0.33.3 + k8s.io/apimachinery v0.33.3 + k8s.io/client-go v0.33.3 + k8s.io/component-base v0.33.3 k8s.io/klog/v2 v2.130.1 - k8s.io/utils v0.0.0-20240921022957-49e7df575cb6 - sigs.k8s.io/cluster-api v1.8.5 - sigs.k8s.io/controller-runtime v0.19.4 - sigs.k8s.io/kustomize/kustomize/v5 v5.6.0 - sigs.k8s.io/yaml v1.4.0 + k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 + sigs.k8s.io/cluster-api v1.10.4 + sigs.k8s.io/controller-runtime v0.21.0 + sigs.k8s.io/kustomize/kustomize/v5 v5.7.1 + sigs.k8s.io/yaml v1.6.0 ) require ( + cel.dev/expr v0.20.0 // indirect + dario.cat/mergo v1.0.2 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/emicklei/go-restful/v3 v3.12.1 // indirect - github.com/evanphx/json-patch/v5 v5.9.0 // indirect - github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/emicklei/go-restful/v3 v3.12.2 // indirect + github.com/evanphx/json-patch v5.9.0+incompatible // indirect + github.com/evanphx/json-patch/v5 v5.9.11 // indirect + github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/go-errors/errors v1.5.1 // 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-openapi/swag v0.23.1 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect - github.com/gobuffalo/flect v1.0.2 // indirect + github.com/gobuffalo/flect v1.0.3 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.4 // indirect + github.com/google/btree v1.1.3 // indirect github.com/google/gnostic-models v0.6.9 // indirect - github.com/google/gofuzz v1.2.0 // indirect - github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect - github.com/imdario/mergo v0.3.16 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.17.9 // indirect - github.com/mailru/easyjson v0.7.7 // indirect + github.com/mailru/easyjson v0.9.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect @@ -62,35 +57,46 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/nxadm/tail v1.4.11 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/prometheus/client_golang v1.20.5 // indirect + github.com/prometheus/client_golang v1.22.0 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.55.0 // indirect + github.com/prometheus/common v0.62.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/sergi/go-diff v1.2.0 // indirect - github.com/spf13/cobra v1.8.1 // indirect + github.com/spf13/cobra v1.9.1 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/xlab/treeprint v1.2.0 // indirect - golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect - golang.org/x/net v0.38.0 // indirect - golang.org/x/oauth2 v0.22.0 // indirect - golang.org/x/sys v0.31.0 // indirect - golang.org/x/term v0.30.0 // indirect - golang.org/x/text v0.23.0 // indirect - golang.org/x/time v0.6.0 // indirect - golang.org/x/tools v0.30.0 // indirect - gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/protobuf v1.36.5 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect + go.opentelemetry.io/otel v1.36.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.36.0 // indirect + go.opentelemetry.io/otel/sdk v1.36.0 // indirect + go.opentelemetry.io/otel/trace v1.36.0 // indirect + go.yaml.in/yaml/v2 v2.4.2 // indirect + go.yaml.in/yaml/v3 v3.0.3 // indirect + golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 // indirect + golang.org/x/net v0.41.0 // indirect + golang.org/x/oauth2 v0.29.0 // indirect + golang.org/x/sync v0.15.0 // indirect + golang.org/x/sys v0.33.0 // indirect + golang.org/x/term v0.32.0 // indirect + golang.org/x/text v0.26.0 // indirect + golang.org/x/time v0.9.0 // indirect + golang.org/x/tools v0.33.0 // indirect + gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250519155744-55703ea1f237 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237 // indirect + google.golang.org/grpc v1.72.2 // indirect + google.golang.org/protobuf v1.36.6 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apiextensions-apiserver v0.31.0 // indirect - k8s.io/cluster-bootstrap v0.30.3 // indirect - k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 // indirect - sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/kustomize/api v0.19.0 // indirect - sigs.k8s.io/kustomize/cmd/config v0.19.0 // indirect - sigs.k8s.io/kustomize/kyaml v0.19.0 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.5.0 // indirect + k8s.io/apiextensions-apiserver v0.33.0 // indirect + k8s.io/cluster-bootstrap v0.32.3 // indirect + k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect + sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect + sigs.k8s.io/kustomize/api v0.20.1 // indirect + sigs.k8s.io/kustomize/cmd/config v0.20.1 // indirect + sigs.k8s.io/kustomize/kyaml v0.20.1 // indirect + sigs.k8s.io/randfill v1.0.0 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect ) diff --git a/go.sum b/go.sum index d268d982..61b25c30 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ -dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= -dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +cel.dev/expr v0.20.0 h1:OunBvVCfvpWlt4dN7zg3FM6TDkzOePe1+foGJ9AXeeI= +cel.dev/expr v0.20.0/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= +dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8= +dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= @@ -10,47 +12,45 @@ github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0= github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= -github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA= -github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= 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/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= -github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= -github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8= +github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= 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/coredns/caddy v1.1.1 h1:2eYKZT7i6yxIfGP3qLJoJ7HAsDJqYB+X68g4NYjSrE0= github.com/coredns/caddy v1.1.1/go.mod h1:A6ntJQlAWuQfFlsd9hvigKbo2WS0VUs2l1e2F+BawD4= -github.com/coredns/corefile-migration v1.0.23 h1:Fp4FETmk8sT/IRgnKX2xstC2dL7+QdcU+BL5AYIN3Jw= -github.com/coredns/corefile-migration v1.0.23/go.mod h1:8HyMhuyzx9RLZp8cRc9Uf3ECpEAafHOFxQWUPqktMQI= +github.com/coredns/corefile-migration v1.0.26 h1:xiiEkVB1Dwolb24pkeDUDBfygV9/XsOSq79yFCrhptY= +github.com/coredns/corefile-migration v1.0.26/go.mod h1:56DPqONc3njpVPsdilEnfijCwNGC3/kTJLl7i7SPavY= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= 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/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU= -github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI= -github.com/evanphx/json-patch v5.7.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/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= +github.com/emicklei/go-restful/v3 v3.12.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/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU= +github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -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/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/go-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.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= @@ -61,20 +61,18 @@ github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1 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-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= +github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= 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-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/gobuffalo/flect v1.0.2 h1:eqjPGSo2WmjgY2XlpGwo2NXgL3RucAKo4k4qQMNA5sA= -github.com/gobuffalo/flect v1.0.2/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs= +github.com/gobuffalo/flect v1.0.3 h1:xeWBM2nui+qnVvNM4S3foBhCAL2XgPU+a7FdpelbTq4= +github.com/gobuffalo/flect v1.0.3/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= 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.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -82,10 +80,10 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= -github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/cel-go v0.20.1 h1:nDx9r8S3L4pE61eDdt8igGj8rf5kjYR3ILxWIpWNi84= -github.com/google/cel-go v0.20.1/go.mod h1:kWcIzTsPX0zmQ+H3TirHstLLf9ep5QTsZBN9u4dOYLg= +github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= +github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/cel-go v0.23.2 h1:UdEe3CvQh3Nv+E/j9r1Y//WO0K0cSyD7/y0bzyLIMI4= +github.com/google/cel-go v0.23.2/go.mod h1:52Pb6QsDbC5kvgxvZhiL9QX1oZEkcUF/ZqaPx1J5Wwo= github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw= github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -97,20 +95,16 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX 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-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg= -github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= -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-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8= +github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= 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/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI= github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= -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/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= @@ -119,8 +113,8 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= +github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -130,8 +124,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= +github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/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= @@ -159,12 +153,12 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.23.3 h1:edHxnszytJ4lD9D5Jjc4tiDkPBZ3siDeJJkUZJJVkp0= -github.com/onsi/ginkgo/v2 v2.23.3/go.mod h1:zXTP6xIp3U8aVuXN8ENK9IXRaTjFnpVB9mGmaSRvxnM= +github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus= +github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y= -github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0= +github.com/onsi/gomega v1.38.0 h1:c/WX+w8SLAinvuKKQFh77WEucCnPk4j2OTUr7lt7BeY= +github.com/onsi/gomega v1.38.0/go.mod h1:OcXcwId0b9QsE7Y49u+BTrL4IdKOBOKnD6VQNTJEB6o= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -172,16 +166,16 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE 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.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= -github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q= +github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= -github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= +github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= +github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= @@ -190,15 +184,15 @@ github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= -github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w= -github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= -github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= -github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= +github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= +github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= +github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU= -github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= +github.com/spf13/pflag v1.0.7 h1:vN6T9TfwStFPFM5XzjsvmzZkLuaLX+HS+0SeFLRgU6M= +github.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs= +github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo= 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= @@ -214,45 +208,51 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/tinkerbell/rufio v0.6.5 h1:9s8QHKLggH0su8PrdWz7MSP6OMhzsKHIShIH4z3hFqU= -github.com/tinkerbell/rufio v0.6.5/go.mod h1:IavMOkADdR1CeC0gzZM39ycccPIoeVMZ1qdtGtwv5ow= -github.com/tinkerbell/tink v0.12.2 h1:ROe5SAx5X8hHEROm9OJzc6XLhEzOhUcdGpY2bLVAOnk= -github.com/tinkerbell/tink v0.12.2/go.mod h1:Cpv7pSazMhq6HYVAByHJu2tkLIsR9K/mBY1S87RQbC4= +github.com/tinkerbell/tinkerbell/api v0.19.2 h1:USEq8X+Ih8FEa3SsqULEQFW0bMpa8T6JvBTQqVQzTaU= +github.com/tinkerbell/tinkerbell/api v0.19.2/go.mod h1:S1DVHOyJ3FjthCv9iDURC3rVrRgh4jOLbohocJUbxMU= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= -go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY= -go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0 h1:lsInsfvhVIfOI6qHVyysXMNDnjO9Npvl7tlDPJFBVd4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0/go.mod h1:KQsVNh4OjgjTG0G6EiNi1jVpnaeeKsKMRwbLN+f1+8M= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0/go.mod h1:MOiCmryaYtc+V0Ei+Tx9o5S1ZjA7kzLucuVuyzBZloQ= -go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE= -go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY= -go.opentelemetry.io/otel/sdk v1.30.0 h1:cHdik6irO49R5IysVhdn8oaiR9m8XluDaJAs4DfOrYE= -go.opentelemetry.io/otel/sdk v1.30.0/go.mod h1:p14X4Ok8S+sygzblytT1nqG98QG2KYKv++HE0LY/mhg= -go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys= -go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A= -go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= -go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= +go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg= +go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0 h1:dNzwXjZKpMpE2JhmO+9HsPl42NIXFIFSUSSs0fiqra0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0/go.mod h1:90PoxvaEB5n6AOdZvi+yWJQoE95U8Dhhw2bSyRqnTD0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.36.0 h1:JgtbA0xkWHnTmYk7YusopJFX6uleBmAuZ8n05NEh8nQ= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.36.0/go.mod h1:179AK5aar5R3eS9FucPy6rggvU0g52cvKId8pv4+v0c= +go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE= +go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs= +go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs= +go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY= +go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w= +go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA= +go.opentelemetry.io/proto/otlp v1.6.0 h1:jQjP+AQyTf+Fe7OKj/MfkDrmK4MNVtw2NpXsf9fefDI= +go.opentelemetry.io/proto/otlp v1.6.0/go.mod h1:cicgGehlFuNdgZkcALOCh3VE6K/u2tAjzlRhDwmVpZc= +go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= +go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8= 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.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= +go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= +go.yaml.in/yaml/v3 v3.0.3 h1:bXOww4E/J3f66rav3pX3m8w6jDE4knZjGOw8b5Y6iNE= +go.yaml.in/yaml/v3 v3.0.3/go.mod h1:tBHosrYAkRZjRAOREWbDnBXUf08JOwYq++0QNwQiWzI= 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.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= -golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= +golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM= +golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U= +golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 h1:1UoZQm6f0P/ZO0w1Ri+f+ifG/gXhegadRdwBIXEFWDo= +golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -261,16 +261,16 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= -golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= -golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= -golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw= +golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA= +golang.org/x/oauth2 v0.29.0 h1:WdYw2tdTK1S8olAzWHdgeqfy+Mtm9XNhv/xJsY65d98= +golang.org/x/oauth2 v0.29.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= -golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8= +golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 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= @@ -284,44 +284,43 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220908164124-27713097b956/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.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= -golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y= -golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= +golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= +golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg= +golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= -golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= -golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= -golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= +golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= +golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= +golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= -golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= +golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc= +golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI= 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/genproto v0.0.0-20230822172742-b8732ec3820d h1:VBu5YqKPv6XiJ199exd8Br+Aetz+o08F+PLMnwJQHAY= -google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc= -google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 h1:QCqS/PdaHTSWGvupk2F/ehwHtGc0/GYkT+3GAcR1CCc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= -google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= -google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0= +gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= +google.golang.org/genproto/googleapis/api v0.0.0-20250519155744-55703ea1f237 h1:Kog3KlB4xevJlAcbbbzPfRG0+X9fdoGM+UBRKVz6Wr0= +google.golang.org/genproto/googleapis/api v0.0.0-20250519155744-55703ea1f237/go.mod h1:ezi0AVyMKDWy5xAncvjLWH7UcLBB5n7y2fQ8MzjJcto= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237 h1:cJfm9zPbe1e873mHJzmQ1nwVEeRDU/T1wXDK2kUSU34= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/grpc v1.72.2 h1:TdbGzwb82ty4OusHWepvFWGLgIbNo1/SUynEN0ssqv8= +google.golang.org/grpc v1.72.2/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= -google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= @@ -336,48 +335,50 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.31.3 h1:umzm5o8lFbdN/hIXbrK9oRpOproJO62CV1zqxXrLgk8= -k8s.io/api v0.31.3/go.mod h1:UJrkIp9pnMOI9K2nlL6vwpxRzzEX5sWgn8kGQe92kCE= -k8s.io/apiextensions-apiserver v0.31.0 h1:fZgCVhGwsclj3qCw1buVXCV6khjRzKC5eCFt24kyLSk= -k8s.io/apiextensions-apiserver v0.31.0/go.mod h1:b9aMDEYaEe5sdK+1T0KU78ApR/5ZVp4i56VacZYEHxk= -k8s.io/apimachinery v0.31.3 h1:6l0WhcYgasZ/wk9ktLq5vLaoXJJr5ts6lkaQzgeYPq4= -k8s.io/apimachinery v0.31.3/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= -k8s.io/apiserver v0.31.0 h1:p+2dgJjy+bk+B1Csz+mc2wl5gHwvNkC9QJV+w55LVrY= -k8s.io/apiserver v0.31.0/go.mod h1:KI9ox5Yu902iBnnyMmy7ajonhKnkeZYJhTZ/YI+WEMk= -k8s.io/client-go v0.31.3 h1:CAlZuM+PH2cm+86LOBemaJI/lQ5linJ6UFxKX/SoG+4= -k8s.io/client-go v0.31.3/go.mod h1:2CgjPUTpv3fE5dNygAr2NcM8nhHzXvxB8KL5gYc3kJs= -k8s.io/cluster-bootstrap v0.30.3 h1:MgxyxMkpaC6mu0BKWJ8985XCOnKU+eH3Iy+biwtDXRk= -k8s.io/cluster-bootstrap v0.30.3/go.mod h1:h8BoLDfdD7XEEIXy7Bx9FcMzxHwz29jsYYi34bM5DKU= -k8s.io/component-base v0.31.3 h1:DMCXXVx546Rfvhj+3cOm2EUxhS+EyztH423j+8sOwhQ= -k8s.io/component-base v0.31.3/go.mod h1:xME6BHfUOafRgT0rGVBGl7TuSg8Z9/deT7qq6w7qjIU= +k8s.io/api v0.33.3 h1:SRd5t//hhkI1buzxb288fy2xvjubstenEKL9K51KBI8= +k8s.io/api v0.33.3/go.mod h1:01Y/iLUjNBM3TAvypct7DIj0M0NIZc+PzAHCIo0CYGE= +k8s.io/apiextensions-apiserver v0.33.0 h1:d2qpYL7Mngbsc1taA4IjJPRJ9ilnsXIrndH+r9IimOs= +k8s.io/apiextensions-apiserver v0.33.0/go.mod h1:VeJ8u9dEEN+tbETo+lFkwaaZPg6uFKLGj5vyNEwwSzc= +k8s.io/apimachinery v0.33.3 h1:4ZSrmNa0c/ZpZJhAgRdcsFcZOw1PQU1bALVQ0B3I5LA= +k8s.io/apimachinery v0.33.3/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM= +k8s.io/apiserver v0.33.0 h1:QqcM6c+qEEjkOODHppFXRiw/cE2zP85704YrQ9YaBbc= +k8s.io/apiserver v0.33.0/go.mod h1:EixYOit0YTxt8zrO2kBU7ixAtxFce9gKGq367nFmqI8= +k8s.io/client-go v0.33.3 h1:M5AfDnKfYmVJif92ngN532gFqakcGi6RvaOF16efrpA= +k8s.io/client-go v0.33.3/go.mod h1:luqKBQggEf3shbxHY4uVENAxrDISLOarxpTKMiUuujg= +k8s.io/cluster-bootstrap v0.32.3 h1:AqIpsUhB6MUeaAsl1WvaUw54AHRd2hfZrESlKChtd8s= +k8s.io/cluster-bootstrap v0.32.3/go.mod h1:CHbBwgOb6liDV6JFUTkx5t85T2xidy0sChBDoyYw344= +k8s.io/component-base v0.33.3 h1:mlAuyJqyPlKZM7FyaoM/LcunZaaY353RXiOd2+B5tGA= +k8s.io/component-base v0.33.3/go.mod h1:ktBVsBzkI3imDuxYXmVxZ2zxJnYTZ4HAsVj9iF09qp4= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 h1:hcha5B1kVACrLujCKLbr8XWMxCxzQx42DY8QKYJrDLg= -k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7/go.mod h1:GewRfANuJ70iYzvn+i4lezLDAFzvjxZYK1gn1lWcfas= -k8s.io/utils v0.0.0-20240921022957-49e7df575cb6 h1:MDF6h2H/h4tbzmtIKTuctcwZmY0tY9mD9fNT47QO6HI= -k8s.io/utils v0.0.0-20240921022957-49e7df575cb6/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 h1:2770sDpzrjjsAtVhSeUFseziht227YAWYHLGNM8QPwY= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= -sigs.k8s.io/cluster-api v1.8.5 h1:lNA2fPN4fkXEs+oOQlnwxT/4VwRFBpv5kkSoJG8nqBA= -sigs.k8s.io/cluster-api v1.8.5/go.mod h1:pXv5LqLxuIbhGIXykyNKiJh+KrLweSBajVHHitPLyoY= -sigs.k8s.io/controller-runtime v0.19.4 h1:SUmheabttt0nx8uJtoII4oIP27BVVvAKFvdvGFwV/Qo= -sigs.k8s.io/controller-runtime v0.19.4/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4= -sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= -sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/kustomize/api v0.19.0 h1:F+2HB2mU1MSiR9Hp1NEgoU2q9ItNOaBJl0I4Dlus5SQ= -sigs.k8s.io/kustomize/api v0.19.0/go.mod h1:/BbwnivGVcBh1r+8m3tH1VNxJmHSk1PzP5fkP6lbL1o= -sigs.k8s.io/kustomize/cmd/config v0.19.0 h1:D3uASwjHWHmNiEHu3pPJBJMBIsb+auFvHrHql3HAarU= -sigs.k8s.io/kustomize/cmd/config v0.19.0/go.mod h1:29Vvdl26PidPLUDi7nfjYa/I0wHBkwCZp15Nlcc4y98= -sigs.k8s.io/kustomize/kustomize/v5 v5.6.0 h1:MWtRRDWCwQEeW2rnJTqJMuV6Agy56P53SkbVoJpN7wA= -sigs.k8s.io/kustomize/kustomize/v5 v5.6.0/go.mod h1:XuuZiQF7WdcvZzEYyNww9A0p3LazCKeJmCjeycN8e1I= -sigs.k8s.io/kustomize/kyaml v0.19.0 h1:RFge5qsO1uHhwJsu3ipV7RNolC7Uozc0jUBC/61XSlA= -sigs.k8s.io/kustomize/kyaml v0.19.0/go.mod h1:FeKD5jEOH+FbZPpqUghBP8mrLjJ3+zD3/rf9NNu1cwY= -sigs.k8s.io/structured-merge-diff/v4 v4.5.0 h1:nbCitCK2hfnhyiKo6uf2HxUPTCodY6Qaf85SbDIaMBk= -sigs.k8s.io/structured-merge-diff/v4 v4.5.0/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4= -sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= +k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUyGcf03XZEP0ZIKgKj35LS4= +k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8= +k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= +k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 h1:jpcvIRr3GLoUoEKRkHKSmGjxb6lWwrBlJsXc+eUYQHM= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= +sigs.k8s.io/cluster-api v1.10.4 h1:5mdyWLGbbwOowWrjqM/J9N600QnxTohu5J1/1YR6g7c= +sigs.k8s.io/cluster-api v1.10.4/go.mod h1:68GJs286ZChsncp+TxYNj/vhy2NWokiPtH4+SA0afs0= +sigs.k8s.io/controller-runtime v0.21.0 h1:CYfjpEuicjUecRk+KAeyYh+ouUBn4llGyDYytIGcJS8= +sigs.k8s.io/controller-runtime v0.21.0/go.mod h1:OSg14+F65eWqIu4DceX7k/+QRAbTTvxeQSNSOQpukWM= +sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8= +sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo= +sigs.k8s.io/kustomize/api v0.20.1 h1:iWP1Ydh3/lmldBnH/S5RXgT98vWYMaTUL1ADcr+Sv7I= +sigs.k8s.io/kustomize/api v0.20.1/go.mod h1:t6hUFxO+Ph0VxIk1sKp1WS0dOjbPCtLJ4p8aADLwqjM= +sigs.k8s.io/kustomize/cmd/config v0.20.1 h1:4APUORmZe2BYrsqgGfEKdd/r7gM6i43egLrUzilpiFo= +sigs.k8s.io/kustomize/cmd/config v0.20.1/go.mod h1:R7rQ8kxknVlXWVUIbxWtMgu8DCCNVtl8V0KrmeVd/KE= +sigs.k8s.io/kustomize/kustomize/v5 v5.7.1 h1:sYJsarwy/SDJfjjLMUqwFDGPwzUtMOQ1i1Ed49+XSbw= +sigs.k8s.io/kustomize/kustomize/v5 v5.7.1/go.mod h1:+5/SrBcJ4agx1SJknGuR/c9thwRSKLxnKoI5BzXFaLU= +sigs.k8s.io/kustomize/kyaml v0.20.1 h1:PCMnA2mrVbRP3NIB6v9kYCAc38uvFLVs8j/CD567A78= +sigs.k8s.io/kustomize/kyaml v0.20.1/go.mod h1:0EmkQHRUsJxY8Ug9Niig1pUMSCGHxQ5RklbpV/Ri6po= +sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= +sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +sigs.k8s.io/structured-merge-diff/v4 v4.6.0 h1:IUA9nvMmnKWcj5jl84xn+T5MnlZKThmUW1TdblaLVAc= +sigs.k8s.io/structured-merge-diff/v4 v4.6.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= +sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= +sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= diff --git a/main.go b/main.go index 2f218d2c..0cefec56 100644 --- a/main.go +++ b/main.go @@ -37,12 +37,10 @@ import ( "sigs.k8s.io/controller-runtime/pkg/cache" "sigs.k8s.io/controller-runtime/pkg/controller" - rufiov1 "github.com/tinkerbell/rufio/api/v1alpha1" - tinkv1 "github.com/tinkerbell/tink/api/v1alpha1" - metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" infrastructurev1 "github.com/tinkerbell/cluster-api-provider-tinkerbell/api/v1beta1" + captctrl "github.com/tinkerbell/cluster-api-provider-tinkerbell/controller" "github.com/tinkerbell/cluster-api-provider-tinkerbell/controller/cluster" "github.com/tinkerbell/cluster-api-provider-tinkerbell/controller/machine" // +kubebuilder:scaffold:imports @@ -61,8 +59,8 @@ func init() { _ = clientgoscheme.AddToScheme(scheme) _ = infrastructurev1.AddToScheme(scheme) _ = clusterv1.AddToScheme(scheme) - _ = tinkv1.AddToScheme(scheme) - _ = rufiov1.AddToScheme(scheme) + _ = captctrl.AddToSchemeTinkerbell(scheme) + _ = captctrl.AddToSchemeBMC(scheme) // +kubebuilder:scaffold:scheme } @@ -101,27 +99,27 @@ func initFlags(fs *pflag.FlagSet) { //nolint:funlen &enableLeaderElection, "leader-elect", false, - "Enable leader election for controller manager. Enabling this will ensure there is only one active controller manager.", //nolint:lll + "Enable leader election for controller manager. Enabling this will ensure there is only one active controller manager.", ) fs.DurationVar( &leaderElectionLeaseDuration, "leader-elect-lease-duration", - 15*time.Second, //nolint:gomnd + 15*time.Second, "Interval at which non-leader candidates will wait to force acquire leadership (duration string)", ) fs.DurationVar( &leaderElectionRenewDeadline, "leader-elect-renew-deadline", - 10*time.Second, //nolint:gomnd + 10*time.Second, "Duration that the leading controller manager will retry refreshing leadership before giving up (duration string)", ) fs.DurationVar( &leaderElectionRetryPeriod, "leader-elect-retry-period", - 2*time.Second, //nolint:gomnd + 2*time.Second, "Duration the LeaderElector clients should wait between tries of actions (duration string)", ) @@ -136,7 +134,7 @@ func initFlags(fs *pflag.FlagSet) { //nolint:funlen &leaderElectionNamespace, "leader-election-namespace", "", - "Namespace that the controller performs leader election in. If unspecified, the controller will discover which namespace it is running in.", //nolint:lll + "Namespace that the controller performs leader election in. If unspecified, the controller will discover which namespace it is running in.", ) fs.StringVar( @@ -155,43 +153,43 @@ func initFlags(fs *pflag.FlagSet) { //nolint:funlen fs.IntVar(&tinkerbellClusterConcurrency, "tinkerbellcluster-concurrency", - 10, //nolint:gomnd + 10, "Number of TinkerbellClusters to process simultaneously", ) fs.IntVar(&tinkerbellMachineConcurrency, "tinkerbellmachine-concurrency", - 10, //nolint:gomnd + 10, "Number of TinkerbellMachines to process simultaneously", ) fs.IntVar(&tinkerbellHardwareConcurrency, "tinkerbell-hardware-concurrency", - 10, //nolint:gomnd + 10, "Number of Tinkerbell Hardware resources to process simultaneously", ) fs.IntVar(&tinkerbellTemplateConcurrency, "tinkerbell-template-concurrency", - 10, //nolint:gomnd + 10, "Number of Tinkerbell Template resources to process simultaneously", ) fs.IntVar(&tinkerbellWorkflowConcurrency, "tinkerbell-workflow-concurrency", - 10, //nolint:gomnd + 10, "Number of Tinkerbell Workflow resources to process simultaneously", ) fs.DurationVar(&syncPeriod, "sync-period", - 10*time.Minute, //nolint:gomnd + 10*time.Minute, "The minimum interval at which watched resources are reconciled (e.g. 15m)", ) fs.IntVar(&webhookPort, "webhook-port", - 9443, //nolint:gomnd + 9443, "Webhook Server port", ) @@ -224,14 +222,14 @@ func setupReconcilers(ctx context.Context, mgr ctrl.Manager) error { if err := (&cluster.TinkerbellClusterReconciler{ Client: mgr.GetClient(), WatchFilterValue: watchFilterValue, - }).SetupWithManager(ctx, mgr, controller.Options{MaxConcurrentReconciles: tinkerbellClusterConcurrency}); err != nil { + }).SetupWithManager(ctx, mgr, controller.Options{MaxConcurrentReconciles: tinkerbellClusterConcurrency}, mgr.GetScheme()); err != nil { return fmt.Errorf("unable to setup TinkerbellCluster controller:%w", err) } if err := (&machine.TinkerbellMachineReconciler{ Client: mgr.GetClient(), WatchFilterValue: watchFilterValue, - }).SetupWithManager(ctx, mgr, controller.Options{MaxConcurrentReconciles: tinkerbellMachineConcurrency}); err != nil { + }).SetupWithManager(ctx, mgr, controller.Options{MaxConcurrentReconciles: tinkerbellMachineConcurrency}, mgr.GetScheme()); err != nil { return fmt.Errorf("unable to setup TinkerbellMachine controller:%w", err) } @@ -280,7 +278,7 @@ func main() { //nolint:funlen // Machine and cluster operations can create enough events to trigger the event recorder spam filter // Setting the burst size higher ensures all events will be recorded and submitted to the API broadcaster := cgrecord.NewBroadcasterWithCorrelatorOptions(cgrecord.CorrelatorOptions{ - BurstSize: 100, //nolint:gomnd + BurstSize: 100, }) opts := ctrl.Options{ Scheme: scheme,