1 package kpoll
2
3 import (
4 "context"
5 "fmt"
6
7 "gotest.tools/v3/poll"
8 "sigs.k8s.io/controller-runtime/pkg/client"
9
10 "edge-infra.dev/pkg/k8s/object"
11 "edge-infra.dev/pkg/k8s/runtime/inventory"
12 "edge-infra.dev/pkg/k8s/unstructured"
13 )
14
15
16
17
18
19 func Exists(ctx context.Context, c client.Client, objs ...client.Object) poll.Check {
20 return func(_ poll.LogT) poll.Result {
21 return objsExist(ctx, c, objs...)
22 }
23 }
24
25 func objExists(ctx context.Context, c client.Client, o client.Object) poll.Result {
26 err := c.Get(ctx, client.ObjectKeyFromObject(o), o)
27 switch {
28 case err == nil && !object.IsDeleted(o, err):
29 return poll.Success()
30 case object.IsDeleted(o, err):
31 return poll.Continue("%s not present", object.FmtObject(o))
32 case err != nil:
33
34 return poll.Error(err)
35 default:
36 return poll.Error(fmt.Errorf(
37 "unknown state: object should either be deleted or present",
38 ))
39 }
40 }
41
42 func objsExist(ctx context.Context, c client.Client, objs ...client.Object) poll.Result {
43 if len(objs) == 1 {
44 return objExists(ctx, c, objs[0])
45 }
46
47 results := make([]poll.Result, len(objs))
48 for i, o := range objs {
49 results[i] = objExists(ctx, c, o)
50 }
51
52 return JoinResults(results...)
53 }
54
55
56
57
58
59 func Deleted(ctx context.Context, c client.Client, objs ...client.Object) poll.Check {
60 return func(_ poll.LogT) poll.Result {
61 return objsDeleted(ctx, c, objs...)
62 }
63 }
64
65 func objDeleted(ctx context.Context, c client.Client, o client.Object) poll.Result {
66 err := c.Get(ctx, client.ObjectKeyFromObject(o), o)
67 switch {
68 case object.IsDeleted(o, err):
69 return poll.Success()
70 case !object.IsDeleted(o, err):
71 return poll.Continue("%s present", object.FmtObject(o))
72 case err != nil:
73
74 return poll.Error(err)
75 default:
76 return poll.Error(fmt.Errorf(
77 "unknown state: object should either be deleted or present",
78 ))
79 }
80 }
81
82 func objsDeleted(ctx context.Context, c client.Client, objs ...client.Object) poll.Result {
83 if len(objs) == 1 {
84 return objDeleted(ctx, c, objs[0])
85 }
86
87 results := make([]poll.Result, len(objs))
88 for i, o := range objs {
89 results[i] = objDeleted(ctx, c, o)
90 }
91
92 return JoinResults(results...)
93 }
94
95
96
97
98
99
100 func InventoryPruned(ctx context.Context, c client.Client, curr, old *inventory.ResourceInventory) poll.Check {
101 return func(_ poll.LogT) poll.Result {
102 diff, err := old.Diff(curr)
103 if err != nil {
104 return poll.Error(err)
105 }
106 if len(diff) == 0 {
107 return poll.Error(fmt.Errorf(
108 "can't validate pruning with identical inventories: no diff produced",
109 ))
110 }
111
112 return objsDeleted(ctx, c, unstructured.ToClientObjArray(diff...)...)
113 }
114 }
115
116
117
118
119
120
121
122 func InventoryExists(ctx context.Context, c client.Client, exp *inventory.ResourceInventory) poll.Check {
123 return func(_ poll.LogT) poll.Result {
124 objs, err := exp.ListObjects()
125 if err != nil {
126 return poll.Error(err)
127 }
128 return objsExist(ctx, c, unstructured.ToClientObjArray(objs...)...)
129 }
130 }
131
View as plain text