Repository: doitintl/kube-no-trouble
Pull request #374 (2022-09-30 14:37:49)

feat: Cover deprecated autoscaling/v2beta1 and autoscaling/v2beta2
Closes https://github.com/doitintl/kube-no-trouble/pull/330

stepanstipl: _Note: Dupe of #330 and #368, related to #356_

Patch:
diff --git a/fixtures/autoscaler-v2beta1.yaml b/fixtures/autoscaler-v2beta1.yaml
new file mode 100644
index 0000000..6bb0533
--- /dev/null
+++ b/fixtures/autoscaler-v2beta1.yaml
@@ -0,0 +1,30 @@
+apiVersion: autoscaling/v2beta1
+kind: HorizontalPodAutoscaler
+metadata:
+  name: php-apache
+spec:
+  scaleTargetRef:
+    apiVersion: apps/v1
+    kind: Deployment
+    name: php-apache
+  minReplicas: 1
+  maxReplicas: 10
+  metrics:
+  - type: Resource
+    resource:
+      name: cpu
+      target:
+        type: Utilization
+        averageUtilization: 50
+status:
+  observedGeneration: 1
+  lastScaleTime: 12
+  currentReplicas: 1
+  desiredReplicas: 1
+  currentMetrics:
+  - type: Resource
+    resource:
+      name: cpu
+      current:
+        averageUtilization: 0
+        averageValue: 0
diff --git a/fixtures/autoscaler-v2beta2.yaml b/fixtures/autoscaler-v2beta2.yaml
new file mode 100644
index 0000000..0de86e4
--- /dev/null
+++ b/fixtures/autoscaler-v2beta2.yaml
@@ -0,0 +1,30 @@
+apiVersion: autoscaling/v2beta2
+kind: HorizontalPodAutoscaler
+metadata:
+  name: php-apache
+spec:
+  scaleTargetRef:
+    apiVersion: apps/v1
+    kind: Deployment
+    name: php-apache
+  minReplicas: 1
+  maxReplicas: 10
+  metrics:
+  - type: Resource
+    resource:
+      name: cpu
+      target:
+        type: Utilization
+        averageUtilization: 50
+status:
+  observedGeneration: 1
+  lastScaleTime: 12
+  currentReplicas: 1
+  desiredReplicas: 1
+  currentMetrics:
+  - type: Resource
+    resource:
+      name: cpu
+      current:
+        averageUtilization: 0
+        averageValue: 0
diff --git a/pkg/collector/cluster.go b/pkg/collector/cluster.go
index bd69c50..baa8415 100644
--- a/pkg/collector/cluster.go
+++ b/pkg/collector/cluster.go
@@ -102,6 +102,7 @@ func (c *ClusterCollector) Get() ([]map[string]interface{}, error) {
 		schema.GroupVersionResource{Group: "policy", Version: "v1beta1", Resource: "podsecuritypolicies"},
 		schema.GroupVersionResource{Group: "discovery.k8s.io", Version: "v1", Resource: "endpointslices"},
 		schema.GroupVersionResource{Group: "batch", Version: "v1", Resource: "cronjobs"},
+		schema.GroupVersionResource{Group: "autoscaling", Version: "v2", Resource: "horizontalpodautoscalers"},
 		schema.GroupVersionResource{Group: "snapshot.storage.k8s.io", Version: "v1", Resource: "volumesnapshots"},
 		schema.GroupVersionResource{Group: "snapshot.storage.k8s.io", Version: "v1", Resource: "volumesnapshotclasses"},
 		schema.GroupVersionResource{Group: "snapshot.storage.k8s.io", Version: "v1", Resource: "volumesnapshotcontents"},
diff --git a/pkg/rules/rego/deprecated-1-26.rego b/pkg/rules/rego/deprecated-1-26.rego
new file mode 100644
index 0000000..fe67e3e
--- /dev/null
+++ b/pkg/rules/rego/deprecated-1-26.rego
@@ -0,0 +1,42 @@
+package deprecated126
+
+main[return] {
+	resource := input[_]
+	api := deprecated_resource(resource)
+	return := {
+		"Name": get_default(resource.metadata, "name", "<undefined>"),
+		# Namespace does not have to be defined in case of local manifests
+		"Namespace": get_default(resource.metadata, "namespace", "<undefined>"),
+		"Kind": resource.kind,
+		"ApiVersion": api.old,
+		"ReplaceWith": api.new,
+		"RuleSet": "Deprecated APIs removed in 1.26",
+		"Since": api.since,
+	}
+}
+
+deprecated_resource(r) = api {
+	api := deprecated_api(r.kind, r.apiVersion)
+}
+
+deprecated_api(kind, api_version) = api {
+	deprecated_apis = {"HorizontalPodAutoscaler": {
+		"old": ["autoscaling/v2beta1", "autoscaling/v2beta2"],
+		"new": "autoscaling/v2",
+		"since": "1.23",
+	}}
+
+	deprecated_apis[kind].old[_] == api_version
+
+	api := {
+		"old": api_version,
+		"new": deprecated_apis[kind].new,
+		"since": deprecated_apis[kind].since,
+	}
+}
+
+get_default(val, key, _) = val[key]
+
+get_default(val, key, fallback) = fallback {
+	not val[key]
+}


Test patch:
diff --git a/test/rules_125_test.go b/test/rules_125_test.go
index a2d844c..975e632 100644
--- a/test/rules_125_test.go
+++ b/test/rules_125_test.go
@@ -6,11 +6,11 @@ import (
 
 func TestRego125(t *testing.T) {
 	testCases := []resourceFixtureTestCase{
-		{"RuntimeClass", []string{"../fixtures/runtimeclass-v1beta1.yaml"}, []string{"RuntimeClass"}},
+		{"CronJob", []string{"../fixtures/cronjob-v1beta1.yaml"}, []string{"CronJob"}},
+		{"EndpointSlice", []string{"../fixtures/endpointslice-v1beta1.yaml"}, []string{"EndpointSlice"}},
 		{"PodDisruptionBudget", []string{"../fixtures/poddisruptionbudget-v1beta1.yaml"}, []string{"PodDisruptionBudget"}},
 		{"PodSecurityPolicy", []string{"../fixtures/podsecuritypolicy-v1beta1.yaml"}, []string{"PodSecurityPolicy"}},
-		{"EndpointSlice", []string{"../fixtures/endpointslice-v1beta1.yaml"}, []string{"EndpointSlice"}},
-		{"CronJob", []string{"../fixtures/cronjob-v1beta1.yaml"}, []string{"CronJob"}},
+		{"RuntimeClass", []string{"../fixtures/runtimeclass-v1beta1.yaml"}, []string{"RuntimeClass"}},
 	}
 
 	testResourcesUsingFixtures(t, testCases)
diff --git a/test/rules_126_test.go b/test/rules_126_test.go
new file mode 100644
index 0000000..5fdd208
--- /dev/null
+++ b/test/rules_126_test.go
@@ -0,0 +1,14 @@
+package test
+
+import (
+	"testing"
+)
+
+func TestRego126(t *testing.T) {
+	testCases := []resourceFixtureTestCase{
+		{"AutoScaler-v2beta1", []string{"../fixtures/autoscaler-v2beta1.yaml"}, []string{"HorizontalPodAutoscaler"}},
+		{"AutoScaler-v2beta2", []string{"../fixtures/autoscaler-v2beta2.yaml"}, []string{"HorizontalPodAutoscaler"}},
+	}
+
+	testResourcesUsingFixtures(t, testCases)
+}