Skip to content

Commit 971f839

Browse files
authored
feat(kubernetes): add apiVersion field to KubernetesCheck (#2860)
* feat(kubernetes): add apiVersion field to KubernetesCheck Allows specifying apiVersion to distinguish between resources with the same Kind but different API groups (e.g., v1/Service vs serving.knative.dev/v1/Service). When apiVersion is set, the check uses the format 'apiVersion/Kind' to query resources via GetClientByGroupVersionKind for precise GVK targeting. Closes #2859 * test(kubernetes): add fixture for apiVersion feature Tests same Kind (Event) with different apiVersions (v1 vs events.k8s.io/v1). * chore: use local duty with apiVersion/Kind support Temporary replace directive for flanksource/duty#1757 * chore(deps): update duty and remove local replace * make manifests & make resources
1 parent 804c52f commit 971f839

File tree

11 files changed

+144
-42
lines changed

11 files changed

+144
-42
lines changed

Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,10 @@ gen-schemas:
7676
cd hack/generate-schemas && \
7777
go mod edit -module=github.com/flanksource/canary-checker/hack/generate-schemas && \
7878
go mod edit -require=github.com/flanksource/canary-checker@v1.0.0 && \
79-
go mod edit -replace=github.com/flanksource/canary-checker=../../ && \
79+
go mod edit -replace=github.com/flanksource/canary-checker=../../ && \
80+
if grep -v "^//" ../../go.mod | grep -q "replace.*github.com/flanksource/duty.*=>"; then \
81+
go mod edit -replace=github.com/flanksource/duty=../../../duty; \
82+
fi && \
8083
go mod tidy && \
8184
go run ./main.go
8285

api/v1/checks.go

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,21 +1066,43 @@ func (rs ResourceSelector) ToDutySelector() types.ResourceSelector {
10661066
}
10671067

10681068
type KubernetesCheck struct {
1069+
// Description provides the base check metadata including name, description,
1070+
// namespace, icon, labels, and metrics export configuration.
10691071
Description `yaml:",inline" json:",inline"`
1072+
1073+
// Templatable provides test, display, and transform templates for the check results.
10701074
Templatable `yaml:",inline" json:",inline"`
1071-
Relatable `yaml:",inline" json:",inline"`
1072-
Namespace ResourceSelector `yaml:"namespaceSelector,omitempty" json:"namespaceSelector,omitempty"`
1073-
Resource ResourceSelector `yaml:"resource,omitempty" json:"resource,omitempty"`
1074-
// KubeConfig is the kubeconfig or the path to the kubeconfig file.
1075+
1076+
// Relatable defines relationships to link check results to components and configs.
1077+
Relatable `yaml:",inline" json:",inline"`
1078+
1079+
// Namespace specifies which namespace(s) to search for resources.
1080+
// Use empty ResourceSelector to search in canary's namespace.
1081+
Namespace ResourceSelector `yaml:"namespaceSelector,omitempty" json:"namespaceSelector,omitempty"`
1082+
1083+
// Resource specifies which resources to select by name, labels, or field selectors.
1084+
Resource ResourceSelector `yaml:"resource,omitempty" json:"resource,omitempty"`
1085+
1086+
// KubernetesConnection defines how to connect to the Kubernetes cluster.
1087+
// Supports kubeconfig path/content, EKS, GKE, CNRM connections, or connection reference.
10751088
connection.KubernetesConnection `yaml:",inline" json:",inline"`
1076-
// Ignore the specified resources from the fetched resources. Can be a glob pattern.
1089+
1090+
// Ignore specifies resources to exclude from the fetched results.
1091+
// Values can be glob patterns (e.g., "kube-*", "*-system").
10771092
Ignore []string `yaml:"ignore,omitempty" json:"ignore,omitempty"`
1078-
Kind string `yaml:"kind" json:"kind"`
10791093

1080-
// Fail the check if any resources are unhealthy
1094+
// Kind is the Kubernetes resource Kind to check (e.g., "Pod", "Deployment", "Service").
1095+
// This is a required field.
1096+
Kind string `yaml:"kind" json:"kind"`
1097+
1098+
// APIVersion is the Kubernetes API version for the resource (e.g., "v1", "apps/v1", "serving.knative.dev/v1").
1099+
// Used to distinguish between resources with the same Kind but different API groups.
1100+
APIVersion string `yaml:"apiVersion,omitempty" json:"apiVersion,omitempty"`
1101+
1102+
// Healthy when true, fails the check if any resources are unhealthy.
10811103
Healthy bool `yaml:"healthy,omitempty" json:"healthy,omitempty"`
10821104

1083-
// Fail the check if any resources are not ready
1105+
// Ready when true, fails the check if any resources are not ready.
10841106
Ready bool `yaml:"ready,omitempty" json:"ready,omitempty"`
10851107
}
10861108

checks/kubernetes.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,11 @@ func (c *KubernetesChecker) Check(ctx context.Context, extConfig external.Check)
6363
if namespace != "" {
6464
selector.Namespace = namespace
6565
}
66-
selector.Types = []string{check.Kind}
66+
if check.APIVersion != "" {
67+
selector.Types = []string{check.APIVersion + "/" + check.Kind}
68+
} else {
69+
selector.Types = []string{check.Kind}
70+
}
6771
resources, err := k8sClient.QueryResources(ctx, selector)
6872

6973
if err != nil {

config/deploy/Canary.yml

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5153,6 +5153,11 @@ spec:
51535153
kubernetes:
51545154
items:
51555155
properties:
5156+
apiVersion:
5157+
description: |-
5158+
APIVersion is the Kubernetes API version for the resource (e.g., "v1", "apps/v1", "serving.knative.dev/v1").
5159+
Used to distinguish between resources with the same Kind but different API groups.
5160+
type: string
51565161
cnrm:
51575162
properties:
51585163
clusterResource:
@@ -5456,16 +5461,21 @@ spec:
54565461
- zone
54575462
type: object
54585463
healthy:
5459-
description: Fail the check if any resources are unhealthy
5464+
description: Healthy when true, fails the check if any resources are unhealthy.
54605465
type: boolean
54615466
icon:
54625467
type: string
54635468
ignore:
5464-
description: Ignore the specified resources from the fetched resources. Can be a glob pattern.
5469+
description: |-
5470+
Ignore specifies resources to exclude from the fetched results.
5471+
Values can be glob patterns (e.g., "kube-*", "*-system").
54655472
items:
54665473
type: string
54675474
type: array
54685475
kind:
5476+
description: |-
5477+
Kind is the Kubernetes resource Kind to check (e.g., "Pod", "Deployment", "Service").
5478+
This is a required field.
54695479
type: string
54705480
kubeconfig:
54715481
properties:
@@ -5547,6 +5557,9 @@ spec:
55475557
description: Namespace to insert the check into, if different to the namespace the canary is defined, e.g.
55485558
type: string
55495559
namespaceSelector:
5560+
description: |-
5561+
Namespace specifies which namespace(s) to search for resources.
5562+
Use empty ResourceSelector to search in canary's namespace.
55505563
properties:
55515564
fieldSelector:
55525565
type: string
@@ -5558,12 +5571,13 @@ spec:
55585571
type: string
55595572
type: object
55605573
ready:
5561-
description: Fail the check if any resources are not ready
5574+
description: Ready when true, fails the check if any resources are not ready.
55625575
type: boolean
55635576
relationships:
55645577
type: object
55655578
x-kubernetes-preserve-unknown-fields: true
55665579
resource:
5580+
description: Resource specifies which resources to select by name, labels, or field selectors.
55675581
properties:
55685582
fieldSelector:
55695583
type: string

config/deploy/manifests.yaml

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5152,6 +5152,11 @@ spec:
51525152
kubernetes:
51535153
items:
51545154
properties:
5155+
apiVersion:
5156+
description: |-
5157+
APIVersion is the Kubernetes API version for the resource (e.g., "v1", "apps/v1", "serving.knative.dev/v1").
5158+
Used to distinguish between resources with the same Kind but different API groups.
5159+
type: string
51555160
cnrm:
51565161
properties:
51575162
clusterResource:
@@ -5455,16 +5460,21 @@ spec:
54555460
- zone
54565461
type: object
54575462
healthy:
5458-
description: Fail the check if any resources are unhealthy
5463+
description: Healthy when true, fails the check if any resources are unhealthy.
54595464
type: boolean
54605465
icon:
54615466
type: string
54625467
ignore:
5463-
description: Ignore the specified resources from the fetched resources. Can be a glob pattern.
5468+
description: |-
5469+
Ignore specifies resources to exclude from the fetched results.
5470+
Values can be glob patterns (e.g., "kube-*", "*-system").
54645471
items:
54655472
type: string
54665473
type: array
54675474
kind:
5475+
description: |-
5476+
Kind is the Kubernetes resource Kind to check (e.g., "Pod", "Deployment", "Service").
5477+
This is a required field.
54685478
type: string
54695479
kubeconfig:
54705480
properties:
@@ -5546,6 +5556,9 @@ spec:
55465556
description: Namespace to insert the check into, if different to the namespace the canary is defined, e.g.
55475557
type: string
55485558
namespaceSelector:
5559+
description: |-
5560+
Namespace specifies which namespace(s) to search for resources.
5561+
Use empty ResourceSelector to search in canary's namespace.
55495562
properties:
55505563
fieldSelector:
55515564
type: string
@@ -5557,12 +5570,13 @@ spec:
55575570
type: string
55585571
type: object
55595572
ready:
5560-
description: Fail the check if any resources are not ready
5573+
description: Ready when true, fails the check if any resources are not ready.
55615574
type: boolean
55625575
relationships:
55635576
type: object
55645577
x-kubernetes-preserve-unknown-fields: true
55655578
resource:
5579+
description: Resource specifies which resources to select by name, labels, or field selectors.
55665580
properties:
55675581
fieldSelector:
55685582
type: string

config/schemas/canary.schema.json

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2929,10 +2929,12 @@
29292929
"description": "Relationships defines a way to link the check results to components and configs\nusing lookup expressions."
29302930
},
29312931
"namespaceSelector": {
2932-
"$ref": "#/$defs/ResourceSelector"
2932+
"$ref": "#/$defs/ResourceSelector",
2933+
"description": "Namespace specifies which namespace(s) to search for resources.\nUse empty ResourceSelector to search in canary's namespace."
29332934
},
29342935
"resource": {
2935-
"$ref": "#/$defs/ResourceSelector"
2936+
"$ref": "#/$defs/ResourceSelector",
2937+
"description": "Resource specifies which resources to select by name, labels, or field selectors."
29362938
},
29372939
"connection": {
29382940
"type": "string"
@@ -2954,18 +2956,23 @@
29542956
"type": "string"
29552957
},
29562958
"type": "array",
2957-
"description": "Ignore the specified resources from the fetched resources. Can be a glob pattern."
2959+
"description": "Ignore specifies resources to exclude from the fetched results.\nValues can be glob patterns (e.g., \"kube-*\", \"*-system\")."
29582960
},
29592961
"kind": {
2960-
"type": "string"
2962+
"type": "string",
2963+
"description": "Kind is the Kubernetes resource Kind to check (e.g., \"Pod\", \"Deployment\", \"Service\").\nThis is a required field."
2964+
},
2965+
"apiVersion": {
2966+
"type": "string",
2967+
"description": "APIVersion is the Kubernetes API version for the resource (e.g., \"v1\", \"apps/v1\", \"serving.knative.dev/v1\").\nUsed to distinguish between resources with the same Kind but different API groups."
29612968
},
29622969
"healthy": {
29632970
"type": "boolean",
2964-
"description": "Fail the check if any resources are unhealthy"
2971+
"description": "Healthy when true, fails the check if any resources are unhealthy."
29652972
},
29662973
"ready": {
29672974
"type": "boolean",
2968-
"description": "Fail the check if any resources are not ready"
2975+
"description": "Ready when true, fails the check if any resources are not ready."
29692976
}
29702977
},
29712978
"additionalProperties": false,

config/schemas/component.schema.json

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3225,10 +3225,12 @@
32253225
"description": "Relationships defines a way to link the check results to components and configs\nusing lookup expressions."
32263226
},
32273227
"namespaceSelector": {
3228-
"$ref": "#/$defs/ResourceSelector"
3228+
"$ref": "#/$defs/ResourceSelector",
3229+
"description": "Namespace specifies which namespace(s) to search for resources.\nUse empty ResourceSelector to search in canary's namespace."
32293230
},
32303231
"resource": {
3231-
"$ref": "#/$defs/ResourceSelector"
3232+
"$ref": "#/$defs/ResourceSelector",
3233+
"description": "Resource specifies which resources to select by name, labels, or field selectors."
32323234
},
32333235
"connection": {
32343236
"type": "string"
@@ -3250,18 +3252,23 @@
32503252
"type": "string"
32513253
},
32523254
"type": "array",
3253-
"description": "Ignore the specified resources from the fetched resources. Can be a glob pattern."
3255+
"description": "Ignore specifies resources to exclude from the fetched results.\nValues can be glob patterns (e.g., \"kube-*\", \"*-system\")."
32543256
},
32553257
"kind": {
3256-
"type": "string"
3258+
"type": "string",
3259+
"description": "Kind is the Kubernetes resource Kind to check (e.g., \"Pod\", \"Deployment\", \"Service\").\nThis is a required field."
3260+
},
3261+
"apiVersion": {
3262+
"type": "string",
3263+
"description": "APIVersion is the Kubernetes API version for the resource (e.g., \"v1\", \"apps/v1\", \"serving.knative.dev/v1\").\nUsed to distinguish between resources with the same Kind but different API groups."
32573264
},
32583265
"healthy": {
32593266
"type": "boolean",
3260-
"description": "Fail the check if any resources are unhealthy"
3267+
"description": "Healthy when true, fails the check if any resources are unhealthy."
32613268
},
32623269
"ready": {
32633270
"type": "boolean",
3264-
"description": "Fail the check if any resources are not ready"
3271+
"description": "Ready when true, fails the check if any resources are not ready."
32653272
}
32663273
},
32673274
"additionalProperties": false,

config/schemas/health_kubernetes.schema.json

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -234,10 +234,12 @@
234234
"description": "Relationships defines a way to link the check results to components and configs\nusing lookup expressions."
235235
},
236236
"namespaceSelector": {
237-
"$ref": "#/$defs/ResourceSelector"
237+
"$ref": "#/$defs/ResourceSelector",
238+
"description": "Namespace specifies which namespace(s) to search for resources.\nUse empty ResourceSelector to search in canary's namespace."
238239
},
239240
"resource": {
240-
"$ref": "#/$defs/ResourceSelector"
241+
"$ref": "#/$defs/ResourceSelector",
242+
"description": "Resource specifies which resources to select by name, labels, or field selectors."
241243
},
242244
"connection": {
243245
"type": "string"
@@ -259,18 +261,23 @@
259261
"type": "string"
260262
},
261263
"type": "array",
262-
"description": "Ignore the specified resources from the fetched resources. Can be a glob pattern."
264+
"description": "Ignore specifies resources to exclude from the fetched results.\nValues can be glob patterns (e.g., \"kube-*\", \"*-system\")."
263265
},
264266
"kind": {
265-
"type": "string"
267+
"type": "string",
268+
"description": "Kind is the Kubernetes resource Kind to check (e.g., \"Pod\", \"Deployment\", \"Service\").\nThis is a required field."
269+
},
270+
"apiVersion": {
271+
"type": "string",
272+
"description": "APIVersion is the Kubernetes API version for the resource (e.g., \"v1\", \"apps/v1\", \"serving.knative.dev/v1\").\nUsed to distinguish between resources with the same Kind but different API groups."
266273
},
267274
"healthy": {
268275
"type": "boolean",
269-
"description": "Fail the check if any resources are unhealthy"
276+
"description": "Healthy when true, fails the check if any resources are unhealthy."
270277
},
271278
"ready": {
272279
"type": "boolean",
273-
"description": "Fail the check if any resources are not ready"
280+
"description": "Ready when true, fails the check if any resources are not ready."
274281
}
275282
},
276283
"additionalProperties": false,

config/schemas/topology.schema.json

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3237,10 +3237,12 @@
32373237
"description": "Relationships defines a way to link the check results to components and configs\nusing lookup expressions."
32383238
},
32393239
"namespaceSelector": {
3240-
"$ref": "#/$defs/ResourceSelector"
3240+
"$ref": "#/$defs/ResourceSelector",
3241+
"description": "Namespace specifies which namespace(s) to search for resources.\nUse empty ResourceSelector to search in canary's namespace."
32413242
},
32423243
"resource": {
3243-
"$ref": "#/$defs/ResourceSelector"
3244+
"$ref": "#/$defs/ResourceSelector",
3245+
"description": "Resource specifies which resources to select by name, labels, or field selectors."
32443246
},
32453247
"connection": {
32463248
"type": "string"
@@ -3262,18 +3264,23 @@
32623264
"type": "string"
32633265
},
32643266
"type": "array",
3265-
"description": "Ignore the specified resources from the fetched resources. Can be a glob pattern."
3267+
"description": "Ignore specifies resources to exclude from the fetched results.\nValues can be glob patterns (e.g., \"kube-*\", \"*-system\")."
32663268
},
32673269
"kind": {
3268-
"type": "string"
3270+
"type": "string",
3271+
"description": "Kind is the Kubernetes resource Kind to check (e.g., \"Pod\", \"Deployment\", \"Service\").\nThis is a required field."
3272+
},
3273+
"apiVersion": {
3274+
"type": "string",
3275+
"description": "APIVersion is the Kubernetes API version for the resource (e.g., \"v1\", \"apps/v1\", \"serving.knative.dev/v1\").\nUsed to distinguish between resources with the same Kind but different API groups."
32693276
},
32703277
"healthy": {
32713278
"type": "boolean",
3272-
"description": "Fail the check if any resources are unhealthy"
3279+
"description": "Healthy when true, fails the check if any resources are unhealthy."
32733280
},
32743281
"ready": {
32753282
"type": "boolean",
3276-
"description": "Fail the check if any resources are not ready"
3283+
"description": "Ready when true, fails the check if any resources are not ready."
32773284
}
32783285
},
32793286
"additionalProperties": false,
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
apiVersion: canaries.flanksource.com/v1
2+
kind: Canary
3+
metadata:
4+
name: kube-apiversion-pass
5+
spec:
6+
schedule: "@every 5m"
7+
kubernetes:
8+
# Same Kind (Event), different apiVersions
9+
- name: events-core
10+
kind: Event
11+
apiVersion: v1
12+
namespaceSelector:
13+
name: kube-system
14+
15+
- name: events-k8s-io
16+
kind: Event
17+
apiVersion: events.k8s.io/v1
18+
namespaceSelector:
19+
name: kube-system

0 commit comments

Comments
 (0)