From 2d0bda93fb64f04628815327063057292c05f116 Mon Sep 17 00:00:00 2001 From: Simone Tiraboschi Date: Wed, 20 May 2026 15:28:35 +0200 Subject: [PATCH] chore: replace interface{} with any and enforce use-any lint rule Enable the revive use-any rule in .golangci.yml and replace all interface{} occurrences with any across the codebase. Also derive GOTOOLCHAIN and ENVTEST_K8S_VERSION from go.mod at runtime in the Makefile, and add GOTOOLCHAIN to the lint target to work around a golangci-lint panic caused by k8s.io v0.36 dependencies declaring go 1.26. Signed-off-by: Simone Tiraboschi --- .golangci.yml | 1 - Makefile | 8 +- pkg/assets/loader.go | 6 +- pkg/assets/loader_test.go | 46 ++++----- pkg/assets/registry.go | 2 +- pkg/context/render_context.go | 4 +- pkg/controller/hco_context_test.go | 12 +-- pkg/debug/handlers.go | 2 +- pkg/engine/applier_test.go | 28 +++--- pkg/engine/drift.go | 20 ++-- pkg/engine/drift_test.go | 94 ++++++++--------- pkg/engine/patcher.go | 2 +- pkg/engine/renderer.go | 18 ++-- pkg/engine/renderer_perf_tuning_test.go | 10 +- pkg/engine/renderer_prometheus_test.go | 60 +++++------ pkg/engine/renderer_test.go | 78 +++++++-------- pkg/engine/tombstone_test.go | 12 +-- pkg/overrides/jsonpatch.go | 2 +- pkg/overrides/jsonpatch_test.go | 50 ++++----- pkg/overrides/jsonpointer_test.go | 64 ++++++------ pkg/overrides/validation_test.go | 128 ++++++++++++------------ pkg/rbac/rbac.go | 2 +- pkg/util/events_test.go | 2 +- pkg/util/unstructured.go | 10 +- pkg/util/unstructured_test.go | 82 +++++++-------- test/anti_thrashing_integration_test.go | 28 +++--- test/asset_failure_test.go | 44 ++++---- test/controller_integration_test.go | 34 +++---- test/descheduler_crd_versions_test.go | 12 +-- test/drift_detection_test.go | 58 +++++------ test/e2e/anti_thrashing_e2e_test.go | 8 +- test/e2e/controller_e2e_test.go | 8 +- test/e2e/crd_lifecycle_test.go | 10 +- test/e2e/drift_test.go | 12 +-- test/events_integration_test.go | 58 +++++------ test/metrics_integration_test.go | 62 ++++++------ test/patcher_integration_test.go | 94 ++++++++--------- test/prometheus_rules_test.go | 48 ++++----- test/tombstone_integration_test.go | 8 +- 39 files changed, 614 insertions(+), 613 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index dc5b9831..8a922944 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -57,7 +57,6 @@ linters: disabled: true - name: useless-break - name: use-any - disabled: true - name: var-declaration - name: var-naming disabled: true diff --git a/Makefile b/Makefile index 59ce62d9..44b38c3c 100644 --- a/Makefile +++ b/Makefile @@ -21,8 +21,6 @@ goimport: test: fmt vet goimport ## Run unit tests go test ./pkg/... -coverprofile cover.out -# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary. -ENVTEST_K8S_VERSION = 1.35.0 ENVTEST = $(shell pwd)/bin/setup-envtest GINKGO = $(shell pwd)/bin/ginkgo @@ -32,6 +30,10 @@ GINKGO = $(shell pwd)/bin/ginkgo # which is how the sub-module is published and what `go install @` resolves to. CONTROLLER_RUNTIME_BRANCH := $(shell grep 'sigs.k8s.io/controller-runtime ' go.mod | awk '{print $$2}' | sed 's/v\([0-9]*\.[0-9]*\)\..*/release-\1/') GINKGO_VERSION := $(shell grep 'github.com/onsi/ginkgo/v2 ' go.mod | awk '{print $$2}') +# k8s.io/client-go v0.X.Y → envtest Kubernetes version 1.X.0 +ENVTEST_K8S_VERSION := $(shell grep 'k8s.io/client-go ' go.mod | awk '{print $$2}' | sed 's/v0\.\([0-9]*\)\..*/1.\1.0/') +# Go toolchain constraint for golangci-lint, matched to the go directive in go.mod +GOTOOLCHAIN := go$(shell grep '^go ' go.mod | awk '{print $$2}') .PHONY: test-integration test-integration: envtest ginkgo ## Run integration tests with envtest @@ -174,7 +176,7 @@ lint: ## Run golangci-lint echo "golangci-lint v2 not found. Installing..."; \ go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest; \ fi - $(GOLANGCI_LINT) run + GOTOOLCHAIN=$(GOTOOLCHAIN) $(GOLANGCI_LINT) run SHELLCHECK ?= $(shell which shellcheck) diff --git a/pkg/assets/loader.go b/pkg/assets/loader.go index 590a8be8..101bceff 100644 --- a/pkg/assets/loader.go +++ b/pkg/assets/loader.go @@ -150,9 +150,9 @@ func ParseYAML(data []byte) (*unstructured.Unstructured, error) { } // calculateDepth recursively calculates the maximum nesting depth of a map structure -func calculateDepth(obj interface{}) int { +func calculateDepth(obj any) int { switch v := obj.(type) { - case map[string]interface{}: + case map[string]any: maxDepth := 0 for _, value := range v { depth := calculateDepth(value) @@ -161,7 +161,7 @@ func calculateDepth(obj interface{}) int { } } return 1 + maxDepth - case []interface{}: + case []any: maxDepth := 0 for _, item := range v { depth := calculateDepth(item) diff --git a/pkg/assets/loader_test.go b/pkg/assets/loader_test.go index b6b79724..1ec3a246 100644 --- a/pkg/assets/loader_test.go +++ b/pkg/assets/loader_test.go @@ -366,7 +366,7 @@ func TestLoader_ListAssets(t *testing.T) { func TestCalculateDepth(t *testing.T) { tests := []struct { name string - obj interface{} + obj any expectedMax int description string }{ @@ -384,13 +384,13 @@ func TestCalculateDepth(t *testing.T) { }, { name: "empty map", - obj: map[string]interface{}{}, + obj: map[string]any{}, expectedMax: 1, description: "Empty map has depth 1", }, { name: "flat map", - obj: map[string]interface{}{ + obj: map[string]any{ "key1": "value1", "key2": "value2", }, @@ -399,9 +399,9 @@ func TestCalculateDepth(t *testing.T) { }, { name: "nested map", - obj: map[string]interface{}{ - "level1": map[string]interface{}{ - "level2": map[string]interface{}{ + obj: map[string]any{ + "level1": map[string]any{ + "level2": map[string]any{ "level3": "value", }, }, @@ -411,7 +411,7 @@ func TestCalculateDepth(t *testing.T) { }, { name: "array of strings", - obj: []interface{}{ + obj: []any{ "item1", "item2", }, @@ -420,8 +420,8 @@ func TestCalculateDepth(t *testing.T) { }, { name: "array of maps", - obj: []interface{}{ - map[string]interface{}{ + obj: []any{ + map[string]any{ "nested": "value", }, }, @@ -430,19 +430,19 @@ func TestCalculateDepth(t *testing.T) { }, { name: "complex nested structure", - obj: map[string]interface{}{ - "metadata": map[string]interface{}{ + obj: map[string]any{ + "metadata": map[string]any{ "name": "test", - "labels": map[string]interface{}{ + "labels": map[string]any{ "app": "myapp", }, }, - "spec": map[string]interface{}{ + "spec": map[string]any{ "replicas": 3, - "template": map[string]interface{}{ - "spec": map[string]interface{}{ - "containers": []interface{}{ - map[string]interface{}{ + "template": map[string]any{ + "spec": map[string]any{ + "containers": []any{ + map[string]any{ "name": "nginx", "image": "nginx:latest", }, @@ -456,17 +456,17 @@ func TestCalculateDepth(t *testing.T) { }, { name: "empty array", - obj: []interface{}{}, + obj: []any{}, expectedMax: 1, description: "Empty array has depth 1", }, { name: "deeply nested maps", - obj: map[string]interface{}{ - "l1": map[string]interface{}{ - "l2": map[string]interface{}{ - "l3": map[string]interface{}{ - "l4": map[string]interface{}{ + obj: map[string]any{ + "l1": map[string]any{ + "l2": map[string]any{ + "l3": map[string]any{ + "l4": map[string]any{ "l5": "deep", }, }, diff --git a/pkg/assets/registry.go b/pkg/assets/registry.go index f60ff050..7a5095ee 100644 --- a/pkg/assets/registry.go +++ b/pkg/assets/registry.go @@ -200,7 +200,7 @@ func extractRequiredCRD(content []byte, isTemplate bool) string { if doc == "" { continue } - var obj map[string]interface{} + var obj map[string]any if err := yaml.Unmarshal([]byte(doc), &obj); err != nil { continue } diff --git a/pkg/context/render_context.go b/pkg/context/render_context.go index 215de3ed..65545e2b 100644 --- a/pkg/context/render_context.go +++ b/pkg/context/render_context.go @@ -105,8 +105,8 @@ type TopologyContext struct { } // AsMap converts TopologyContext to a flat map for condition evaluation. -func (t *TopologyContext) AsMap() map[string]interface{} { - return map[string]interface{}{ +func (t *TopologyContext) AsMap() map[string]any { + return map[string]any{ "isHCP": t.IsHCP, "isCompact": t.IsCompact, "controlPlaneTopology": t.ControlPlaneTopology, diff --git a/pkg/controller/hco_context_test.go b/pkg/controller/hco_context_test.go index 50def530..0ce116bb 100644 --- a/pkg/controller/hco_context_test.go +++ b/pkg/controller/hco_context_test.go @@ -405,14 +405,14 @@ func workerOnlyNode(name string) corev1.Node { } func infraCR(cpTopology, platformType string) *unstructured.Unstructured { - status := map[string]interface{}{"controlPlaneTopology": cpTopology} + status := map[string]any{"controlPlaneTopology": cpTopology} if platformType != "" { - status["platformStatus"] = map[string]interface{}{"type": platformType} + status["platformStatus"] = map[string]any{"type": platformType} } - return &unstructured.Unstructured{Object: map[string]interface{}{ + return &unstructured.Unstructured{Object: map[string]any{ "apiVersion": "config.openshift.io/v1", "kind": "Infrastructure", - "metadata": map[string]interface{}{"name": "cluster"}, + "metadata": map[string]any{"name": "cluster"}, "status": status, }} } @@ -640,10 +640,10 @@ func TestRenderContextBuilder_Build(t *testing.T) { builder := NewRenderContextBuilder(fakeClient) hco := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "hco.kubevirt.io/v1", "kind": "HyperConverged", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "test-hco", "namespace": "test-namespace", }, diff --git a/pkg/debug/handlers.go b/pkg/debug/handlers.go index d0493a42..3d479296 100644 --- a/pkg/debug/handlers.go +++ b/pkg/debug/handlers.go @@ -423,7 +423,7 @@ func (s *Server) writeRenderResponse(w http.ResponseWriter, outputs []pkgrender. // writeResponse writes the response in the requested format (used for // non-render endpoints such as /debug/exclusions and /debug/tombstones). -func (s *Server) writeResponse(w http.ResponseWriter, data interface{}, format string) { +func (s *Server) writeResponse(w http.ResponseWriter, data any, format string) { var contentType string var output []byte var err error diff --git a/pkg/engine/applier_test.go b/pkg/engine/applier_test.go index e5fb24e2..27188725 100644 --- a/pkg/engine/applier_test.go +++ b/pkg/engine/applier_test.go @@ -31,9 +31,9 @@ func TestHasManagedByLabel(t *testing.T) { { name: "has correct managed-by label", obj: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "metadata": map[string]interface{}{ - "labels": map[string]interface{}{ + Object: map[string]any{ + "metadata": map[string]any{ + "labels": map[string]any{ ManagedByLabel: ManagedByValue, }, }, @@ -44,9 +44,9 @@ func TestHasManagedByLabel(t *testing.T) { { name: "has label with wrong value", obj: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "metadata": map[string]interface{}{ - "labels": map[string]interface{}{ + Object: map[string]any{ + "metadata": map[string]any{ + "labels": map[string]any{ ManagedByLabel: "wrong-value", }, }, @@ -57,8 +57,8 @@ func TestHasManagedByLabel(t *testing.T) { { name: "has no labels", obj: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "metadata": map[string]interface{}{}, + Object: map[string]any{ + "metadata": map[string]any{}, }, }, want: false, @@ -66,9 +66,9 @@ func TestHasManagedByLabel(t *testing.T) { { name: "has other labels but not managed-by", obj: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "metadata": map[string]interface{}{ - "labels": map[string]interface{}{ + Object: map[string]any{ + "metadata": map[string]any{ + "labels": map[string]any{ "app": "test", }, }, @@ -79,9 +79,9 @@ func TestHasManagedByLabel(t *testing.T) { { name: "has managed-by label among others", obj: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "metadata": map[string]interface{}{ - "labels": map[string]interface{}{ + Object: map[string]any{ + "metadata": map[string]any{ + "labels": map[string]any{ "app": "test", ManagedByLabel: ManagedByValue, "environment": "prod", diff --git a/pkg/engine/drift.go b/pkg/engine/drift.go index 5fc67bfc..c73a1968 100644 --- a/pkg/engine/drift.go +++ b/pkg/engine/drift.go @@ -105,7 +105,7 @@ func (d *DriftDetector) SimpleDriftCheck(desired, live *unstructured.Unstructure } // sanitizeObject removes fields that should not be compared for drift -func sanitizeObject(obj *unstructured.Unstructured) map[string]interface{} { +func sanitizeObject(obj *unstructured.Unstructured) map[string]any { if obj == nil { return nil } @@ -113,7 +113,7 @@ func sanitizeObject(obj *unstructured.Unstructured) map[string]interface{} { sanitized := obj.DeepCopy().Object // Remove metadata fields that change on every update - if metadata, ok := sanitized["metadata"].(map[string]interface{}); ok { + if metadata, ok := sanitized["metadata"].(map[string]any); ok { // Keep: name, namespace, labels, annotations // Remove: resourceVersion, generation, uid, creationTimestamp, managedFields, etc. fieldsToKeep := map[string]bool{ @@ -123,7 +123,7 @@ func sanitizeObject(obj *unstructured.Unstructured) map[string]interface{} { "annotations": true, } - sanitizedMetadata := make(map[string]interface{}) + sanitizedMetadata := make(map[string]any) for key, value := range metadata { if fieldsToKeep[key] { sanitizedMetadata[key] = value @@ -142,29 +142,29 @@ func sanitizeObject(obj *unstructured.Unstructured) map[string]interface{} { // structuredDiff returns a map containing only the fields that differ between // live and desired. Leaf differences are represented as {"live": , "desired": }, // so the result can be logged directly as a structured value. -func structuredDiff(live, desired map[string]interface{}) map[string]interface{} { - result := make(map[string]interface{}) +func structuredDiff(live, desired map[string]any) map[string]any { + result := make(map[string]any) for k, liveVal := range live { desiredVal, ok := desired[k] if !ok { - result[k] = map[string]interface{}{"live": liveVal, "desired": nil} + result[k] = map[string]any{"live": liveVal, "desired": nil} continue } - liveMap, liveIsMap := liveVal.(map[string]interface{}) - desiredMap, desiredIsMap := desiredVal.(map[string]interface{}) + liveMap, liveIsMap := liveVal.(map[string]any) + desiredMap, desiredIsMap := desiredVal.(map[string]any) if liveIsMap && desiredIsMap { if sub := structuredDiff(liveMap, desiredMap); len(sub) > 0 { result[k] = sub } } else if !equality.Semantic.DeepEqual(liveVal, desiredVal) { - result[k] = map[string]interface{}{"live": liveVal, "desired": desiredVal} + result[k] = map[string]any{"live": liveVal, "desired": desiredVal} } } for k, desiredVal := range desired { if _, ok := live[k]; !ok { - result[k] = map[string]interface{}{"live": nil, "desired": desiredVal} + result[k] = map[string]any{"live": nil, "desired": desiredVal} } } diff --git a/pkg/engine/drift_test.go b/pkg/engine/drift_test.go index b48a0b42..e3714c73 100644 --- a/pkg/engine/drift_test.go +++ b/pkg/engine/drift_test.go @@ -37,12 +37,12 @@ func (c *errApplyClient) Apply(_ context.Context, _ runtime.ApplyConfiguration, return c.applyErr } -func makeObj(labels map[string]string, spec map[string]interface{}) *unstructured.Unstructured { +func makeObj(labels map[string]string, spec map[string]any) *unstructured.Unstructured { obj := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "test", "namespace": "default", }, @@ -68,20 +68,20 @@ func TestSimpleDriftCheck(t *testing.T) { }{ { name: "identical objects, no labels", - desired: makeObj(nil, map[string]interface{}{"key": "value"}), - live: makeObj(nil, map[string]interface{}{"key": "value"}), + desired: makeObj(nil, map[string]any{"key": "value"}), + live: makeObj(nil, map[string]any{"key": "value"}), want: false, }, { name: "both have managed-by label, spec equal", - desired: makeObj(map[string]string{ManagedByLabel: ManagedByValue}, map[string]interface{}{"key": "value"}), - live: makeObj(map[string]string{ManagedByLabel: ManagedByValue}, map[string]interface{}{"key": "value"}), + desired: makeObj(map[string]string{ManagedByLabel: ManagedByValue}, map[string]any{"key": "value"}), + live: makeObj(map[string]string{ManagedByLabel: ManagedByValue}, map[string]any{"key": "value"}), want: false, }, { name: "spec differs", - desired: makeObj(map[string]string{ManagedByLabel: ManagedByValue}, map[string]interface{}{"key": "a"}), - live: makeObj(map[string]string{ManagedByLabel: ManagedByValue}, map[string]interface{}{"key": "b"}), + desired: makeObj(map[string]string{ManagedByLabel: ManagedByValue}, map[string]any{"key": "a"}), + live: makeObj(map[string]string{ManagedByLabel: ManagedByValue}, map[string]any{"key": "b"}), want: true, }, { @@ -91,8 +91,8 @@ func TestSimpleDriftCheck(t *testing.T) { // always present on the live object will show up as spurious drift on // every reconciliation cycle, causing unnecessary applies and events. name: "regression: managed-by label only on live causes false drift when desired not labeled", - desired: makeObj(nil, map[string]interface{}{"key": "value"}), - live: makeObj(map[string]string{ManagedByLabel: ManagedByValue}, map[string]interface{}{"key": "value"}), + desired: makeObj(nil, map[string]any{"key": "value"}), + live: makeObj(map[string]string{ManagedByLabel: ManagedByValue}, map[string]any{"key": "value"}), want: true, // this is the bug: drift is wrongly detected }, { @@ -101,11 +101,11 @@ func TestSimpleDriftCheck(t *testing.T) { // spurious drift is reported. name: "fix: no spurious drift when desired is labeled before comparison", desired: func() *unstructured.Unstructured { - obj := makeObj(nil, map[string]interface{}{"key": "value"}) + obj := makeObj(nil, map[string]any{"key": "value"}) ensureManagedByLabel(obj) // what ReconcileAsset now does before drift check return obj }(), - live: makeObj(map[string]string{ManagedByLabel: ManagedByValue}, map[string]interface{}{"key": "value"}), + live: makeObj(map[string]string{ManagedByLabel: ManagedByValue}, map[string]any{"key": "value"}), want: false, }, { @@ -149,8 +149,8 @@ func TestCompareSpecs(t *testing.T) { name: "first nil", obj1: nil, obj2: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "spec": map[string]interface{}{"replicas": 3}, + Object: map[string]any{ + "spec": map[string]any{"replicas": 3}, }, }, want: false, @@ -158,8 +158,8 @@ func TestCompareSpecs(t *testing.T) { { name: "second nil", obj1: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "spec": map[string]interface{}{"replicas": 3}, + Object: map[string]any{ + "spec": map[string]any{"replicas": 3}, }, }, obj2: nil, @@ -168,18 +168,18 @@ func TestCompareSpecs(t *testing.T) { { name: "identical specs", obj1: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "spec": map[string]interface{}{ + Object: map[string]any{ + "spec": map[string]any{ "replicas": int64(3), - "selector": map[string]interface{}{"app": "test"}, + "selector": map[string]any{"app": "test"}, }, }, }, obj2: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "spec": map[string]interface{}{ + Object: map[string]any{ + "spec": map[string]any{ "replicas": int64(3), - "selector": map[string]interface{}{"app": "test"}, + "selector": map[string]any{"app": "test"}, }, }, }, @@ -188,13 +188,13 @@ func TestCompareSpecs(t *testing.T) { { name: "different specs", obj1: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "spec": map[string]interface{}{"replicas": int64(3)}, + Object: map[string]any{ + "spec": map[string]any{"replicas": int64(3)}, }, }, obj2: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "spec": map[string]interface{}{"replicas": int64(5)}, + Object: map[string]any{ + "spec": map[string]any{"replicas": int64(5)}, }, }, want: false, @@ -202,13 +202,13 @@ func TestCompareSpecs(t *testing.T) { { name: "both have no spec", obj1: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "metadata": map[string]interface{}{"name": "test"}, + Object: map[string]any{ + "metadata": map[string]any{"name": "test"}, }, }, obj2: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "metadata": map[string]interface{}{"name": "test"}, + Object: map[string]any{ + "metadata": map[string]any{"name": "test"}, }, }, want: true, @@ -216,13 +216,13 @@ func TestCompareSpecs(t *testing.T) { { name: "only first has spec", obj1: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "spec": map[string]interface{}{"replicas": int64(3)}, + Object: map[string]any{ + "spec": map[string]any{"replicas": int64(3)}, }, }, obj2: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "metadata": map[string]interface{}{"name": "test"}, + Object: map[string]any{ + "metadata": map[string]any{"name": "test"}, }, }, want: false, @@ -230,13 +230,13 @@ func TestCompareSpecs(t *testing.T) { { name: "only second has spec", obj1: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "metadata": map[string]interface{}{"name": "test"}, + Object: map[string]any{ + "metadata": map[string]any{"name": "test"}, }, }, obj2: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "spec": map[string]interface{}{"replicas": int64(3)}, + Object: map[string]any{ + "spec": map[string]any{"replicas": int64(3)}, }, }, want: false, @@ -244,15 +244,15 @@ func TestCompareSpecs(t *testing.T) { { name: "metadata differs but specs identical", obj1: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "metadata": map[string]interface{}{"name": "test1"}, - "spec": map[string]interface{}{"replicas": int64(3)}, + Object: map[string]any{ + "metadata": map[string]any{"name": "test1"}, + "spec": map[string]any{"replicas": int64(3)}, }, }, obj2: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "metadata": map[string]interface{}{"name": "test2"}, - "spec": map[string]interface{}{"replicas": int64(3)}, + Object: map[string]any{ + "metadata": map[string]any{"name": "test2"}, + "spec": map[string]any{"replicas": int64(3)}, }, }, want: true, @@ -285,8 +285,8 @@ func TestDetectDriftPropagatesClientError(t *testing.T) { } dd := NewDriftDetector(c) - desired := makeObj(nil, map[string]interface{}{"key": "value"}) - live := makeObj(nil, map[string]interface{}{"key": "value"}) + desired := makeObj(nil, map[string]any{"key": "value"}) + live := makeObj(nil, map[string]any{"key": "value"}) _, err := dd.DetectDrift(context.Background(), desired, live) if err == nil { diff --git a/pkg/engine/patcher.go b/pkg/engine/patcher.go index c65ce10c..1111e35f 100644 --- a/pkg/engine/patcher.go +++ b/pkg/engine/patcher.go @@ -524,7 +524,7 @@ func isNamespaceNotFound(err error) bool { // countJSONPatchOperations counts the number of operations in a JSON patch string // Returns the count or 0 if parsing fails func countJSONPatchOperations(patchStr string) int { - var patch []map[string]interface{} + var patch []map[string]any if err := json.Unmarshal([]byte(patchStr), &patch); err != nil { return 0 } diff --git a/pkg/engine/renderer.go b/pkg/engine/renderer.go index 74ed46db..f3db5b22 100644 --- a/pkg/engine/renderer.go +++ b/pkg/engine/renderer.go @@ -233,7 +233,7 @@ func (r *Renderer) customFuncMap() template.FuncMap { // dig safely accesses nested fields with a default value // This is already provided by sprig, but we include it for clarity -func dig(keys ...interface{}) interface{} { +func dig(keys ...any) any { if len(keys) < 2 { return nil } @@ -250,7 +250,7 @@ func dig(keys ...interface{}) interface{} { // Navigate through the path current := obj for _, key := range pathKeys { - if m, ok := current.(map[string]interface{}); ok { + if m, ok := current.(map[string]any); ok { keyStr, ok := key.(string) if !ok { return defaultVal @@ -269,9 +269,9 @@ func dig(keys ...interface{}) interface{} { } // has checks if a slice contains a value -func has(needle interface{}, haystack interface{}) bool { +func has(needle any, haystack any) bool { switch h := haystack.(type) { - case []interface{}: + case []any: for _, item := range h { if item == needle { return true @@ -470,30 +470,30 @@ func (r *Renderer) prometheusRuleHasRecordingRuleFunc() func(string, string, str } // Navigate to spec.groups[].rules[] - spec, ok := obj.Object["spec"].(map[string]interface{}) + spec, ok := obj.Object["spec"].(map[string]any) if !ok { return false } - groups, ok := spec["groups"].([]interface{}) + groups, ok := spec["groups"].([]any) if !ok { return false } // Search through all groups and rules for _, group := range groups { - groupMap, ok := group.(map[string]interface{}) + groupMap, ok := group.(map[string]any) if !ok { continue } - rules, ok := groupMap["rules"].([]interface{}) + rules, ok := groupMap["rules"].([]any) if !ok { continue } for _, rule := range rules { - ruleMap, ok := rule.(map[string]interface{}) + ruleMap, ok := rule.(map[string]any) if !ok { continue } diff --git a/pkg/engine/renderer_perf_tuning_test.go b/pkg/engine/renderer_perf_tuning_test.go index eece14f7..8bdffec4 100644 --- a/pkg/engine/renderer_perf_tuning_test.go +++ b/pkg/engine/renderer_perf_tuning_test.go @@ -78,9 +78,9 @@ func TestHCOGoldenConfigPreservesCertConfig(t *testing.T) { hco.SetNamespace("openshift-cnv") // Simulate a user-configured certConfig - err = unstructured.SetNestedMap(hco.Object, map[string]interface{}{ - "ca": map[string]interface{}{"duration": "24h0m0s", "renewBefore": "12h0m0s"}, - "server": map[string]interface{}{"duration": "12h0m0s", "renewBefore": "6h0m0s"}, + err = unstructured.SetNestedMap(hco.Object, map[string]any{ + "ca": map[string]any{"duration": "24h0m0s", "renewBefore": "12h0m0s"}, + "server": map[string]any{"duration": "12h0m0s", "renewBefore": "6h0m0s"}, }, "spec", "certConfig") if err != nil { t.Fatalf("Failed to set certConfig in HCO: %v", err) @@ -290,14 +290,14 @@ func TestCPUManagerReservedMemory(t *testing.T) { t.Errorf("reservedMemory length = %d, want 1", len(reservedMem)) } - node0, ok := reservedMem[0].(map[string]interface{}) + node0, ok := reservedMem[0].(map[string]any) if !ok { t.Fatal("reservedMemory[0] is not a map") } if numa, ok := node0["numaNode"].(int64); !ok || numa != 0 { t.Errorf("numaNode = %v, want 0", node0["numaNode"]) } - limits, ok := node0["limits"].(map[string]interface{}) + limits, ok := node0["limits"].(map[string]any) if !ok { t.Fatal("limits is not a map") } diff --git a/pkg/engine/renderer_prometheus_test.go b/pkg/engine/renderer_prometheus_test.go index 72d0ee63..f15e64ff 100644 --- a/pkg/engine/renderer_prometheus_test.go +++ b/pkg/engine/renderer_prometheus_test.go @@ -33,10 +33,10 @@ func TestPrometheusRuleIntrospection(t *testing.T) { t.Run("objectExists returns true when object exists", func(t *testing.T) { // Create a fake PrometheusRule prometheusRule := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "monitoring.coreos.com/v1", "kind": "PrometheusRule", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "descheduler-rules", "namespace": "openshift-kube-descheduler-operator", }, @@ -82,23 +82,23 @@ func TestPrometheusRuleIntrospection(t *testing.T) { t.Run("prometheusRuleHasRecordingRule returns true when rule exists", func(t *testing.T) { // Create a PrometheusRule with the specific recording rule prometheusRule := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "monitoring.coreos.com/v1", "kind": "PrometheusRule", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "descheduler-rules", "namespace": "openshift-kube-descheduler-operator", }, - "spec": map[string]interface{}{ - "groups": []interface{}{ - map[string]interface{}{ + "spec": map[string]any{ + "groups": []any{ + map[string]any{ "name": "descheduler", - "rules": []interface{}{ - map[string]interface{}{ + "rules": []any{ + map[string]any{ "record": "descheduler:node:linear_amplified_ideal_point_positive_distance:k3:avg1m", "expr": "some_query", }, - map[string]interface{}{ + map[string]any{ "record": "some_other_rule", "expr": "some_other_query", }, @@ -130,19 +130,19 @@ func TestPrometheusRuleIntrospection(t *testing.T) { t.Run("prometheusRuleHasRecordingRule returns false when rule does not exist", func(t *testing.T) { // Create a PrometheusRule without the specific rule prometheusRule := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "monitoring.coreos.com/v1", "kind": "PrometheusRule", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "descheduler-rules", "namespace": "openshift-kube-descheduler-operator", }, - "spec": map[string]interface{}{ - "groups": []interface{}{ - map[string]interface{}{ + "spec": map[string]any{ + "groups": []any{ + map[string]any{ "name": "descheduler", - "rules": []interface{}{ - map[string]interface{}{ + "rules": []any{ + map[string]any{ "record": "some_other_rule", "expr": "some_query", }, @@ -174,19 +174,19 @@ func TestPrometheusRuleIntrospection(t *testing.T) { t.Run("template renders with devActualUtilizationProfile based on PrometheusRule", func(t *testing.T) { // Create a PrometheusRule with the k3 rule prometheusRule := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "monitoring.coreos.com/v1", "kind": "PrometheusRule", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "descheduler-rules", "namespace": "openshift-kube-descheduler-operator", }, - "spec": map[string]interface{}{ - "groups": []interface{}{ - map[string]interface{}{ + "spec": map[string]any{ + "groups": []any{ + map[string]any{ "name": "descheduler", - "rules": []interface{}{ - map[string]interface{}{ + "rules": []any{ + map[string]any{ "record": "descheduler:node:linear_amplified_ideal_point_positive_distance:k3:avg1m", "expr": "some_query", }, @@ -235,18 +235,18 @@ devActualUtilizationProfile: {{ $devActualUtilizationProfile }} t.Run("template uses fallback profile when k3 rule not found", func(t *testing.T) { // Create a PrometheusRule without the k3 rule prometheusRule := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "monitoring.coreos.com/v1", "kind": "PrometheusRule", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "descheduler-rules", "namespace": "openshift-kube-descheduler-operator", }, - "spec": map[string]interface{}{ - "groups": []interface{}{ - map[string]interface{}{ + "spec": map[string]any{ + "groups": []any{ + map[string]any{ "name": "descheduler", - "rules": []interface{}{}, + "rules": []any{}, }, }, }, diff --git a/pkg/engine/renderer_test.go b/pkg/engine/renderer_test.go index b5ab0821..00cdbc85 100644 --- a/pkg/engine/renderer_test.go +++ b/pkg/engine/renderer_test.go @@ -29,17 +29,17 @@ import ( func TestDig(t *testing.T) { tests := []struct { name string - keys []interface{} - want interface{} + keys []any + want any }{ { name: "access nested field successfully", - keys: []interface{}{ + keys: []any{ "spec", "replicas", "default", - map[string]interface{}{ - "spec": map[string]interface{}{ + map[string]any{ + "spec": map[string]any{ "replicas": int64(5), }, }, @@ -48,12 +48,12 @@ func TestDig(t *testing.T) { }, { name: "field not found returns default", - keys: []interface{}{ + keys: []any{ "spec", "missing", "default-value", - map[string]interface{}{ - "spec": map[string]interface{}{ + map[string]any{ + "spec": map[string]any{ "replicas": int64(5), }, }, @@ -62,16 +62,16 @@ func TestDig(t *testing.T) { }, { name: "deep nesting", - keys: []interface{}{ + keys: []any{ "spec", "template", "spec", "containers", 99, - map[string]interface{}{ - "spec": map[string]interface{}{ - "template": map[string]interface{}{ - "spec": map[string]interface{}{ + map[string]any{ + "spec": map[string]any{ + "template": map[string]any{ + "spec": map[string]any{ "containers": "found", }, }, @@ -82,17 +82,17 @@ func TestDig(t *testing.T) { }, { name: "less than 2 arguments returns nil", - keys: []interface{}{ - map[string]interface{}{}, + keys: []any{ + map[string]any{}, }, want: nil, }, { name: "non-string key returns default", - keys: []interface{}{ + keys: []any{ 123, // non-string key "default", - map[string]interface{}{ + map[string]any{ "field": "value", }, }, @@ -100,7 +100,7 @@ func TestDig(t *testing.T) { }, { name: "non-map object returns default", - keys: []interface{}{ + keys: []any{ "field", "default", "not-a-map", @@ -122,8 +122,8 @@ func TestDig(t *testing.T) { func TestHas(t *testing.T) { tests := []struct { name string - needle interface{} - haystack interface{} + needle any + haystack any want bool }{ { @@ -141,13 +141,13 @@ func TestHas(t *testing.T) { { name: "value in interface slice", needle: "test", - haystack: []interface{}{"test", "other"}, + haystack: []any{"test", "other"}, want: true, }, { name: "value not in interface slice", needle: "missing", - haystack: []interface{}{"test", "other"}, + haystack: []any{"test", "other"}, want: false, }, { @@ -165,7 +165,7 @@ func TestHas(t *testing.T) { { name: "empty interface slice", needle: "value", - haystack: []interface{}{}, + haystack: []any{}, want: false, }, { @@ -244,7 +244,7 @@ func TestSafeFuncMap(t *testing.T) { } // assertFunctionsExist checks that all expected functions are present in the funcMap -func assertFunctionsExist(t *testing.T, funcMap map[string]interface{}, expectedFuncs []string) { +func assertFunctionsExist(t *testing.T, funcMap map[string]any, expectedFuncs []string) { t.Helper() for _, name := range expectedFuncs { if _, exists := funcMap[name]; !exists { @@ -254,7 +254,7 @@ func assertFunctionsExist(t *testing.T, funcMap map[string]interface{}, expected } // assertFunctionsNotExist checks that dangerous functions are not present in the funcMap -func assertFunctionsNotExist(t *testing.T, funcMap map[string]interface{}, dangerousFuncs []string) { +func assertFunctionsNotExist(t *testing.T, funcMap map[string]any, dangerousFuncs []string) { t.Helper() for _, name := range dangerousFuncs { if _, exists := funcMap[name]; exists { @@ -312,8 +312,8 @@ func TestRenderTemplate(t *testing.T) { t.Run("renders simple template", func(t *testing.T) { ctx := &pkgcontext.RenderContext{ HCO: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "metadata": map[string]interface{}{ + Object: map[string]any{ + "metadata": map[string]any{ "name": "test-hco", }, }, @@ -335,8 +335,8 @@ func TestRenderTemplate(t *testing.T) { t.Run("uses safe functions", func(t *testing.T) { ctx := &pkgcontext.RenderContext{ HCO: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "metadata": map[string]interface{}{ + Object: map[string]any{ + "metadata": map[string]any{ "name": "test", }, }, @@ -356,9 +356,9 @@ func TestRenderTemplate(t *testing.T) { }) t.Run("uses custom dig function", func(t *testing.T) { - hcoObj := map[string]interface{}{ - "spec": map[string]interface{}{ - "nested": map[string]interface{}{ + hcoObj := map[string]any{ + "spec": map[string]any{ + "nested": map[string]any{ "field": "value", }, }, @@ -384,7 +384,7 @@ func TestRenderTemplate(t *testing.T) { t.Run("handles hardware context", func(t *testing.T) { ctx := &pkgcontext.RenderContext{ HCO: &unstructured.Unstructured{ - Object: map[string]interface{}{}, + Object: map[string]any{}, }, Hardware: &pkgcontext.HardwareContext{ GPUPresent: true, @@ -405,7 +405,7 @@ func TestRenderTemplate(t *testing.T) { t.Run("returns error for invalid template", func(t *testing.T) { ctx := &pkgcontext.RenderContext{ HCO: &unstructured.Unstructured{ - Object: map[string]interface{}{}, + Object: map[string]any{}, }, } @@ -419,7 +419,7 @@ func TestRenderTemplate(t *testing.T) { t.Run("returns error for undefined function", func(t *testing.T) { ctx := &pkgcontext.RenderContext{ HCO: &unstructured.Unstructured{ - Object: map[string]interface{}{}, + Object: map[string]any{}, }, } @@ -444,7 +444,7 @@ func TestRenderAsset(t *testing.T) { ctx := &pkgcontext.RenderContext{ HCO: &unstructured.Unstructured{ - Object: map[string]interface{}{}, + Object: map[string]any{}, }, } @@ -469,7 +469,7 @@ func TestRenderAsset(t *testing.T) { ctx := &pkgcontext.RenderContext{ HCO: &unstructured.Unstructured{ - Object: map[string]interface{}{}, + Object: map[string]any{}, }, } @@ -496,7 +496,7 @@ func TestRenderMultiAsset(t *testing.T) { ctx := &pkgcontext.RenderContext{ HCO: &unstructured.Unstructured{ - Object: map[string]interface{}{}, + Object: map[string]any{}, }, } @@ -521,7 +521,7 @@ func TestRenderMultiAsset(t *testing.T) { ctx := &pkgcontext.RenderContext{ HCO: &unstructured.Unstructured{ - Object: map[string]interface{}{}, + Object: map[string]any{}, }, } diff --git a/pkg/engine/tombstone_test.go b/pkg/engine/tombstone_test.go index 2889602f..7635d14c 100644 --- a/pkg/engine/tombstone_test.go +++ b/pkg/engine/tombstone_test.go @@ -104,7 +104,7 @@ var _ = Describe("Tombstone Reconciler", func() { resource.SetLabels(map[string]string{ assets.TombstoneLabel: assets.TombstoneLabelValue, }) - resource.Object["data"] = map[string]interface{}{"key": "value"} + resource.Object["data"] = map[string]any{"key": "value"} Expect(fakeClient.Create(ctx, resource)).To(Succeed()) @@ -128,7 +128,7 @@ var _ = Describe("Tombstone Reconciler", func() { resource.SetKind("ConfigMap") resource.SetName("test-config") resource.SetNamespace("default") - resource.Object["data"] = map[string]interface{}{"key": "value"} + resource.Object["data"] = map[string]any{"key": "value"} Expect(fakeClient.Create(ctx, resource)).To(Succeed()) @@ -155,7 +155,7 @@ var _ = Describe("Tombstone Reconciler", func() { resource.SetLabels(map[string]string{ assets.TombstoneLabel: "wrong-value", }) - resource.Object["data"] = map[string]interface{}{"key": "value"} + resource.Object["data"] = map[string]any{"key": "value"} Expect(fakeClient.Create(ctx, resource)).To(Succeed()) @@ -213,7 +213,7 @@ var _ = Describe("Tombstone Reconciler", func() { resource.SetLabels(map[string]string{ assets.TombstoneLabel: assets.TombstoneLabelValue, }) - resource.Object["spec"] = map[string]interface{}{"config": "test"} + resource.Object["spec"] = map[string]any{"config": "test"} Expect(fakeClient.Create(ctx, resource)).To(Succeed()) @@ -240,7 +240,7 @@ var _ = Describe("Tombstone Reconciler", func() { resource.SetLabels(map[string]string{ assets.TombstoneLabel: assets.TombstoneLabelValue, }) - resource.Object["data"] = map[string]interface{}{"key": "value"} + resource.Object["data"] = map[string]any{"key": "value"} Expect(fakeClient.Create(ctx, resource)).To(Succeed()) @@ -261,7 +261,7 @@ var _ = Describe("Tombstone Reconciler", func() { resource.SetKind("ConfigMap") resource.SetName("test-config") resource.SetNamespace("default") - resource.Object["data"] = map[string]interface{}{"key": "value"} + resource.Object["data"] = map[string]any{"key": "value"} Expect(fakeClient.Create(ctx, resource)).To(Succeed()) diff --git a/pkg/overrides/jsonpatch.go b/pkg/overrides/jsonpatch.go index 2f29b6ba..cc8463c9 100644 --- a/pkg/overrides/jsonpatch.go +++ b/pkg/overrides/jsonpatch.go @@ -66,7 +66,7 @@ func ApplyJSONPatch(obj *unstructured.Unstructured) (bool, error) { } // Unmarshal back into the object - var patchedObj map[string]interface{} + var patchedObj map[string]any if err := json.Unmarshal(patchedJSON, &patchedObj); err != nil { return false, fmt.Errorf("failed to unmarshal patched JSON: %w", err) } diff --git a/pkg/overrides/jsonpatch_test.go b/pkg/overrides/jsonpatch_test.go index dd8c1737..072d9fa2 100644 --- a/pkg/overrides/jsonpatch_test.go +++ b/pkg/overrides/jsonpatch_test.go @@ -34,13 +34,13 @@ func TestApplyJSONPatch(t *testing.T) { { name: "no patch annotation", obj: &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "test", }, - "data": map[string]interface{}{ + "data": map[string]any{ "key": "value", }, }, @@ -51,16 +51,16 @@ func TestApplyJSONPatch(t *testing.T) { { name: "add operation", obj: &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "test", - "annotations": map[string]interface{}{ + "annotations": map[string]any{ PatchAnnotation: `[{"op": "add", "path": "/data/newKey", "value": "newValue"}]`, }, }, - "data": map[string]interface{}{ + "data": map[string]any{ "key": "value", }, }, @@ -80,16 +80,16 @@ func TestApplyJSONPatch(t *testing.T) { { name: "replace operation", obj: &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "test", - "annotations": map[string]interface{}{ + "annotations": map[string]any{ PatchAnnotation: `[{"op": "replace", "path": "/data/key", "value": "newValue"}]`, }, }, - "data": map[string]interface{}{ + "data": map[string]any{ "key": "value", }, }, @@ -106,16 +106,16 @@ func TestApplyJSONPatch(t *testing.T) { { name: "remove operation", obj: &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "test", - "annotations": map[string]interface{}{ + "annotations": map[string]any{ PatchAnnotation: `[{"op": "remove", "path": "/data/key"}]`, }, }, - "data": map[string]interface{}{ + "data": map[string]any{ "key": "value", "other": "data", }, @@ -136,19 +136,19 @@ func TestApplyJSONPatch(t *testing.T) { { name: "multiple operations", obj: &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "test", - "annotations": map[string]interface{}{ + "annotations": map[string]any{ PatchAnnotation: `[ {"op": "replace", "path": "/data/key", "value": "updated"}, {"op": "add", "path": "/data/new", "value": "added"} ]`, }, }, - "data": map[string]interface{}{ + "data": map[string]any{ "key": "value", }, }, @@ -168,12 +168,12 @@ func TestApplyJSONPatch(t *testing.T) { { name: "invalid patch JSON", obj: &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "test", - "annotations": map[string]interface{}{ + "annotations": map[string]any{ PatchAnnotation: `not valid json`, }, }, @@ -185,12 +185,12 @@ func TestApplyJSONPatch(t *testing.T) { { name: "invalid patch operation", obj: &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "test", - "annotations": map[string]interface{}{ + "annotations": map[string]any{ PatchAnnotation: `[{"op": "invalid", "path": "/data/key"}]`, }, }, diff --git a/pkg/overrides/jsonpointer_test.go b/pkg/overrides/jsonpointer_test.go index 91902d47..f073d8a5 100644 --- a/pkg/overrides/jsonpointer_test.go +++ b/pkg/overrides/jsonpointer_test.go @@ -33,15 +33,15 @@ func TestMaskIgnoredFields(t *testing.T) { { name: "no ignore-fields annotation", desired: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "spec": map[string]interface{}{ + Object: map[string]any{ + "spec": map[string]any{ "replicas": int64(3), }, }, }, live: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "spec": map[string]interface{}{ + Object: map[string]any{ + "spec": map[string]any{ "replicas": int64(5), }, }, @@ -57,25 +57,25 @@ func TestMaskIgnoredFields(t *testing.T) { { name: "mask single field", desired: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "spec": map[string]interface{}{ + Object: map[string]any{ + "spec": map[string]any{ "replicas": int64(3), - "template": map[string]interface{}{ + "template": map[string]any{ "spec": "desired", }, }, }, }, live: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "metadata": map[string]interface{}{ - "annotations": map[string]interface{}{ + Object: map[string]any{ + "metadata": map[string]any{ + "annotations": map[string]any{ AnnotationIgnoreFields: "/spec/replicas", }, }, - "spec": map[string]interface{}{ + "spec": map[string]any{ "replicas": int64(5), - "template": map[string]interface{}{ + "template": map[string]any{ "spec": "live", }, }, @@ -96,8 +96,8 @@ func TestMaskIgnoredFields(t *testing.T) { { name: "mask multiple fields", desired: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "spec": map[string]interface{}{ + Object: map[string]any{ + "spec": map[string]any{ "replicas": int64(3), "image": "desired:v1", "port": int64(8080), @@ -105,13 +105,13 @@ func TestMaskIgnoredFields(t *testing.T) { }, }, live: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "metadata": map[string]interface{}{ - "annotations": map[string]interface{}{ + Object: map[string]any{ + "metadata": map[string]any{ + "annotations": map[string]any{ AnnotationIgnoreFields: "/spec/replicas, /spec/image", }, }, - "spec": map[string]interface{}{ + "spec": map[string]any{ "replicas": int64(5), "image": "live:v2", "port": int64(9090), @@ -137,20 +137,20 @@ func TestMaskIgnoredFields(t *testing.T) { { name: "field exists in live but not in desired", desired: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "spec": map[string]interface{}{ + Object: map[string]any{ + "spec": map[string]any{ "replicas": int64(3), }, }, }, live: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "metadata": map[string]interface{}{ - "annotations": map[string]interface{}{ + Object: map[string]any{ + "metadata": map[string]any{ + "annotations": map[string]any{ AnnotationIgnoreFields: "/spec/image", }, }, - "spec": map[string]interface{}{ + "spec": map[string]any{ "replicas": int64(5), "image": "user-set:v1", }, @@ -167,21 +167,21 @@ func TestMaskIgnoredFields(t *testing.T) { { name: "field doesn't exist in live", desired: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "spec": map[string]interface{}{ + Object: map[string]any{ + "spec": map[string]any{ "replicas": int64(3), "image": "desired:v1", }, }, }, live: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "metadata": map[string]interface{}{ - "annotations": map[string]interface{}{ + Object: map[string]any{ + "metadata": map[string]any{ + "annotations": map[string]any{ AnnotationIgnoreFields: "/spec/image", }, }, - "spec": map[string]interface{}{ + "spec": map[string]any{ "replicas": int64(5), }, }, @@ -203,8 +203,8 @@ func TestMaskIgnoredFields(t *testing.T) { { name: "nil live object", desired: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "spec": map[string]interface{}{ + Object: map[string]any{ + "spec": map[string]any{ "replicas": int64(3), }, }, diff --git a/pkg/overrides/validation_test.go b/pkg/overrides/validation_test.go index da8d7ecc..a3a8ec70 100644 --- a/pkg/overrides/validation_test.go +++ b/pkg/overrides/validation_test.go @@ -39,10 +39,10 @@ func TestValidatePatchSecurity(t *testing.T) { { name: "patch on allowed kind (ConfigMap)", obj: &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "kind": "ConfigMap", - "metadata": map[string]interface{}{ - "annotations": map[string]interface{}{ + "metadata": map[string]any{ + "annotations": map[string]any{ PatchAnnotation: `[{"op": "add", "path": "/data/key", "value": "val"}]`, }, }, @@ -53,10 +53,10 @@ func TestValidatePatchSecurity(t *testing.T) { { name: "patch on sensitive kind (MachineConfig)", obj: &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "kind": "MachineConfig", - "metadata": map[string]interface{}{ - "annotations": map[string]interface{}{ + "metadata": map[string]any{ + "annotations": map[string]any{ PatchAnnotation: `[{"op": "add", "path": "/spec/config", "value": {}}]`, }, }, @@ -68,10 +68,10 @@ func TestValidatePatchSecurity(t *testing.T) { { name: "no patch on sensitive kind (MachineConfig)", obj: &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "kind": "MachineConfig", - "metadata": map[string]interface{}{ - "annotations": map[string]interface{}{}, + "metadata": map[string]any{ + "annotations": map[string]any{}, }, }, }, @@ -80,7 +80,7 @@ func TestValidatePatchSecurity(t *testing.T) { { name: "object without annotations", obj: &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "kind": "ConfigMap", }, }, @@ -111,9 +111,9 @@ func TestIsUnmanaged(t *testing.T) { { name: "unmanaged annotation present", obj: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "metadata": map[string]interface{}{ - "annotations": map[string]interface{}{ + Object: map[string]any{ + "metadata": map[string]any{ + "annotations": map[string]any{ AnnotationMode: ModeUnmanaged, }, }, @@ -124,9 +124,9 @@ func TestIsUnmanaged(t *testing.T) { { name: "unmanaged annotation with different value", obj: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "metadata": map[string]interface{}{ - "annotations": map[string]interface{}{ + Object: map[string]any{ + "metadata": map[string]any{ + "annotations": map[string]any{ AnnotationMode: "managed", }, }, @@ -137,9 +137,9 @@ func TestIsUnmanaged(t *testing.T) { { name: "no mode annotation", obj: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "metadata": map[string]interface{}{ - "annotations": map[string]interface{}{}, + Object: map[string]any{ + "metadata": map[string]any{ + "annotations": map[string]any{}, }, }, }, @@ -148,8 +148,8 @@ func TestIsUnmanaged(t *testing.T) { { name: "no annotations", obj: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "metadata": map[string]interface{}{}, + Object: map[string]any{ + "metadata": map[string]any{}, }, }, want: false, @@ -180,9 +180,9 @@ func TestIsAutopilotEnabled(t *testing.T) { { name: "annotation set to true", obj: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "metadata": map[string]interface{}{ - "annotations": map[string]interface{}{ + Object: map[string]any{ + "metadata": map[string]any{ + "annotations": map[string]any{ AnnotationAutopilotEnabled: "true", }, }, @@ -193,9 +193,9 @@ func TestIsAutopilotEnabled(t *testing.T) { { name: "annotation set to comma-separated asset names", obj: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "metadata": map[string]interface{}{ - "annotations": map[string]interface{}{ + Object: map[string]any{ + "metadata": map[string]any{ + "annotations": map[string]any{ AnnotationAutopilotEnabled: "swap-enable,descheduler-loadaware", }, }, @@ -206,9 +206,9 @@ func TestIsAutopilotEnabled(t *testing.T) { { name: "annotation absent", obj: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "metadata": map[string]interface{}{ - "annotations": map[string]interface{}{}, + Object: map[string]any{ + "metadata": map[string]any{ + "annotations": map[string]any{}, }, }, }, @@ -217,9 +217,9 @@ func TestIsAutopilotEnabled(t *testing.T) { { name: "annotation set to empty string", obj: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "metadata": map[string]interface{}{ - "annotations": map[string]interface{}{ + Object: map[string]any{ + "metadata": map[string]any{ + "annotations": map[string]any{ AnnotationAutopilotEnabled: "", }, }, @@ -230,8 +230,8 @@ func TestIsAutopilotEnabled(t *testing.T) { { name: "no annotations", obj: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "metadata": map[string]interface{}{}, + Object: map[string]any{ + "metadata": map[string]any{}, }, }, want: false, @@ -256,16 +256,16 @@ func TestIsAutopilotEnabled(t *testing.T) { func TestParseAutopilotScope(t *testing.T) { hcoWith := func(val string) *unstructured.Unstructured { return &unstructured.Unstructured{ - Object: map[string]interface{}{ - "metadata": map[string]interface{}{ - "annotations": map[string]interface{}{ + Object: map[string]any{ + "metadata": map[string]any{ + "annotations": map[string]any{ AnnotationAutopilotEnabled: val, }, }, }, } } - noAnnotations := &unstructured.Unstructured{Object: map[string]interface{}{}} + noAnnotations := &unstructured.Unstructured{Object: map[string]any{}} tests := []struct { name string @@ -327,10 +327,10 @@ func TestValidateAnnotations(t *testing.T) { { name: "valid patch annotation", obj: &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "kind": "ConfigMap", - "metadata": map[string]interface{}{ - "annotations": map[string]interface{}{ + "metadata": map[string]any{ + "annotations": map[string]any{ PatchAnnotation: `[{"op": "add", "path": "/data/key", "value": "val"}]`, }, }, @@ -341,10 +341,10 @@ func TestValidateAnnotations(t *testing.T) { { name: "invalid patch annotation (malformed JSON)", obj: &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "kind": "ConfigMap", - "metadata": map[string]interface{}{ - "annotations": map[string]interface{}{ + "metadata": map[string]any{ + "annotations": map[string]any{ PatchAnnotation: `invalid json`, }, }, @@ -356,10 +356,10 @@ func TestValidateAnnotations(t *testing.T) { { name: "patch on sensitive kind", obj: &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "kind": "MachineConfig", - "metadata": map[string]interface{}{ - "annotations": map[string]interface{}{ + "metadata": map[string]any{ + "annotations": map[string]any{ PatchAnnotation: `[{"op": "add", "path": "/spec/config", "value": {}}]`, }, }, @@ -371,10 +371,10 @@ func TestValidateAnnotations(t *testing.T) { { name: "valid ignore-fields annotation", obj: &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "kind": "ConfigMap", - "metadata": map[string]interface{}{ - "annotations": map[string]interface{}{ + "metadata": map[string]any{ + "annotations": map[string]any{ AnnotationIgnoreFields: "/spec/replicas,/metadata/labels", }, }, @@ -385,10 +385,10 @@ func TestValidateAnnotations(t *testing.T) { { name: "invalid ignore-fields annotation", obj: &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "kind": "ConfigMap", - "metadata": map[string]interface{}{ - "annotations": map[string]interface{}{ + "metadata": map[string]any{ + "annotations": map[string]any{ AnnotationIgnoreFields: "not-a-pointer", }, }, @@ -400,10 +400,10 @@ func TestValidateAnnotations(t *testing.T) { { name: "valid unmanaged mode", obj: &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "kind": "ConfigMap", - "metadata": map[string]interface{}{ - "annotations": map[string]interface{}{ + "metadata": map[string]any{ + "annotations": map[string]any{ AnnotationMode: ModeUnmanaged, }, }, @@ -414,10 +414,10 @@ func TestValidateAnnotations(t *testing.T) { { name: "invalid mode annotation", obj: &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "kind": "ConfigMap", - "metadata": map[string]interface{}{ - "annotations": map[string]interface{}{ + "metadata": map[string]any{ + "annotations": map[string]any{ AnnotationMode: "invalid-mode", }, }, @@ -429,7 +429,7 @@ func TestValidateAnnotations(t *testing.T) { { name: "no annotations", obj: &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "kind": "ConfigMap", }, }, @@ -438,10 +438,10 @@ func TestValidateAnnotations(t *testing.T) { { name: "all valid annotations together", obj: &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "kind": "Deployment", - "metadata": map[string]interface{}{ - "annotations": map[string]interface{}{ + "metadata": map[string]any{ + "annotations": map[string]any{ PatchAnnotation: `[{"op": "replace", "path": "/spec/replicas", "value": 3}]`, AnnotationIgnoreFields: "/metadata/labels/app", AnnotationMode: ModeUnmanaged, diff --git a/pkg/rbac/rbac.go b/pkg/rbac/rbac.go index e2f198d2..92000a65 100644 --- a/pkg/rbac/rbac.go +++ b/pkg/rbac/rbac.go @@ -305,7 +305,7 @@ func processAssetFile(content []byte, seen map[string]bool, resources *[]Resourc continue } - var doc map[string]interface{} + var doc map[string]any if err := yaml.Unmarshal([]byte(docStr), &doc); err != nil { continue // template remnants or invalid YAML — skip } diff --git a/pkg/util/events_test.go b/pkg/util/events_test.go index 6018121c..de7f8904 100644 --- a/pkg/util/events_test.go +++ b/pkg/util/events_test.go @@ -38,7 +38,7 @@ type Event struct { Message string } -func (f *FakeRecorder) Eventf(regarding runtime.Object, related runtime.Object, eventtype, reason, action, note string, args ...interface{}) { +func (f *FakeRecorder) Eventf(regarding runtime.Object, related runtime.Object, eventtype, reason, action, note string, args ...any) { message := fmt.Sprintf(note, args...) f.Events = append(f.Events, Event{ EventType: eventtype, diff --git a/pkg/util/unstructured.go b/pkg/util/unstructured.go index 33d8b825..12e87b21 100644 --- a/pkg/util/unstructured.go +++ b/pkg/util/unstructured.go @@ -24,7 +24,7 @@ import ( ) // SetNestedFieldWithDefault sets a nested field with a default value if not already set -func SetNestedFieldWithDefault(obj map[string]interface{}, value interface{}, fields ...string) error { +func SetNestedFieldWithDefault(obj map[string]any, value any, fields ...string) error { if obj == nil { return fmt.Errorf("object is nil") } @@ -39,7 +39,7 @@ func SetNestedFieldWithDefault(obj map[string]interface{}, value interface{}, fi } // GetNestedString safely gets a nested string field -func GetNestedString(obj map[string]interface{}, fields ...string) (string, bool) { +func GetNestedString(obj map[string]any, fields ...string) (string, bool) { val, found, err := unstructured.NestedString(obj, fields...) if err != nil || !found { return "", false @@ -48,7 +48,7 @@ func GetNestedString(obj map[string]interface{}, fields ...string) (string, bool } // GetNestedInt64 safely gets a nested int64 field -func GetNestedInt64(obj map[string]interface{}, fields ...string) (int64, bool) { +func GetNestedInt64(obj map[string]any, fields ...string) (int64, bool) { val, found, err := unstructured.NestedInt64(obj, fields...) if err != nil || !found { return 0, false @@ -57,7 +57,7 @@ func GetNestedInt64(obj map[string]interface{}, fields ...string) (int64, bool) } // GetNestedBool safely gets a nested bool field -func GetNestedBool(obj map[string]interface{}, fields ...string) (bool, bool) { +func GetNestedBool(obj map[string]any, fields ...string) (bool, bool) { val, found, err := unstructured.NestedBool(obj, fields...) if err != nil || !found { return false, false @@ -66,7 +66,7 @@ func GetNestedBool(obj map[string]interface{}, fields ...string) (bool, bool) { } // GetNestedStringSlice safely gets a nested string slice field -func GetNestedStringSlice(obj map[string]interface{}, fields ...string) ([]string, bool) { +func GetNestedStringSlice(obj map[string]any, fields ...string) ([]string, bool) { val, found, err := unstructured.NestedStringSlice(obj, fields...) if err != nil || !found { return nil, false diff --git a/pkg/util/unstructured_test.go b/pkg/util/unstructured_test.go index 4c3a403f..c6a34ca6 100644 --- a/pkg/util/unstructured_test.go +++ b/pkg/util/unstructured_test.go @@ -26,16 +26,16 @@ import ( func TestSetNestedFieldWithDefault(t *testing.T) { tests := []struct { name string - obj map[string]interface{} - value interface{} + obj map[string]any + value any fields []string wantErr bool - wantValue interface{} + wantValue any }{ { name: "set field when not present", - obj: map[string]interface{}{ - "metadata": map[string]interface{}{}, + obj: map[string]any{ + "metadata": map[string]any{}, }, value: "test-value", fields: []string{"metadata", "name"}, @@ -44,8 +44,8 @@ func TestSetNestedFieldWithDefault(t *testing.T) { }, { name: "do not override existing field", - obj: map[string]interface{}{ - "metadata": map[string]interface{}{ + obj: map[string]any{ + "metadata": map[string]any{ "name": "existing-value", }, }, @@ -63,8 +63,8 @@ func TestSetNestedFieldWithDefault(t *testing.T) { }, { name: "set nested field multiple levels", - obj: map[string]interface{}{ - "spec": map[string]interface{}{}, + obj: map[string]any{ + "spec": map[string]any{}, }, value: int64(3), fields: []string{"spec", "replicas"}, @@ -98,15 +98,15 @@ func TestSetNestedFieldWithDefault(t *testing.T) { func TestGetNestedString(t *testing.T) { tests := []struct { name string - obj map[string]interface{} + obj map[string]any fields []string wantValue string wantFound bool }{ { name: "get existing string", - obj: map[string]interface{}{ - "metadata": map[string]interface{}{ + obj: map[string]any{ + "metadata": map[string]any{ "name": "test-name", }, }, @@ -116,8 +116,8 @@ func TestGetNestedString(t *testing.T) { }, { name: "field not found", - obj: map[string]interface{}{ - "metadata": map[string]interface{}{}, + obj: map[string]any{ + "metadata": map[string]any{}, }, fields: []string{"metadata", "missing"}, wantValue: "", @@ -125,7 +125,7 @@ func TestGetNestedString(t *testing.T) { }, { name: "wrong type returns not found", - obj: map[string]interface{}{ + obj: map[string]any{ "count": 123, }, fields: []string{"count"}, @@ -150,15 +150,15 @@ func TestGetNestedString(t *testing.T) { func TestGetNestedInt64(t *testing.T) { tests := []struct { name string - obj map[string]interface{} + obj map[string]any fields []string wantValue int64 wantFound bool }{ { name: "get existing int64", - obj: map[string]interface{}{ - "spec": map[string]interface{}{ + obj: map[string]any{ + "spec": map[string]any{ "replicas": int64(5), }, }, @@ -168,8 +168,8 @@ func TestGetNestedInt64(t *testing.T) { }, { name: "field not found", - obj: map[string]interface{}{ - "spec": map[string]interface{}{}, + obj: map[string]any{ + "spec": map[string]any{}, }, fields: []string{"spec", "missing"}, wantValue: 0, @@ -177,7 +177,7 @@ func TestGetNestedInt64(t *testing.T) { }, { name: "wrong type returns not found", - obj: map[string]interface{}{ + obj: map[string]any{ "name": "string-value", }, fields: []string{"name"}, @@ -202,15 +202,15 @@ func TestGetNestedInt64(t *testing.T) { func TestGetNestedBool(t *testing.T) { tests := []struct { name string - obj map[string]interface{} + obj map[string]any fields []string wantValue bool wantFound bool }{ { name: "get existing bool true", - obj: map[string]interface{}{ - "spec": map[string]interface{}{ + obj: map[string]any{ + "spec": map[string]any{ "enabled": true, }, }, @@ -220,8 +220,8 @@ func TestGetNestedBool(t *testing.T) { }, { name: "get existing bool false", - obj: map[string]interface{}{ - "spec": map[string]interface{}{ + obj: map[string]any{ + "spec": map[string]any{ "enabled": false, }, }, @@ -231,8 +231,8 @@ func TestGetNestedBool(t *testing.T) { }, { name: "field not found", - obj: map[string]interface{}{ - "spec": map[string]interface{}{}, + obj: map[string]any{ + "spec": map[string]any{}, }, fields: []string{"spec", "missing"}, wantValue: false, @@ -256,16 +256,16 @@ func TestGetNestedBool(t *testing.T) { func TestGetNestedStringSlice(t *testing.T) { tests := []struct { name string - obj map[string]interface{} + obj map[string]any fields []string wantValue []string wantFound bool }{ { name: "get existing string slice", - obj: map[string]interface{}{ - "spec": map[string]interface{}{ - "args": []interface{}{"arg1", "arg2"}, + obj: map[string]any{ + "spec": map[string]any{ + "args": []any{"arg1", "arg2"}, }, }, fields: []string{"spec", "args"}, @@ -274,8 +274,8 @@ func TestGetNestedStringSlice(t *testing.T) { }, { name: "field not found", - obj: map[string]interface{}{ - "spec": map[string]interface{}{}, + obj: map[string]any{ + "spec": map[string]any{}, }, fields: []string{"spec", "missing"}, wantValue: nil, @@ -283,9 +283,9 @@ func TestGetNestedStringSlice(t *testing.T) { }, { name: "empty slice", - obj: map[string]interface{}{ - "spec": map[string]interface{}{ - "args": []interface{}{}, + obj: map[string]any{ + "spec": map[string]any{ + "args": []any{}, }, }, fields: []string{"spec", "args"}, @@ -385,19 +385,19 @@ func TestCloneUnstructured(t *testing.T) { { name: "clone non-nil object", obj: &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "test", }, }, }, want: &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "test", }, }, diff --git a/test/anti_thrashing_integration_test.go b/test/anti_thrashing_integration_test.go index 4f84dc35..8b68056f 100644 --- a/test/anti_thrashing_integration_test.go +++ b/test/anti_thrashing_integration_test.go @@ -199,20 +199,20 @@ var _ = Describe("Anti-Thrashing Integration", func() { Context("Pause Annotation", func() { It("should skip reconciliation when pause annotation is present", func() { cm := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "paused-cm", "namespace": testNs, - "labels": map[string]interface{}{ + "labels": map[string]any{ "platform.kubevirt.io/managed-by": "virt-platform-autopilot", }, - "annotations": map[string]interface{}{ + "annotations": map[string]any{ overrides.AnnotationReconcilePaused: "true", }, }, - "data": map[string]interface{}{ + "data": map[string]any{ "key": "value", }, }, @@ -227,20 +227,20 @@ var _ = Describe("Anti-Thrashing Integration", func() { It("should allow reconciliation when pause annotation is removed", func() { cm := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "recoverable-cm", "namespace": testNs, - "labels": map[string]interface{}{ + "labels": map[string]any{ "platform.kubevirt.io/managed-by": "virt-platform-autopilot", }, - "annotations": map[string]interface{}{ + "annotations": map[string]any{ overrides.AnnotationReconcilePaused: "true", }, }, - "data": map[string]interface{}{ + "data": map[string]any{ "key": "value", }, }, @@ -348,17 +348,17 @@ var _ = Describe("Anti-Thrashing Integration", func() { By("creating resource to test pause annotation") cm := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "fight-cm", "namespace": testNs, - "labels": map[string]interface{}{ + "labels": map[string]any{ "platform.kubevirt.io/managed-by": "virt-platform-autopilot", }, }, - "data": map[string]interface{}{ + "data": map[string]any{ "key": "original", }, }, diff --git a/test/asset_failure_test.go b/test/asset_failure_test.go index 9fc62670..631d18fc 100644 --- a/test/asset_failure_test.go +++ b/test/asset_failure_test.go @@ -45,14 +45,14 @@ var _ = Describe("Asset Failure Handling", func() { It("should continue processing after one asset fails and report aggregated error", func() { // Valid ConfigMap 1 validCM1 := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "test-cm-1", "namespace": testNs, }, - "data": map[string]interface{}{ + "data": map[string]any{ "key": "value1", }, }, @@ -60,14 +60,14 @@ var _ = Describe("Asset Failure Handling", func() { // Invalid ConfigMap - missing name (will fail validation) invalidCM := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "namespace": testNs, // Missing "name" field - required by Kubernetes }, - "data": map[string]interface{}{ + "data": map[string]any{ "key": "invalid", }, }, @@ -75,14 +75,14 @@ var _ = Describe("Asset Failure Handling", func() { // Valid ConfigMap 2 validCM2 := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "test-cm-2", "namespace": testNs, }, - "data": map[string]interface{}{ + "data": map[string]any{ "key": "value2", }, }, @@ -124,10 +124,10 @@ var _ = Describe("Asset Failure Handling", func() { It("should handle multiple simultaneous failures", func() { // Create 2 invalid and 1 valid asset invalid1 := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "namespace": testNs, // Missing name }, @@ -135,24 +135,24 @@ var _ = Describe("Asset Failure Handling", func() { } valid := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "valid-cm", "namespace": testNs, }, - "data": map[string]interface{}{ + "data": map[string]any{ "test": "value", }, }, } invalid2 := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "namespace": testNs, // Missing name }, @@ -188,14 +188,14 @@ var _ = Describe("Asset Failure Handling", func() { // Create 3 valid ConfigMaps for i := 0; i < 3; i++ { cm := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": fmt.Sprintf("cm-%d", i), "namespace": testNs, }, - "data": map[string]interface{}{ + "data": map[string]any{ "index": fmt.Sprintf("%d", i), }, }, @@ -245,14 +245,14 @@ var _ = Describe("Asset Failure Handling", func() { By("applying a ConfigMap to a namespace that does not exist") missingNs := "missing-ns-" + randString() obj := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "test-cm", "namespace": missingNs, }, - "data": map[string]interface{}{"key": "value"}, + "data": map[string]any{"key": "value"}, }, } diff --git a/test/controller_integration_test.go b/test/controller_integration_test.go index 76193429..1ac7b8d4 100644 --- a/test/controller_integration_test.go +++ b/test/controller_integration_test.go @@ -30,7 +30,7 @@ var _ = Describe("Platform Controller Integration", func() { obj.SetKind("ConfigMap") obj.SetName("test-ssa") obj.SetNamespace("default") - obj.Object["data"] = map[string]interface{}{ + obj.Object["data"] = map[string]any{ "key1": "value1", } @@ -78,7 +78,7 @@ var _ = Describe("Platform Controller Integration", func() { obj.SetKind("ConfigMap") obj.SetName("test-drift") obj.SetNamespace("default") - obj.Object["data"] = map[string]interface{}{ + obj.Object["data"] = map[string]any{ "key1": "original-value", } @@ -97,7 +97,7 @@ var _ = Describe("Platform Controller Integration", func() { Expect(err).NotTo(HaveOccurred()) // User modifies the value - fetched.Object["data"] = map[string]interface{}{ + fetched.Object["data"] = map[string]any{ "key1": "user-modified-value", } err = k8sClient.Update(ctx, fetched) @@ -111,7 +111,7 @@ var _ = Describe("Platform Controller Integration", func() { desired.SetKind("ConfigMap") desired.SetName("test-drift") desired.SetNamespace("default") - desired.Object["data"] = map[string]interface{}{ + desired.Object["data"] = map[string]any{ "key1": "original-value", } @@ -149,7 +149,7 @@ var _ = Describe("Platform Controller Integration", func() { obj.SetKind("ConfigMap") obj.SetName("test-conflict") obj.SetNamespace("default") - obj.Object["data"] = map[string]interface{}{ + obj.Object["data"] = map[string]any{ "key1": "manager1-value", } @@ -160,7 +160,7 @@ var _ = Describe("Platform Controller Integration", func() { By("second manager modifying same field with ForceOwnership") obj2 := obj.DeepCopy() - obj2.Object["data"] = map[string]interface{}{ + obj2.Object["data"] = map[string]any{ "key1": "manager2-value", } // Clear managedFields for SSA (required by API server) @@ -222,14 +222,14 @@ var _ = Describe("Platform Controller Integration", func() { }() hco := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "hco.kubevirt.io/v1", "kind": "HyperConverged", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "kubevirt-hyperconverged", // HCO CRD requires this exact name "namespace": testNs, }, - "spec": map[string]interface{}{}, + "spec": map[string]any{}, }, } @@ -311,16 +311,16 @@ var _ = Describe("Platform Controller Integration", func() { By("creating an HCO without the managed-by label") hco := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "hco.kubevirt.io/v1", "kind": "HyperConverged", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "kubevirt-hyperconverged", "namespace": testNs, }, - "spec": map[string]interface{}{ - "virtualization": map[string]interface{}{ - "liveMigrationConfig": map[string]interface{}{ + "spec": map[string]any{ + "virtualization": map[string]any{ + "liveMigrationConfig": map[string]any{ "parallelMigrationsPerCluster": 5, "parallelOutboundMigrationsPerNode": 2, }, @@ -346,14 +346,14 @@ var _ = Describe("Platform Controller Integration", func() { // The applier's Apply method should automatically label objects // even if they don't have the managed-by label initially testObj := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "test-adoption-cm", "namespace": testNs, }, - "data": map[string]interface{}{ + "data": map[string]any{ "key": "value", }, }, diff --git a/test/descheduler_crd_versions_test.go b/test/descheduler_crd_versions_test.go index ba2593f4..c5cd4a6a 100644 --- a/test/descheduler_crd_versions_test.go +++ b/test/descheduler_crd_versions_test.go @@ -53,9 +53,9 @@ var _ = Describe("Descheduler CRD Version Compatibility", func() { // Create mock HCO with custom eviction limits hco = pkgcontext.NewMockHCO("kubevirt-hyperconverged", ns.GetName()) // Set custom eviction limits to verify they're extracted correctly (v1 paths) - hcoSpec := map[string]interface{}{ - "virtualization": map[string]interface{}{ - "liveMigrationConfig": map[string]interface{}{ + hcoSpec := map[string]any{ + "virtualization": map[string]any{ + "liveMigrationConfig": map[string]any{ "parallelMigrationsPerCluster": int64(45), "parallelOutboundMigrationsPerNode": int64(20), }, @@ -266,9 +266,9 @@ var _ = Describe("Descheduler CRD Version Compatibility", func() { // Create HCO with only total limit set partialHCO := pkgcontext.NewMockHCO("test-hco", ns.GetName()) - partialHCO.Object["spec"] = map[string]interface{}{ - "virtualization": map[string]interface{}{ - "liveMigrationConfig": map[string]interface{}{ + partialHCO.Object["spec"] = map[string]any{ + "virtualization": map[string]any{ + "liveMigrationConfig": map[string]any{ "parallelMigrationsPerCluster": int64(100), // parallelOutboundMigrationsPerNode omitted }, diff --git a/test/drift_detection_test.go b/test/drift_detection_test.go index 3dfaeb97..9ad091a8 100644 --- a/test/drift_detection_test.go +++ b/test/drift_detection_test.go @@ -47,18 +47,18 @@ var _ = Describe("Real-Time Drift Detection", func() { By("creating a MachineConfig with managed-by label") mc := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "machineconfiguration.openshift.io/v1", "kind": "MachineConfig", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "test-drift-detection", - "labels": map[string]interface{}{ + "labels": map[string]any{ engine.ManagedByLabel: engine.ManagedByValue, }, }, - "spec": map[string]interface{}{ - "config": map[string]interface{}{ - "ignition": map[string]interface{}{ + "spec": map[string]any{ + "config": map[string]any{ + "ignition": map[string]any{ "version": "3.2.0", }, }, @@ -131,24 +131,24 @@ var _ = Describe("Real-Time Drift Detection", func() { By("creating a NodeHealthCheck with managed-by label") nhc := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "remediation.medik8s.io/v1alpha1", "kind": "NodeHealthCheck", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "test-nhc-drift", "namespace": testNs, - "labels": map[string]interface{}{ + "labels": map[string]any{ engine.ManagedByLabel: engine.ManagedByValue, }, }, - "spec": map[string]interface{}{ - "selector": map[string]interface{}{ - "matchLabels": map[string]interface{}{ + "spec": map[string]any{ + "selector": map[string]any{ + "matchLabels": map[string]any{ "test": "drift", }, }, - "unhealthyConditions": []interface{}{ - map[string]interface{}{ + "unhealthyConditions": []any{ + map[string]any{ "type": "Ready", "status": "False", "duration": "300s", @@ -178,8 +178,8 @@ var _ = Describe("Real-Time Drift Detection", func() { // Modify duration (simulating user/other controller changing it) spec, _, _ := unstructured.NestedMap(fetched.Object, "spec") - unhealthyConditions := spec["unhealthyConditions"].([]interface{}) - condition := unhealthyConditions[0].(map[string]interface{}) + unhealthyConditions := spec["unhealthyConditions"].([]any) + condition := unhealthyConditions[0].(map[string]any) condition["duration"] = "600s" // Changed from 300s Expect(k8sClient.Update(ctx, fetched)).To(Succeed()) @@ -199,8 +199,8 @@ var _ = Describe("Real-Time Drift Detection", func() { Expect(k8sClient.Get(ctx, key, final)).To(Succeed()) finalSpec, _, _ := unstructured.NestedMap(final.Object, "spec") - finalConditions := finalSpec["unhealthyConditions"].([]interface{}) - finalCondition := finalConditions[0].(map[string]interface{}) + finalConditions := finalSpec["unhealthyConditions"].([]any) + finalCondition := finalConditions[0].(map[string]any) // SSA should restore to desired state Expect(finalCondition["duration"]).To(Equal("300s")) }) @@ -221,16 +221,16 @@ var _ = Describe("Real-Time Drift Detection", func() { By("creating an HCO instance") hco := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "hco.kubevirt.io/v1", "kind": "HyperConverged", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "kubevirt-hyperconverged", "namespace": testNs, }, - "spec": map[string]interface{}{ - "virtualization": map[string]interface{}{ - "liveMigrationConfig": map[string]interface{}{ + "spec": map[string]any{ + "virtualization": map[string]any{ + "liveMigrationConfig": map[string]any{ "parallelMigrationsPerCluster": int64(5), }, }, @@ -310,18 +310,18 @@ var _ = Describe("Real-Time Drift Detection", func() { By("creating a MachineConfig") mc := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "machineconfiguration.openshift.io/v1", "kind": "MachineConfig", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "test-perf", - "labels": map[string]interface{}{ + "labels": map[string]any{ engine.ManagedByLabel: engine.ManagedByValue, }, }, - "spec": map[string]interface{}{ - "config": map[string]interface{}{ - "ignition": map[string]interface{}{ + "spec": map[string]any{ + "config": map[string]any{ + "ignition": map[string]any{ "version": "3.2.0", }, }, diff --git a/test/e2e/anti_thrashing_e2e_test.go b/test/e2e/anti_thrashing_e2e_test.go index ec3e1a13..a0d16480 100644 --- a/test/e2e/anti_thrashing_e2e_test.go +++ b/test/e2e/anti_thrashing_e2e_test.go @@ -43,17 +43,17 @@ var _ = Describe("Anti-Thrashing E2E Tests", Ordered, func() { BeforeAll(func() { By("ensuring HCO instance exists with opt-in annotation") hco = &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "hco.kubevirt.io/v1", "kind": "HyperConverged", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": hcoName, "namespace": operatorNamespace, - "annotations": map[string]interface{}{ + "annotations": map[string]any{ autopilotAnnotation: autopilotEnabled, }, }, - "spec": map[string]interface{}{}, + "spec": map[string]any{}, }, } diff --git a/test/e2e/controller_e2e_test.go b/test/e2e/controller_e2e_test.go index d8164420..659ec6e9 100644 --- a/test/e2e/controller_e2e_test.go +++ b/test/e2e/controller_e2e_test.go @@ -98,18 +98,18 @@ var _ = Describe("Controller E2E Tests", func() { By("creating unlabeled HCO instance") hco = &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "hco.kubevirt.io/v1", "kind": "HyperConverged", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": hcoName, "namespace": operatorNamespace, // Deliberately NO managed-by label to test adoption - "annotations": map[string]interface{}{ + "annotations": map[string]any{ autopilotAnnotation: autopilotEnabled, }, }, - "spec": map[string]interface{}{}, + "spec": map[string]any{}, }, } Expect(k8sClient.Create(ctx, hco)).To(Succeed()) diff --git a/test/e2e/crd_lifecycle_test.go b/test/e2e/crd_lifecycle_test.go index 7639ec5f..8a9b3d4f 100644 --- a/test/e2e/crd_lifecycle_test.go +++ b/test/e2e/crd_lifecycle_test.go @@ -40,20 +40,20 @@ var _ = Describe("CRD Lifecycle Tests", Ordered, func() { BeforeAll(func() { By("ensuring clean HCO instance for lifecycle tests") hco = &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "hco.kubevirt.io/v1", "kind": "HyperConverged", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": hcoName, "namespace": operatorNamespace, - "labels": map[string]interface{}{ + "labels": map[string]any{ lifecycleManagedByLabel: lifecycleManagedByValue, }, - "annotations": map[string]interface{}{ + "annotations": map[string]any{ autopilotAnnotation: autopilotEnabled, }, }, - "spec": map[string]interface{}{}, + "spec": map[string]any{}, }, } diff --git a/test/e2e/drift_test.go b/test/e2e/drift_test.go index c9f41ff2..f0676c1f 100644 --- a/test/e2e/drift_test.go +++ b/test/e2e/drift_test.go @@ -43,20 +43,20 @@ var _ = Describe("Drift Detection Tests", Ordered, func() { BeforeAll(func() { By("ensuring clean HCO instance for drift tests") hco = &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "hco.kubevirt.io/v1", "kind": "HyperConverged", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": hcoName, "namespace": operatorNamespace, - "labels": map[string]interface{}{ + "labels": map[string]any{ driftManagedByLabel: driftManagedByValue, }, - "annotations": map[string]interface{}{ + "annotations": map[string]any{ autopilotAnnotation: autopilotEnabled, }, }, - "spec": map[string]interface{}{}, + "spec": map[string]any{}, }, } @@ -150,7 +150,7 @@ var _ = Describe("Drift Detection Tests", Ordered, func() { }) // setNestedField sets a value in an unstructured object at the given field path. -func setNestedField(obj *unstructured.Unstructured, value interface{}, fields ...string) error { +func setNestedField(obj *unstructured.Unstructured, value any, fields ...string) error { return unstructured.SetNestedField(obj.Object, value, fields...) } diff --git a/test/events_integration_test.go b/test/events_integration_test.go index 0e33e430..e4c19df6 100644 --- a/test/events_integration_test.go +++ b/test/events_integration_test.go @@ -45,7 +45,7 @@ type RecordedEvent struct { Message string } -func (f *FakeEventRecorder) Eventf(regarding runtime.Object, related runtime.Object, eventtype, reason, action, note string, args ...interface{}) { +func (f *FakeEventRecorder) Eventf(regarding runtime.Object, related runtime.Object, eventtype, reason, action, note string, args ...any) { message := fmt.Sprintf(note, args...) f.Events = append(f.Events, RecordedEvent{ EventType: eventtype, @@ -97,10 +97,10 @@ var _ = Describe("Event Recording Integration", func() { // Create minimal render context with HCO renderCtx = &pkgcontext.RenderContext{ HCO: &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "hco.kubevirt.io/v1", "kind": "HyperConverged", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "kubevirt-hyperconverged", "namespace": testNs, }, @@ -114,14 +114,14 @@ var _ = Describe("Event Recording Integration", func() { It("should emit AssetApplied and DriftCorrected events on successful apply", func() { // Create initial object obj := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "event-test", "namespace": testNs, }, - "data": map[string]interface{}{ + "data": map[string]any{ "key": "value1", }, }, @@ -132,7 +132,7 @@ var _ = Describe("Event Recording Integration", func() { Expect(err).NotTo(HaveOccurred()) // Manually modify to create drift - obj.Object["data"] = map[string]interface{}{ + obj.Object["data"] = map[string]any{ "key": "value2", } err = k8sClient.Update(ctx, obj) @@ -143,14 +143,14 @@ var _ = Describe("Event Recording Integration", func() { // Reconcile by reapplying original state (should detect and correct drift) // Create a fresh object to avoid managedFields issues obj = &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "event-test", "namespace": testNs, }, - "data": map[string]interface{}{ + "data": map[string]any{ "key": "value1", }, }, @@ -188,14 +188,14 @@ var _ = Describe("Event Recording Integration", func() { It("should emit DriftDetected event when drift is found", func() { // Create initial object obj := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "drift-test", "namespace": testNs, }, - "data": map[string]interface{}{ + "data": map[string]any{ "key": "value1", }, }, @@ -206,7 +206,7 @@ var _ = Describe("Event Recording Integration", func() { Expect(err).NotTo(HaveOccurred()) // Manually modify to create drift - obj.Object["data"] = map[string]interface{}{ + obj.Object["data"] = map[string]any{ "key": "value2", } err = k8sClient.Update(ctx, obj) @@ -241,17 +241,17 @@ var _ = Describe("Event Recording Integration", func() { It("should emit PatchApplied event when JSON patch is applied", func() { // Create object with valid JSON patch obj := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "patch-test", "namespace": testNs, - "annotations": map[string]interface{}{ + "annotations": map[string]any{ overrides.PatchAnnotation: `[{"op": "add", "path": "/data/patched", "value": "yes"}]`, }, }, - "data": map[string]interface{}{ + "data": map[string]any{ "original": "value", }, }, @@ -281,17 +281,17 @@ var _ = Describe("Event Recording Integration", func() { It("should emit InvalidPatch event when JSON patch is invalid", func() { // Create object with invalid JSON patch obj := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "invalid-patch-test", "namespace": testNs, - "annotations": map[string]interface{}{ + "annotations": map[string]any{ overrides.PatchAnnotation: `[{"op": "invalid", "path": "/data/test"}]`, }, }, - "data": map[string]interface{}{ + "data": map[string]any{ "original": "value", }, }, @@ -323,17 +323,17 @@ var _ = Describe("Event Recording Integration", func() { It("should emit UnmanagedMode event when resource is unmanaged", func() { // Create unmanaged object obj := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "unmanaged-test", "namespace": testNs, - "annotations": map[string]interface{}{ + "annotations": map[string]any{ overrides.AnnotationMode: overrides.ModeUnmanaged, }, }, - "data": map[string]interface{}{ + "data": map[string]any{ "key": "value", }, }, @@ -365,14 +365,14 @@ var _ = Describe("Event Recording Integration", func() { It("should not crash when event recorder is nil", func() { // Create object obj := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "no-events", "namespace": testNs, }, - "data": map[string]interface{}{ + "data": map[string]any{ "key": "value", }, }, diff --git a/test/metrics_integration_test.go b/test/metrics_integration_test.go index aa2a5b3f..14d00590 100644 --- a/test/metrics_integration_test.go +++ b/test/metrics_integration_test.go @@ -67,14 +67,14 @@ var _ = Describe("Metrics Integration", func() { Context("Compliance Status Metrics", func() { It("should set compliance=1 when asset is successfully applied", func() { cm := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "test-cm", "namespace": testNs, }, - "data": map[string]interface{}{ + "data": map[string]any{ "key": "value", }, }, @@ -99,10 +99,10 @@ var _ = Describe("Metrics Integration", func() { It("should set compliance=0 when asset fails to apply", func() { invalidCM := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "namespace": testNs, // Missing required "name" field }, @@ -129,26 +129,26 @@ var _ = Describe("Metrics Integration", func() { It("should track compliance for multiple resources independently", func() { cm1 := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "cm-synced", "namespace": testNs, }, - "data": map[string]interface{}{"k": "v"}, + "data": map[string]any{"k": "v"}, }, } cm2 := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "cm-failed", "namespace": testNs, }, - "data": map[string]interface{}{"k": "v"}, + "data": map[string]any{"k": "v"}, }, } @@ -168,14 +168,14 @@ var _ = Describe("Metrics Integration", func() { It("should update compliance metric when state changes", func() { cm := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "cm-changing", "namespace": testNs, }, - "data": map[string]interface{}{"k": "v"}, + "data": map[string]any{"k": "v"}, }, } @@ -212,10 +212,10 @@ var _ = Describe("Metrics Integration", func() { Context("Thrashing Counter Metrics", func() { It("should increment thrashing counter when throttled", func() { cm := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "thrashing-cm", "namespace": testNs, }, @@ -298,17 +298,17 @@ var _ = Describe("Metrics Integration", func() { Context("Customization Info Metrics", func() { It("should track patch customization", func() { cm := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "patched-cm", "namespace": testNs, - "annotations": map[string]interface{}{ + "annotations": map[string]any{ overrides.PatchAnnotation: `[{"op":"add","path":"/data/foo","value":"bar"}]`, }, }, - "data": map[string]interface{}{"key": "value"}, + "data": map[string]any{"key": "value"}, }, } @@ -411,14 +411,14 @@ var _ = Describe("Metrics Integration", func() { Context("Reconcile Duration Metrics", func() { It("should record reconciliation duration", func() { cm := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "timed-cm", "namespace": testNs, }, - "data": map[string]interface{}{"k": "v"}, + "data": map[string]any{"k": "v"}, }, } @@ -434,10 +434,10 @@ var _ = Describe("Metrics Integration", func() { It("should record duration using timer pattern", func() { cm := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "timer-cm", "namespace": testNs, }, @@ -478,17 +478,17 @@ var _ = Describe("Metrics Integration", func() { Context("End-to-End Metric Emission", func() { It("should emit all relevant metrics during successful reconciliation", func() { cm := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "e2e-cm", "namespace": testNs, - "annotations": map[string]interface{}{ + "annotations": map[string]any{ overrides.PatchAnnotation: `[{"op":"add","path":"/data/patched","value":"true"}]`, }, }, - "data": map[string]interface{}{ + "data": map[string]any{ "original": "value", }, }, @@ -532,10 +532,10 @@ var _ = Describe("Metrics Integration", func() { It("should handle failed reconciliation with correct metrics", func() { invalidCM := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "namespace": testNs, // Missing name - will fail }, diff --git a/test/patcher_integration_test.go b/test/patcher_integration_test.go index 3e402562..58689dcc 100644 --- a/test/patcher_integration_test.go +++ b/test/patcher_integration_test.go @@ -57,14 +57,14 @@ var _ = Describe("Patched Baseline Algorithm Integration", func() { It("should successfully reconcile a static asset", func() { // Create a simple ConfigMap asset for testing asset := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "test-config", "namespace": testNs, }, - "data": map[string]interface{}{ + "data": map[string]any{ "key1": "value1", }, }, @@ -96,14 +96,14 @@ var _ = Describe("Patched Baseline Algorithm Integration", func() { It("should detect and apply drift", func() { // Create initial object obj := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "drift-test", "namespace": testNs, }, - "data": map[string]interface{}{ + "data": map[string]any{ "replicas": "3", }, }, @@ -154,17 +154,17 @@ var _ = Describe("Patched Baseline Algorithm Integration", func() { It("should apply JSON patch from annotation", func() { // Create object with patch annotation obj := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "patch-test", "namespace": testNs, - "annotations": map[string]interface{}{ + "annotations": map[string]any{ overrides.PatchAnnotation: `[{"op": "add", "path": "/data/newKey", "value": "patched"}]`, }, }, - "data": map[string]interface{}{ + "data": map[string]any{ "original": "value", }, }, @@ -203,17 +203,17 @@ var _ = Describe("Patched Baseline Algorithm Integration", func() { It("should mask ignored fields", func() { // Create initial object in cluster live := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "mask-test", "namespace": testNs, - "annotations": map[string]interface{}{ + "annotations": map[string]any{ overrides.AnnotationIgnoreFields: "/data/userManaged", }, }, - "data": map[string]interface{}{ + "data": map[string]any{ "userManaged": "user-value", "operatorManaged": "operator-value", }, @@ -226,14 +226,14 @@ var _ = Describe("Patched Baseline Algorithm Integration", func() { // Create desired state (operator wants to change both fields) desired := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "mask-test", "namespace": testNs, }, - "data": map[string]interface{}{ + "data": map[string]any{ "userManaged": "operator-new-value", "operatorManaged": "operator-new-value", }, @@ -253,17 +253,17 @@ var _ = Describe("Patched Baseline Algorithm Integration", func() { It("should skip reconciliation for unmanaged resources", func() { // Create object with unmanaged annotation obj := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "unmanaged-test", "namespace": testNs, - "annotations": map[string]interface{}{ + "annotations": map[string]any{ overrides.AnnotationMode: overrides.ModeUnmanaged, }, }, - "data": map[string]interface{}{ + "data": map[string]any{ "key": "user-value", }, }, @@ -332,14 +332,14 @@ var _ = Describe("Patched Baseline Algorithm Integration", func() { Describe("SSA Field Ownership", func() { It("should track field ownership with SSA", func() { obj := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "ssa-test", "namespace": testNs, }, - "data": map[string]interface{}{ + "data": map[string]any{ "field1": "value1", }, }, @@ -375,14 +375,14 @@ var _ = Describe("Patched Baseline Algorithm Integration", func() { It("should handle conflicts with different field managers", func() { obj := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "conflict-test", "namespace": testNs, }, - "data": map[string]interface{}{ + "data": map[string]any{ "shared": "operator-value", }, }, @@ -432,18 +432,18 @@ var _ = Describe("Patched Baseline Algorithm Integration", func() { It("should handle patch + mask + drift + throttle in one flow", func() { // Create initial object in cluster (simulating existing resource) live := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "combined-test", "namespace": testNs, - "annotations": map[string]interface{}{ + "annotations": map[string]any{ overrides.PatchAnnotation: `[{"op": "add", "path": "/data/patched", "value": "yes"}]`, overrides.AnnotationIgnoreFields: "/data/userField", }, }, - "data": map[string]interface{}{ + "data": map[string]any{ "userField": "user-controlled", "operatorField": "old-operator-value", }, @@ -463,14 +463,14 @@ var _ = Describe("Patched Baseline Algorithm Integration", func() { // Create desired state (what operator wants) desiredState := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "combined-test", "namespace": testNs, }, - "data": map[string]interface{}{ + "data": map[string]any{ "userField": "operator-wants-to-change-this", "operatorField": "new-operator-value", }, @@ -539,14 +539,14 @@ var _ = Describe("Patched Baseline Algorithm Integration", func() { It("should automatically label managed objects", func() { // Create an object that will be managed obj := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "label-test", "namespace": testNs, }, - "data": map[string]interface{}{ + "data": map[string]any{ "key": "value", }, }, @@ -575,17 +575,17 @@ var _ = Describe("Patched Baseline Algorithm Integration", func() { It("should adopt existing unlabeled objects", func() { // Create an object without the managed-by label (simulating pre-existing resource) unlabeled := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "adoption-test", "namespace": testNs, - "labels": map[string]interface{}{ + "labels": map[string]any{ "existing-label": "keep-me", }, }, - "data": map[string]interface{}{ + "data": map[string]any{ "original": "data", }, }, @@ -607,14 +607,14 @@ var _ = Describe("Patched Baseline Algorithm Integration", func() { // Now apply using the applier - it should adopt the object by adding the label updated := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "adoption-test", "namespace": testNs, }, - "data": map[string]interface{}{ + "data": map[string]any{ "original": "data", "added": "by-operator", }, @@ -650,14 +650,14 @@ var _ = Describe("Patched Baseline Algorithm Integration", func() { It("should re-label objects if label is removed", func() { // Create a labeled object labeled := &unstructured.Unstructured{ - Object: map[string]interface{}{ + Object: map[string]any{ "apiVersion": "v1", "kind": "ConfigMap", - "metadata": map[string]interface{}{ + "metadata": map[string]any{ "name": "relabel-test", "namespace": testNs, }, - "data": map[string]interface{}{ + "data": map[string]any{ "key": "value", }, }, diff --git a/test/prometheus_rules_test.go b/test/prometheus_rules_test.go index 04c9db99..d0b88920 100644 --- a/test/prometheus_rules_test.go +++ b/test/prometheus_rules_test.go @@ -64,7 +64,7 @@ var _ = Describe("Prometheus Alert Rules", func() { Expect(err).NotTo(HaveOccurred()) Expect(found).To(BeTrue(), "spec field should exist") - specMap, ok := spec.(map[string]interface{}) + specMap, ok := spec.(map[string]any) Expect(ok).To(BeTrue(), "spec should be a map") groups, found, err := unstructured.NestedSlice(specMap, "groups") @@ -73,40 +73,40 @@ var _ = Describe("Prometheus Alert Rules", func() { Expect(groups).To(HaveLen(2), "should have 2 rule groups (critical + warning)") By("verifying critical alert group") - criticalGroup := groups[0].(map[string]interface{}) + criticalGroup := groups[0].(map[string]any) Expect(criticalGroup["name"]).To(Equal("virt-platform-autopilot.critical")) - criticalRules := criticalGroup["rules"].([]interface{}) + criticalRules := criticalGroup["rules"].([]any) Expect(criticalRules).To(HaveLen(1), "critical group should have 1 alert") - syncFailedAlert := criticalRules[0].(map[string]interface{}) + syncFailedAlert := criticalRules[0].(map[string]any) Expect(syncFailedAlert["alert"]).To(Equal("VirtPlatformSyncFailed")) Expect(syncFailedAlert["expr"]).To(ContainSubstring("kubevirt_autopilot_compliance_status == 0")) Expect(syncFailedAlert["for"]).To(Equal("15m")) - labels := syncFailedAlert["labels"].(map[string]interface{}) + labels := syncFailedAlert["labels"].(map[string]any) Expect(labels["severity"]).To(Equal("critical")) By("verifying warning alert group") - warningGroup := groups[1].(map[string]interface{}) + warningGroup := groups[1].(map[string]any) Expect(warningGroup["name"]).To(Equal("virt-platform-autopilot.warning")) - warningRules := warningGroup["rules"].([]interface{}) + warningRules := warningGroup["rules"].([]any) Expect(warningRules).To(HaveLen(3), "warning group should have 3 alerts") // Verify thrashing alert - thrashingAlert := warningRules[0].(map[string]interface{}) + thrashingAlert := warningRules[0].(map[string]any) Expect(thrashingAlert["alert"]).To(Equal("VirtPlatformThrashingDetected")) Expect(thrashingAlert["expr"]).To(ContainSubstring("kubevirt_autopilot_paused_resources > 0")) // Verify dependency alert - dependencyAlert := warningRules[1].(map[string]interface{}) + dependencyAlert := warningRules[1].(map[string]any) Expect(dependencyAlert["alert"]).To(Equal("VirtPlatformDependencyMissing")) Expect(dependencyAlert["expr"]).To(ContainSubstring("kubevirt_autopilot_missing_dependency == 1")) Expect(dependencyAlert["for"]).To(Equal("5m")) // Verify tombstone alert - tombstoneAlert := warningRules[2].(map[string]interface{}) + tombstoneAlert := warningRules[2].(map[string]any) Expect(tombstoneAlert["alert"]).To(Equal("VirtPlatformTombstoneStuck")) Expect(tombstoneAlert["expr"]).To(ContainSubstring("kubevirt_autopilot_tombstone_status < 0")) Expect(tombstoneAlert["for"]).To(Equal("30m")) @@ -116,12 +116,12 @@ var _ = Describe("Prometheus Alert Rules", func() { By("extracting all rules from all groups") groups, _, _ := unstructured.NestedSlice(prometheusRuleObj.Object, "spec", "groups") - allAlerts := []map[string]interface{}{} + allAlerts := []map[string]any{} for _, group := range groups { - groupMap := group.(map[string]interface{}) - rules := groupMap["rules"].([]interface{}) + groupMap := group.(map[string]any) + rules := groupMap["rules"].([]any) for _, rule := range rules { - allAlerts = append(allAlerts, rule.(map[string]interface{})) + allAlerts = append(allAlerts, rule.(map[string]any)) } } @@ -130,7 +130,7 @@ var _ = Describe("Prometheus Alert Rules", func() { alertName := alert["alert"].(string) // Verify labels - labels, labelsExist := alert["labels"].(map[string]interface{}) + labels, labelsExist := alert["labels"].(map[string]any) Expect(labelsExist).To(BeTrue(), "Alert %s should have labels", alertName) Expect(labels["severity"]).ToNot(BeEmpty(), "Alert %s should have severity label", alertName) Expect(labels["operator"]).To(Equal("virt-platform-autopilot"), "Alert %s should have operator label", alertName) @@ -139,7 +139,7 @@ var _ = Describe("Prometheus Alert Rules", func() { Expect(labels["operator_health_impact"]).To(Equal(labels["severity"]), "Alert %s operator_health_impact should match severity", alertName) // Verify annotations - annotations, annotationsExist := alert["annotations"].(map[string]interface{}) + annotations, annotationsExist := alert["annotations"].(map[string]any) Expect(annotationsExist).To(BeTrue(), "Alert %s should have annotations", alertName) Expect(annotations["summary"]).ToNot(BeEmpty(), "Alert %s should have summary annotation", alertName) Expect(annotations["description"]).ToNot(BeEmpty(), "Alert %s should have description annotation", alertName) @@ -184,10 +184,10 @@ var _ = Describe("Prometheus Alert Rules", func() { groups, _, _ := unstructured.NestedSlice(prometheusRuleObj.Object, "spec", "groups") // Get VirtPlatformSyncFailed alert annotations - criticalGroup := groups[0].(map[string]interface{}) - criticalRules := criticalGroup["rules"].([]interface{}) - syncFailedAlert := criticalRules[0].(map[string]interface{}) - annotations := syncFailedAlert["annotations"].(map[string]interface{}) + criticalGroup := groups[0].(map[string]any) + criticalRules := criticalGroup["rules"].([]any) + syncFailedAlert := criticalRules[0].(map[string]any) + annotations := syncFailedAlert["annotations"].(map[string]any) summary := annotations["summary"].(string) description := annotations["description"].(string) @@ -200,12 +200,12 @@ var _ = Describe("Prometheus Alert Rules", func() { By("verifying all alerts have properly escaped Prometheus variables") for _, group := range groups { - groupMap := group.(map[string]interface{}) - rules := groupMap["rules"].([]interface{}) + groupMap := group.(map[string]any) + rules := groupMap["rules"].([]any) for _, rule := range rules { - alert := rule.(map[string]interface{}) + alert := rule.(map[string]any) alertName := alert["alert"].(string) - alertAnnotations := alert["annotations"].(map[string]interface{}) + alertAnnotations := alert["annotations"].(map[string]any) alertSummary := alertAnnotations["summary"].(string) alertDescription := alertAnnotations["description"].(string) diff --git a/test/tombstone_integration_test.go b/test/tombstone_integration_test.go index b40b504c..b3cbef1b 100644 --- a/test/tombstone_integration_test.go +++ b/test/tombstone_integration_test.go @@ -83,7 +83,7 @@ var _ = Describe("Tombstone Integration", func() { cm.SetLabels(map[string]string{ assets.TombstoneLabel: assets.TombstoneLabelValue, }) - cm.Object["data"] = map[string]interface{}{"key": "value"} + cm.Object["data"] = map[string]any{"key": "value"} Expect(k8sClient.Create(ctx, cm)).To(Succeed()) @@ -123,7 +123,7 @@ var _ = Describe("Tombstone Integration", func() { cm.SetKind("ConfigMap") cm.SetName("unmanaged-config") cm.SetNamespace(testNs) - cm.Object["data"] = map[string]interface{}{"key": "value"} + cm.Object["data"] = map[string]any{"key": "value"} Expect(k8sClient.Create(ctx, cm)).To(Succeed()) @@ -165,7 +165,7 @@ var _ = Describe("Tombstone Integration", func() { cm.SetLabels(map[string]string{ assets.TombstoneLabel: "some-other-operator", }) - cm.Object["data"] = map[string]interface{}{"key": "value"} + cm.Object["data"] = map[string]any{"key": "value"} Expect(k8sClient.Create(ctx, cm)).To(Succeed()) @@ -195,7 +195,7 @@ var _ = Describe("Tombstone Integration", func() { cm.SetLabels(map[string]string{ assets.TombstoneLabel: assets.TombstoneLabelValue, }) - cm.Object["data"] = map[string]interface{}{"key": "value"} + cm.Object["data"] = map[string]any{"key": "value"} Expect(k8sClient.Create(ctx, cm)).To(Succeed())