Skip to content

Commit bc78e55

Browse files
authored
fix: use client.Client for deleting objects in cleaner (#1373)
1 parent bb306d2 commit bc78e55

File tree

3 files changed

+21
-224
lines changed

3 files changed

+21
-224
lines changed

pkg/clusters/cleanup.go

Lines changed: 12 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,15 @@ package clusters
33
import (
44
"context"
55
"fmt"
6-
"strings"
76
"sync"
87

98
"golang.org/x/sync/errgroup"
109
corev1 "k8s.io/api/core/v1"
1110
"k8s.io/apimachinery/pkg/api/errors"
1211
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
13-
"k8s.io/apimachinery/pkg/runtime/schema"
12+
"k8s.io/apimachinery/pkg/runtime"
1413
"k8s.io/apimachinery/pkg/watch"
15-
"k8s.io/client-go/dynamic"
1614
"sigs.k8s.io/controller-runtime/pkg/client"
17-
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
18-
gatewayv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
19-
gatewayv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"
2015
)
2116

2217
// -----------------------------------------------------------------------------
@@ -27,15 +22,19 @@ import (
2722
// used during integration tests to clean up test resources.
2823
type Cleaner struct {
2924
cluster Cluster
25+
scheme *runtime.Scheme
3026
objects []client.Object
3127
manifests []string
3228
namespaces []*corev1.Namespace
3329
lock sync.RWMutex
3430
}
3531

3632
// NewCleaner provides a new initialized *Cleaner object.
37-
func NewCleaner(cluster Cluster) *Cleaner {
38-
return &Cleaner{cluster: cluster}
33+
func NewCleaner(cluster Cluster, scheme *runtime.Scheme) *Cleaner {
34+
return &Cleaner{
35+
cluster: cluster,
36+
scheme: scheme,
37+
}
3938
}
4039

4140
// -----------------------------------------------------------------------------
@@ -63,15 +62,16 @@ func (c *Cleaner) AddNamespace(namespace *corev1.Namespace) {
6362
func (c *Cleaner) Cleanup(ctx context.Context) error {
6463
c.lock.RLock()
6564
defer c.lock.RUnlock()
66-
dyn, err := dynamic.NewForConfig(c.cluster.Config())
65+
66+
cl, err := client.New(c.cluster.Config(), client.Options{
67+
Scheme: c.scheme,
68+
})
6769
if err != nil {
6870
return err
6971
}
7072

7173
for _, obj := range c.objects {
72-
resource := resourceDeleterForObj(dyn, obj)
73-
74-
if err := resource.Delete(ctx, obj.GetName(), metav1.DeleteOptions{}); err != nil {
74+
if err := cl.Delete(ctx, obj); err != nil {
7575
if !errors.IsNotFound(err) {
7676
return err
7777
}
@@ -128,100 +128,6 @@ func (c *Cleaner) Cleanup(ctx context.Context) error {
128128
return g.Wait()
129129
}
130130

131-
// fixupObjKinds takes a client.Object and checks if it's of one of the gateway
132-
// API types and if so then it adjusts that object's Kind and APIVersion.
133-
// This possibly might also need other types to be included but those are enough
134-
// for our needs for now especially since that will help cleaning up non-namespaced
135-
// GatewayClasses which are not cleaned up on namespace removal also done in
136-
// Cleanup().
137-
//
138-
// The reason we need this is that when decoding to go structs APIVersion and Kind
139-
// are dropper because the type info is inherent in the object.
140-
// Decoding to unstructured objects (like the dynamic client does) preserves that
141-
// information.
142-
// There should be a better way of doing this.
143-
//
144-
// Possibly related:
145-
// - https://github.com/kubernetes/kubernetes/issues/3030
146-
// - https://github.com/kubernetes/kubernetes/issues/80609
147-
func fixupObjKinds(obj client.Object) client.Object {
148-
// If Kind and APIVersion are set then we're good.
149-
if obj.GetObjectKind().GroupVersionKind().Kind != "" && obj.GetResourceVersion() != "" {
150-
return obj
151-
}
152-
153-
// Otherwise try to fix that up by performing type assertions and filling
154-
// those 2 fields accordingly.
155-
switch o := obj.(type) {
156-
case *gatewayv1.GatewayClass:
157-
o.Kind = "GatewayClass"
158-
o.APIVersion = gatewayv1.GroupVersion.String()
159-
return o
160-
case *gatewayv1.Gateway:
161-
o.Kind = "Gateway"
162-
o.APIVersion = gatewayv1.GroupVersion.String()
163-
return o
164-
case *gatewayv1.HTTPRoute:
165-
o.Kind = "HTTPRoute"
166-
o.APIVersion = gatewayv1.GroupVersion.String()
167-
return o
168-
169-
case *gatewayv1alpha2.TCPRoute:
170-
o.Kind = "TCPRoute"
171-
o.APIVersion = gatewayv1alpha2.GroupVersion.String()
172-
return o
173-
case *gatewayv1alpha2.UDPRoute:
174-
o.Kind = "UDPRoute"
175-
o.APIVersion = gatewayv1alpha2.GroupVersion.String()
176-
return o
177-
case *gatewayv1alpha2.TLSRoute:
178-
o.Kind = "TLSRoute"
179-
o.APIVersion = gatewayv1alpha2.GroupVersion.String()
180-
return o
181-
case *gatewayv1beta1.ReferenceGrant:
182-
o.Kind = "ReferenceGrant"
183-
o.APIVersion = gatewayv1beta1.GroupVersion.String()
184-
return o
185-
186-
default:
187-
return obj
188-
}
189-
}
190-
191-
type deleter interface {
192-
Delete(ctx context.Context, name string, options metav1.DeleteOptions, subresources ...string) error
193-
}
194-
195-
func resourceDeleterForObj(dyn *dynamic.DynamicClient, obj client.Object) deleter {
196-
obj = fixupObjKinds(obj)
197-
198-
var (
199-
namespace = obj.GetNamespace()
200-
kind = obj.GetObjectKind()
201-
gvk = kind.GroupVersionKind()
202-
)
203-
204-
var gvr schema.GroupVersionResource
205-
switch gvk.Kind {
206-
// GatewayClass is a special case because gatewayclass + "s" is not a plural
207-
// of gatewayclass.
208-
case "GatewayClass":
209-
gvr = schema.GroupVersionResource{
210-
Group: gvk.Group,
211-
Version: gvk.Version,
212-
Resource: "gatewayclasses",
213-
}
214-
default:
215-
res := strings.ToLower(gvk.Kind) + "s"
216-
gvr = gvk.GroupVersion().WithResource(res)
217-
}
218-
219-
if namespace == "" {
220-
return dyn.Resource(gvr)
221-
}
222-
return dyn.Resource(gvr).Namespace(namespace)
223-
}
224-
225131
// DumpDiagnostics dumps diagnostics from the underlying cluster.
226132
//
227133
// Deprecated: Users should use Cluster.DumpDiagnostics().

pkg/clusters/cleanup_test.go

Lines changed: 3 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -4,128 +4,14 @@ import (
44
"fmt"
55
"testing"
66

7-
"github.com/stretchr/testify/assert"
87
corev1 "k8s.io/api/core/v1"
98
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10-
"k8s.io/apimachinery/pkg/runtime/schema"
11-
"sigs.k8s.io/controller-runtime/pkg/client"
12-
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
13-
gatewayv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
14-
gatewayv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"
9+
"k8s.io/apimachinery/pkg/runtime"
1510
)
1611

17-
func TestFixupObjKinds(t *testing.T) {
18-
testcases := []struct {
19-
name string
20-
obj client.Object
21-
expected schema.GroupVersionKind
22-
}{
23-
{
24-
name: "gatewayclass",
25-
obj: &gatewayv1.GatewayClass{
26-
ObjectMeta: metav1.ObjectMeta{
27-
Name: "my-gatewayclass",
28-
},
29-
},
30-
expected: schema.GroupVersionKind{
31-
Group: "gateway.networking.k8s.io",
32-
Version: "v1",
33-
Kind: "GatewayClass",
34-
},
35-
},
36-
{
37-
name: "gateway",
38-
obj: &gatewayv1.Gateway{
39-
ObjectMeta: metav1.ObjectMeta{
40-
Name: "my-gateway",
41-
},
42-
},
43-
expected: schema.GroupVersionKind{
44-
Group: "gateway.networking.k8s.io",
45-
Version: "v1",
46-
Kind: "Gateway",
47-
},
48-
},
49-
{
50-
name: "httproute",
51-
obj: &gatewayv1.HTTPRoute{
52-
ObjectMeta: metav1.ObjectMeta{
53-
Name: "my-httproute",
54-
},
55-
},
56-
expected: schema.GroupVersionKind{
57-
Group: "gateway.networking.k8s.io",
58-
Version: "v1",
59-
Kind: "HTTPRoute",
60-
},
61-
},
62-
{
63-
name: "tcproute",
64-
obj: &gatewayv1alpha2.TCPRoute{
65-
ObjectMeta: metav1.ObjectMeta{
66-
Name: "my-tcproute",
67-
},
68-
},
69-
expected: schema.GroupVersionKind{
70-
Group: "gateway.networking.k8s.io",
71-
Version: "v1alpha2",
72-
Kind: "TCPRoute",
73-
},
74-
},
75-
{
76-
name: "udproute",
77-
obj: &gatewayv1alpha2.UDPRoute{
78-
ObjectMeta: metav1.ObjectMeta{
79-
Name: "my-udproute",
80-
},
81-
},
82-
expected: schema.GroupVersionKind{
83-
Group: "gateway.networking.k8s.io",
84-
Version: "v1alpha2",
85-
Kind: "UDPRoute",
86-
},
87-
},
88-
{
89-
name: "tlsroute",
90-
obj: &gatewayv1alpha2.TLSRoute{
91-
ObjectMeta: metav1.ObjectMeta{
92-
Name: "my-tlsroute",
93-
},
94-
},
95-
expected: schema.GroupVersionKind{
96-
Group: "gateway.networking.k8s.io",
97-
Version: "v1alpha2",
98-
Kind: "TLSRoute",
99-
},
100-
},
101-
{
102-
name: "referencegrant",
103-
obj: &gatewayv1beta1.ReferenceGrant{
104-
ObjectMeta: metav1.ObjectMeta{
105-
Name: "my-referencegrant",
106-
},
107-
},
108-
expected: schema.GroupVersionKind{
109-
Group: "gateway.networking.k8s.io",
110-
Version: "v1beta1",
111-
Kind: "ReferenceGrant",
112-
},
113-
},
114-
}
115-
116-
for _, tc := range testcases {
117-
t.Run(tc.name, func(t *testing.T) {
118-
obj := fixupObjKinds(tc.obj)
119-
assert.Equal(t, tc.expected.Group, obj.GetObjectKind().GroupVersionKind().Group)
120-
assert.Equal(t, tc.expected.Kind, obj.GetObjectKind().GroupVersionKind().Kind)
121-
assert.Equal(t, tc.expected.Version, obj.GetObjectKind().GroupVersionKind().Version)
122-
})
123-
}
124-
}
125-
12612
func TestCleanerCanBeUsedConcurrently(*testing.T) {
127-
cleaner := NewCleaner(nil)
128-
for i := 0; i < 100; i++ {
13+
cleaner := NewCleaner(nil, runtime.NewScheme())
14+
for i := range 100 {
12915
go func() {
13016
cleaner.Add(&corev1.Pod{})
13117
}()

test/integration/cleaner_test.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import (
1111
corev1 "k8s.io/api/core/v1"
1212
"k8s.io/apimachinery/pkg/api/errors"
1313
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
14+
"k8s.io/apimachinery/pkg/runtime"
15+
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
1416
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
1517
gatewayclient "sigs.k8s.io/gateway-api/pkg/client/clientset/versioned"
1618

@@ -32,7 +34,10 @@ func TestCleaner(t *testing.T) {
3234
require.NoError(t, err)
3335

3436
cluster := env.Cluster()
35-
cleaner := clusters.NewCleaner(cluster)
37+
scheme := runtime.NewScheme()
38+
require.NoError(t, clientgoscheme.AddToScheme(scheme))
39+
require.NoError(t, gatewayv1.Install(scheme))
40+
cleaner := clusters.NewCleaner(cluster, scheme)
3641
t.Cleanup(func() { cleaner.Cleanup(context.Background()) })
3742

3843
t.Log("waiting for the test environment to be ready")

0 commit comments

Comments
 (0)