@@ -2,6 +2,7 @@ package probe
2
2
3
3
import (
4
4
"context"
5
+ k8serrors "k8s.io/apimachinery/pkg/api/errors"
5
6
"strings"
6
7
"time"
7
8
@@ -42,7 +43,7 @@ func prepareK8sProbe(probe v1alpha1.ProbeAttributes, resultDetails *types.Result
42
43
// triggerK8sProbe run the k8s probe command
43
44
func triggerK8sProbe (probe v1alpha1.ProbeAttributes , clients clients.ClientSets , resultDetails * types.ResultDetails ) error {
44
45
45
- inputs := probe .K8sProbeInputs
46
+ inputs := & probe .K8sProbeInputs
46
47
47
48
// It parse the templated command and return normal string
48
49
// if command doesn't have template, it will return the same command
@@ -56,6 +57,19 @@ func triggerK8sProbe(probe v1alpha1.ProbeAttributes, clients clients.ClientSets,
56
57
return err
57
58
}
58
59
60
+ inputs .ResourceNames , err = parseCommand (inputs .ResourceNames , resultDetails )
61
+ if err != nil {
62
+ return err
63
+ }
64
+
65
+ parsedResourceNames := []string {}
66
+ if inputs .ResourceNames != "" {
67
+ parsedResourceNames = strings .Split (inputs .ResourceNames , "," )
68
+ for i := range parsedResourceNames {
69
+ parsedResourceNames [i ] = strings .TrimSpace (parsedResourceNames [i ])
70
+ }
71
+ }
72
+
59
73
// it will retry for some retry count, in each iterations of try it contains following things
60
74
// it contains a timeout per iteration of retry. if the timeout expires without success then it will go to next try
61
75
// for a timeout, it will run the command, if it fails wait for the iterval and again execute the command until timeout expires
@@ -77,32 +91,19 @@ func triggerK8sProbe(probe v1alpha1.ProbeAttributes, clients clients.ClientSets,
77
91
return err
78
92
}
79
93
case "delete" :
80
- if err = deleteResource (probe , gvr , clients ); err != nil {
94
+ if err = deleteResource (probe , gvr , parsedResourceNames , clients ); err != nil {
81
95
log .Errorf ("the %v k8s probe has Failed, err: %v" , probe .Name , err )
82
96
return err
83
97
}
84
98
case "present" :
85
- resourceList , err := clients .DynamicClient .Resource (gvr ).Namespace (inputs .Namespace ).List (context .Background (), v1.ListOptions {
86
- FieldSelector : inputs .FieldSelector ,
87
- LabelSelector : inputs .LabelSelector ,
88
- })
89
- if err != nil {
99
+ if err = resourcesPresent (probe , gvr , parsedResourceNames , clients ); err != nil {
90
100
log .Errorf ("the %v k8s probe has Failed, err: %v" , probe .Name , err )
91
- return errors .Errorf ("unable to list the resources with matching selector, err: %v" , err )
92
- } else if len (resourceList .Items ) == 0 {
93
- return errors .Errorf ("no resource found with provided selectors" )
101
+ return err
94
102
}
95
103
case "absent" :
96
- resourceList , err := clients .DynamicClient .Resource (gvr ).Namespace (inputs .Namespace ).List (context .Background (), v1.ListOptions {
97
- FieldSelector : inputs .FieldSelector ,
98
- LabelSelector : inputs .LabelSelector ,
99
- })
100
- if err != nil {
101
- return errors .Errorf ("unable to list the resources with matching selector, err: %v" , err )
102
- }
103
- if len (resourceList .Items ) != 0 {
104
+ if err = resourcesAbsent (probe , gvr , parsedResourceNames , clients ); err != nil {
104
105
log .Errorf ("the %v k8s probe has Failed, err: %v" , probe .Name , err )
105
- return errors . Errorf ( "resource is not deleted yet due to, err: %v" , err )
106
+ return err
106
107
}
107
108
default :
108
109
return errors .Errorf ("operation type '%s' not supported in the k8s probe" , inputs .Operation )
@@ -165,21 +166,99 @@ func createResource(probe v1alpha1.ProbeAttributes, gvr schema.GroupVersionResou
165
166
}
166
167
167
168
// deleteResource deletes the resource with matching label & field selector
168
- func deleteResource (probe v1alpha1.ProbeAttributes , gvr schema.GroupVersionResource , clients clients.ClientSets ) error {
169
- resourceList , err := clients .DynamicClient .Resource (gvr ).Namespace (probe .K8sProbeInputs .Namespace ).List (context .Background (), v1.ListOptions {
170
- FieldSelector : probe .K8sProbeInputs .FieldSelector ,
171
- LabelSelector : probe .K8sProbeInputs .LabelSelector ,
172
- })
173
- if err != nil {
174
- return errors .Errorf ("unable to list the resources with matching selector, err: %v" , err )
175
- } else if len (resourceList .Items ) == 0 {
176
- return errors .Errorf ("no resource found with provided selectors" )
169
+ func deleteResource (probe v1alpha1.ProbeAttributes , gvr schema.GroupVersionResource , parsedResourceNames []string , clients clients.ClientSets ) error {
170
+ // resource name has higher priority
171
+ if len (parsedResourceNames ) > 0 {
172
+ // check if all resources are available
173
+ if err := areResourcesWithNamePresent (probe , gvr , parsedResourceNames , clients ); err != nil {
174
+ return err
175
+ }
176
+ // delete resources
177
+ for _ , res := range parsedResourceNames {
178
+ if err = clients .DynamicClient .Resource (gvr ).Namespace (probe .K8sProbeInputs .Namespace ).Delete (context .Background (), res , v1.DeleteOptions {}); err != nil {
179
+ return err
180
+ }
181
+ }
182
+ } else {
183
+ resourceList , err := clients .DynamicClient .Resource (gvr ).Namespace (probe .K8sProbeInputs .Namespace ).List (context .Background (), v1.ListOptions {
184
+ FieldSelector : probe .K8sProbeInputs .FieldSelector ,
185
+ LabelSelector : probe .K8sProbeInputs .LabelSelector ,
186
+ })
187
+ if err != nil {
188
+ return errors .Errorf ("unable to list the resources with matching selector, err: %v" , err )
189
+ } else if len (resourceList .Items ) == 0 {
190
+ return errors .Errorf ("no resource found with provided selectors" )
191
+ }
192
+
193
+ for index := range resourceList .Items {
194
+ if err = clients .DynamicClient .Resource (gvr ).Namespace (probe .K8sProbeInputs .Namespace ).Delete (context .Background (), resourceList .Items [index ].GetName (), v1.DeleteOptions {}); err != nil {
195
+ return err
196
+ }
197
+ }
177
198
}
199
+ return nil
200
+ }
178
201
179
- for index := range resourceList .Items {
180
- if err = clients .DynamicClient .Resource (gvr ).Namespace (probe .K8sProbeInputs .Namespace ).Delete (context .Background (), resourceList .Items [index ].GetName (), v1.DeleteOptions {}); err != nil {
202
+ func resourcesPresent (probe v1alpha1.ProbeAttributes , gvr schema.GroupVersionResource , parsedResourceNames []string , clients clients.ClientSets ) error {
203
+ // resource name has higher priority
204
+ if len (parsedResourceNames ) > 0 {
205
+ // check if all resources are available
206
+ if err := areResourcesWithNamePresent (probe , gvr , parsedResourceNames , clients ); err != nil {
181
207
return err
182
208
}
209
+ } else {
210
+ resourceList , err := clients .DynamicClient .Resource (gvr ).Namespace (probe .K8sProbeInputs .Namespace ).List (context .Background (), v1.ListOptions {
211
+ FieldSelector : probe .K8sProbeInputs .FieldSelector ,
212
+ LabelSelector : probe .K8sProbeInputs .LabelSelector ,
213
+ })
214
+ if err != nil {
215
+ log .Errorf ("the %v k8s probe has Failed, err: %v" , probe .Name , err )
216
+ return errors .Errorf ("unable to list the resources with matching selector, err: %v" , err )
217
+ } else if len (resourceList .Items ) == 0 {
218
+ return errors .Errorf ("no resource found with provided selectors" )
219
+ }
220
+ }
221
+ return nil
222
+ }
223
+
224
+ func areResourcesWithNamePresent (probe v1alpha1.ProbeAttributes , gvr schema.GroupVersionResource , parsedResourceNames []string , clients clients.ClientSets ) error {
225
+ for _ , res := range parsedResourceNames {
226
+ resource , err := clients .DynamicClient .Resource (gvr ).Namespace (probe .K8sProbeInputs .Namespace ).Get (context .Background (), res , v1.GetOptions {})
227
+ if err != nil {
228
+ return errors .Errorf ("unable to get the resources with name %v, err: %v" , res , err )
229
+ } else if resource == nil {
230
+ return errors .Errorf ("unable to get the resources with name %v" , res )
231
+ }
232
+ }
233
+ return nil
234
+ }
235
+
236
+ func resourcesAbsent (probe v1alpha1.ProbeAttributes , gvr schema.GroupVersionResource , parsedResourceNames []string , clients clients.ClientSets ) error {
237
+ // resource name has higher priority
238
+ if len (parsedResourceNames ) > 0 {
239
+ // check if all resources are absent
240
+ for _ , res := range parsedResourceNames {
241
+ resource , err := clients .DynamicClient .Resource (gvr ).Namespace (probe .K8sProbeInputs .Namespace ).Get (context .Background (), res , v1.GetOptions {})
242
+ if err != nil {
243
+ // ignore not found error, that is the expected outcome
244
+ if ! k8serrors .IsNotFound (err ) {
245
+ return errors .Errorf ("unable to get the resources with name %v from k8s, err: %v" , res , err )
246
+ }
247
+ } else if resource != nil {
248
+ return errors .Errorf ("resource '%v' still exists but is expected to be absent" , res )
249
+ }
250
+ }
251
+ } else {
252
+ resourceList , err := clients .DynamicClient .Resource (gvr ).Namespace (probe .K8sProbeInputs .Namespace ).List (context .Background (), v1.ListOptions {
253
+ FieldSelector : probe .K8sProbeInputs .FieldSelector ,
254
+ LabelSelector : probe .K8sProbeInputs .LabelSelector ,
255
+ })
256
+ if err != nil {
257
+ return errors .Errorf ("unable to list the resources with matching selector, err: %v" , err )
258
+ }
259
+ if len (resourceList .Items ) != 0 {
260
+ return errors .Errorf ("resource with provided selectors still exists, found %v resources with matching selectors" , len (resourceList .Items ))
261
+ }
183
262
}
184
263
return nil
185
264
}
0 commit comments