Skip to content

Commit ef1cd66

Browse files
authored
Handling the case when the Cluster Analyzer doesn't find a resource (#1760)
* Handling the case when the Cluster Analyzer doesn't find a resource * Add namespace information to Resource not found fail message
1 parent 64c63d3 commit ef1cd66

File tree

3 files changed

+321
-2
lines changed

3 files changed

+321
-2
lines changed
Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
{
2+
"kind": "NamespaceList",
3+
"apiVersion": "v1",
4+
"metadata": {
5+
"resourceVersion": "10270"
6+
},
7+
"items": [
8+
{
9+
"kind": "Namespace",
10+
"apiVersion": "v1",
11+
"metadata": {
12+
"name": "default",
13+
"uid": "a70276f2-a14e-494a-ba66-31548e09da6e",
14+
"resourceVersion": "67",
15+
"creationTimestamp": "2025-03-13T20:09:31Z",
16+
"labels": {
17+
"kubernetes.io/metadata.name": "default"
18+
},
19+
"managedFields": [
20+
{
21+
"manager": "kube-apiserver",
22+
"operation": "Update",
23+
"apiVersion": "v1",
24+
"time": "2025-03-13T20:09:31Z",
25+
"fieldsType": "FieldsV1",
26+
"fieldsV1": {
27+
"f:metadata": {
28+
"f:labels": {
29+
".": {},
30+
"f:kubernetes.io/metadata.name": {}
31+
}
32+
}
33+
}
34+
}
35+
]
36+
},
37+
"spec": {
38+
"finalizers": [
39+
"kubernetes"
40+
]
41+
},
42+
"status": {
43+
"phase": "Active"
44+
}
45+
},
46+
{
47+
"kind": "Namespace",
48+
"apiVersion": "v1",
49+
"metadata": {
50+
"name": "kube-node-lease",
51+
"uid": "77f4b65c-0cf1-4c5f-8d0d-cce5bcd4b7a4",
52+
"resourceVersion": "103",
53+
"creationTimestamp": "2025-03-13T20:09:31Z",
54+
"labels": {
55+
"kubernetes.io/metadata.name": "kube-node-lease"
56+
},
57+
"managedFields": [
58+
{
59+
"manager": "kube-apiserver",
60+
"operation": "Update",
61+
"apiVersion": "v1",
62+
"time": "2025-03-13T20:09:31Z",
63+
"fieldsType": "FieldsV1",
64+
"fieldsV1": {
65+
"f:metadata": {
66+
"f:labels": {
67+
".": {},
68+
"f:kubernetes.io/metadata.name": {}
69+
}
70+
}
71+
}
72+
}
73+
]
74+
},
75+
"spec": {
76+
"finalizers": [
77+
"kubernetes"
78+
]
79+
},
80+
"status": {
81+
"phase": "Active"
82+
}
83+
},
84+
{
85+
"kind": "Namespace",
86+
"apiVersion": "v1",
87+
"metadata": {
88+
"name": "kube-public",
89+
"uid": "b6b29c1d-e278-4916-a644-a4fcd9330654",
90+
"resourceVersion": "65",
91+
"creationTimestamp": "2025-03-13T20:09:31Z",
92+
"labels": {
93+
"kubernetes.io/metadata.name": "kube-public"
94+
},
95+
"managedFields": [
96+
{
97+
"manager": "kube-apiserver",
98+
"operation": "Update",
99+
"apiVersion": "v1",
100+
"time": "2025-03-13T20:09:31Z",
101+
"fieldsType": "FieldsV1",
102+
"fieldsV1": {
103+
"f:metadata": {
104+
"f:labels": {
105+
".": {},
106+
"f:kubernetes.io/metadata.name": {}
107+
}
108+
}
109+
}
110+
}
111+
]
112+
},
113+
"spec": {
114+
"finalizers": [
115+
"kubernetes"
116+
]
117+
},
118+
"status": {
119+
"phase": "Active"
120+
}
121+
},
122+
{
123+
"kind": "Namespace",
124+
"apiVersion": "v1",
125+
"metadata": {
126+
"name": "kube-system",
127+
"uid": "00470492-1276-40ff-9642-ba40327ffed6",
128+
"resourceVersion": "11",
129+
"creationTimestamp": "2025-03-13T20:09:31Z",
130+
"labels": {
131+
"kubernetes.io/metadata.name": "kube-system"
132+
},
133+
"managedFields": [
134+
{
135+
"manager": "kube-apiserver",
136+
"operation": "Update",
137+
"apiVersion": "v1",
138+
"time": "2025-03-13T20:09:31Z",
139+
"fieldsType": "FieldsV1",
140+
"fieldsV1": {
141+
"f:metadata": {
142+
"f:labels": {
143+
".": {},
144+
"f:kubernetes.io/metadata.name": {}
145+
}
146+
}
147+
}
148+
}
149+
]
150+
},
151+
"spec": {
152+
"finalizers": [
153+
"kubernetes"
154+
]
155+
},
156+
"status": {
157+
"phase": "Active"
158+
}
159+
},
160+
{
161+
"kind": "Namespace",
162+
"apiVersion": "v1",
163+
"metadata": {
164+
"name": "local-path-storage",
165+
"uid": "7a0660de-14e9-4aad-bc4d-3d78f0cc6619",
166+
"resourceVersion": "305",
167+
"creationTimestamp": "2025-03-13T20:09:35Z",
168+
"labels": {
169+
"kubernetes.io/metadata.name": "local-path-storage"
170+
},
171+
"annotations": {
172+
"kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"v1\",\"kind\":\"Namespace\",\"metadata\":{\"annotations\":{},\"name\":\"local-path-storage\"}}\n"
173+
},
174+
"managedFields": [
175+
{
176+
"manager": "kubectl-client-side-apply",
177+
"operation": "Update",
178+
"apiVersion": "v1",
179+
"time": "2025-03-13T20:09:35Z",
180+
"fieldsType": "FieldsV1",
181+
"fieldsV1": {
182+
"f:metadata": {
183+
"f:annotations": {
184+
".": {},
185+
"f:kubectl.kubernetes.io/last-applied-configuration": {}
186+
},
187+
"f:labels": {
188+
".": {},
189+
"f:kubernetes.io/metadata.name": {}
190+
}
191+
}
192+
}
193+
}
194+
]
195+
},
196+
"spec": {
197+
"finalizers": [
198+
"kubernetes"
199+
]
200+
},
201+
"status": {
202+
"phase": "Failed"
203+
}
204+
}
205+
]
206+
}

pkg/analyze/kube_resource.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,12 +246,20 @@ func (a *AnalyzeClusterResource) analyzeResource(analyzer *troubleshootv1beta2.C
246246
selected, err := FindResource(analyzer.Kind, analyzer.ClusterScoped, analyzer.Namespace, analyzer.Name, getFileContents)
247247
if err != nil {
248248
klog.Errorf("failed to find resource: %v", err)
249+
}
250+
if err != nil || selected == nil {
251+
var message string
252+
if analyzer.ClusterScoped {
253+
message = fmt.Sprintf("%s %s does not exist", analyzer.Kind, analyzer.Name)
254+
} else {
255+
message = fmt.Sprintf("%s %s in namespace %s does not exist", analyzer.Kind, analyzer.Name, analyzer.Namespace)
256+
}
249257
return &AnalyzeResult{
250258
Title: a.Title(),
251259
IconKey: "kubernetes_text_analyze",
252260
IconURI: "https://troubleshoot.sh/images/analyzer-icons/text-analyze.svg",
253261
IsFail: true,
254-
Message: "resource does not exist",
262+
Message: message,
255263
}, nil
256264
}
257265

pkg/analyze/kube_resource_test.go

Lines changed: 106 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ func Test_analyzeResource(t *testing.T) {
191191
IsWarn: false,
192192
IsFail: true,
193193
Title: "check-pvc-exists",
194-
Message: "YAML path provided is invalid",
194+
Message: "PersistentVolumeClaim data-postgresql-00 in namespace default does not exist",
195195
IconKey: "kubernetes_text_analyze",
196196
IconURI: "https://troubleshoot.sh/images/analyzer-icons/text-analyze.svg",
197197
},
@@ -335,6 +335,111 @@ func Test_analyzeResource(t *testing.T) {
335335
IconURI: "https://troubleshoot.sh/images/analyzer-icons/text-analyze.svg?w=13&h=16",
336336
},
337337
},
338+
{
339+
name: "pass when namespace exists",
340+
analyzer: troubleshootv1beta2.ClusterResource{
341+
AnalyzeMeta: troubleshootv1beta2.AnalyzeMeta{
342+
CheckName: "namespace-check",
343+
},
344+
Kind: "namespace",
345+
Name: "kube-node-lease",
346+
ClusterScoped: true,
347+
YamlPath: "status.phase",
348+
RegexPattern: "Active",
349+
Outcomes: []*troubleshootv1beta2.Outcome{
350+
{
351+
Pass: &troubleshootv1beta2.SingleOutcome{
352+
When: "true",
353+
Message: "pass",
354+
},
355+
},
356+
{
357+
Fail: &troubleshootv1beta2.SingleOutcome{
358+
Message: "fail",
359+
},
360+
},
361+
},
362+
},
363+
expectResult: AnalyzeResult{
364+
IsPass: true,
365+
IsWarn: false,
366+
IsFail: false,
367+
Title: "namespace-check",
368+
Message: "pass",
369+
IconKey: "kubernetes_text_analyze",
370+
IconURI: "https://troubleshoot.sh/images/analyzer-icons/text-analyze.svg",
371+
},
372+
},
373+
{
374+
name: "fail when the namespace does not match the regex",
375+
analyzer: troubleshootv1beta2.ClusterResource{
376+
AnalyzeMeta: troubleshootv1beta2.AnalyzeMeta{
377+
CheckName: "namespace-check",
378+
},
379+
Kind: "namespace",
380+
Name: "local-path-storage",
381+
ClusterScoped: true,
382+
YamlPath: "status.phase",
383+
RegexPattern: "Active",
384+
Outcomes: []*troubleshootv1beta2.Outcome{
385+
{
386+
Pass: &troubleshootv1beta2.SingleOutcome{
387+
When: "true",
388+
Message: "pass",
389+
},
390+
},
391+
{
392+
Fail: &troubleshootv1beta2.SingleOutcome{
393+
Message: "my custom fail message",
394+
},
395+
},
396+
},
397+
},
398+
expectResult: AnalyzeResult{
399+
IsPass: false,
400+
IsWarn: false,
401+
IsFail: true,
402+
Title: "namespace-check",
403+
Message: "my custom fail message",
404+
IconKey: "kubernetes_text_analyze",
405+
IconURI: "https://troubleshoot.sh/images/analyzer-icons/text-analyze.svg",
406+
},
407+
},
408+
{
409+
name: "fail when the namespace does not exist",
410+
analyzer: troubleshootv1beta2.ClusterResource{
411+
AnalyzeMeta: troubleshootv1beta2.AnalyzeMeta{
412+
CheckName: "namespace-check",
413+
},
414+
Kind: "namespace",
415+
Name: "foobar",
416+
ClusterScoped: true,
417+
YamlPath: "status.phase",
418+
RegexPattern: "Active",
419+
Outcomes: []*troubleshootv1beta2.Outcome{
420+
{
421+
Pass: &troubleshootv1beta2.SingleOutcome{
422+
When: "true",
423+
Message: "pass",
424+
},
425+
},
426+
{
427+
Fail: &troubleshootv1beta2.SingleOutcome{
428+
Message: "fail",
429+
},
430+
},
431+
},
432+
},
433+
expectResult: AnalyzeResult{
434+
IsPass: false,
435+
IsWarn: false,
436+
IsFail: true,
437+
Title: "namespace-check",
438+
Message: "namespace foobar does not exist",
439+
IconKey: "kubernetes_text_analyze",
440+
IconURI: "https://troubleshoot.sh/images/analyzer-icons/text-analyze.svg",
441+
},
442+
},
338443
}
339444
{
340445
for _, test := range tests {

0 commit comments

Comments
 (0)