Skip to content

Commit 4dd5a17

Browse files
committed
separate k8sClient object
1 parent 7149410 commit 4dd5a17

17 files changed

+372
-313
lines changed

tests/framework/crossplane.go

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ func ValidateNginxFieldExists(conf *Payload, expFieldCfg ExpectedNginxField, opt
6969
return nil
7070
}
7171

72-
if expFieldCfg.Upstream != "" && fieldExistsInUpstream(expFieldCfg, *directive) {
72+
if expFieldCfg.Upstream != "" && fieldExistsInUpstream(expFieldCfg, *directive, opts...) {
7373
return nil
7474
}
7575
}
@@ -100,12 +100,19 @@ func fieldExistsInServer(
100100
func fieldExistsInUpstream(
101101
expFieldCfg ExpectedNginxField,
102102
directive Directive,
103+
opts ...Option,
103104
) bool {
104-
GinkgoWriter.Printf(
105-
"Checking upstream for directive %q with value %q\n",
106-
expFieldCfg.Directive,
107-
expFieldCfg.Value,
108-
)
105+
options := &Options{logEnabled: true}
106+
for _, opt := range opts {
107+
opt(options)
108+
}
109+
if options.logEnabled {
110+
GinkgoWriter.Printf(
111+
"Checking upstream for directive %q with value %q\n",
112+
expFieldCfg.Directive,
113+
expFieldCfg.Value,
114+
)
115+
}
109116
if directive.Directive == "upstream" && directive.Args[0] == expFieldCfg.Upstream {
110117
for _, directive := range directive.Block {
111118
if expFieldCfg.fieldFound(directive) {

tests/framework/k8s_client.go

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
package framework
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
. "github.com/onsi/ginkgo/v2"
8+
apierrors "k8s.io/apimachinery/pkg/api/errors"
9+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10+
"k8s.io/apimachinery/pkg/labels"
11+
"k8s.io/client-go/rest"
12+
"sigs.k8s.io/controller-runtime/pkg/client"
13+
)
14+
15+
// K8sClient wraps controller-runtime Client to add logging and custom behavior.
16+
type K8sClient struct {
17+
inner client.Client
18+
}
19+
20+
func (c *K8sClient) InNamespace(namespace string) client.ListOption {
21+
return client.InNamespace(namespace)
22+
}
23+
24+
// HasLabels returns a ListOption that filters for objects which have
25+
// all of the given label keys (regardless of value).
26+
func (c *K8sClient) HasLabels(keys ...string) client.ListOption {
27+
reqs := make([]metav1.LabelSelectorRequirement, 0, len(keys))
28+
for _, k := range keys {
29+
reqs = append(reqs, metav1.LabelSelectorRequirement{
30+
Key: k,
31+
Operator: metav1.LabelSelectorOpExists,
32+
})
33+
}
34+
sel := &metav1.LabelSelector{MatchExpressions: reqs}
35+
ls, err := metav1.LabelSelectorAsSelector(sel)
36+
if err != nil {
37+
GinkgoWriter.Printf("error constructing label selector: %v\n", err)
38+
// fallback to a selector that matches nothing
39+
return client.MatchingLabelsSelector{Selector: labels.Nothing()}
40+
}
41+
return client.MatchingLabelsSelector{Selector: ls}
42+
}
43+
44+
// MatchingLabels is just a passthrough to the real helper.
45+
func (c *K8sClient) MatchingLabels(m map[string]string) client.ListOption {
46+
return client.MatchingLabels(m)
47+
}
48+
49+
func logOptions(opts ...Option) *Options {
50+
options := &Options{logEnabled: true}
51+
for _, opt := range opts {
52+
opt(options)
53+
}
54+
55+
return options
56+
}
57+
58+
// NewK8sClient returns a new wrapped Kubernetes client.
59+
func NewK8sClient(config *rest.Config, options client.Options) (K8sClient, error) {
60+
inner, err := client.New(config, options)
61+
if err != nil {
62+
clientErr := fmt.Errorf("error creating k8s client: %w", err)
63+
GinkgoWriter.Printf("%v\n", clientErr)
64+
65+
return K8sClient{}, err
66+
}
67+
68+
return K8sClient{inner: inner}, nil
69+
}
70+
71+
// Get retrieves a resource by key, logging errors if enabled.
72+
func (c *K8sClient) Get(
73+
ctx context.Context,
74+
key client.ObjectKey,
75+
obj client.Object,
76+
opts ...Option,
77+
) error {
78+
options := logOptions(opts...)
79+
err := c.inner.Get(ctx, key, obj)
80+
if err != nil {
81+
if apierrors.IsNotFound(err) {
82+
if options.logEnabled {
83+
GinkgoWriter.Printf("Not found k8s resource %q error: %v\n", obj.GetName(), err)
84+
}
85+
return err
86+
}
87+
getErr := fmt.Errorf("error getting k8s resource %q: %w", obj.GetName(), err)
88+
if options.logEnabled {
89+
GinkgoWriter.Printf("%v\n", getErr)
90+
}
91+
92+
return getErr
93+
}
94+
95+
return nil
96+
}
97+
98+
// Create adds a new resource, returning an error on failure.
99+
func (c *K8sClient) Create(
100+
ctx context.Context,
101+
obj client.Object,
102+
) error {
103+
err := c.inner.Create(ctx, obj)
104+
if err != nil {
105+
createErr := fmt.Errorf("error creating k8s resource %q: %w", obj.GetName(), err)
106+
GinkgoWriter.Printf("%v\n", createErr)
107+
108+
return createErr
109+
}
110+
return nil
111+
}
112+
113+
// Delete removes a resource, returning an error on failure.
114+
func (c *K8sClient) Delete(
115+
ctx context.Context,
116+
obj client.Object,
117+
deleteOpts []client.DeleteOption,
118+
opts ...Option,
119+
) error {
120+
options := logOptions(opts...)
121+
var dOpts []client.DeleteOption
122+
for _, do := range deleteOpts {
123+
if do != nil {
124+
dOpts = append(dOpts, do)
125+
}
126+
}
127+
128+
err := c.inner.Delete(ctx, obj, dOpts...)
129+
if err != nil {
130+
deleteErr := fmt.Errorf("error deleting k8s resource %q: %w", obj.GetName(), err)
131+
if options.logEnabled {
132+
GinkgoWriter.Printf("%v\n", deleteErr)
133+
}
134+
135+
return deleteErr
136+
}
137+
return nil
138+
}
139+
140+
// Update modifies a resource.
141+
func (c *K8sClient) Update(
142+
ctx context.Context,
143+
obj client.Object,
144+
updateOpts []client.UpdateOption,
145+
opts ...Option,
146+
) error {
147+
options := logOptions(opts...)
148+
var uOpts []client.UpdateOption
149+
for _, uo := range updateOpts {
150+
if uo != nil {
151+
uOpts = append(uOpts, uo)
152+
}
153+
}
154+
155+
if err := c.inner.Update(ctx, obj, uOpts...); err != nil {
156+
updateDeploymentErr := fmt.Errorf("error updating Deployment: %w", err)
157+
if options.logEnabled {
158+
GinkgoWriter.Printf(
159+
"ERROR occurred during updating Deployment in namespace %q with name %q, error: %s\n",
160+
obj.GetNamespace(),
161+
obj.GetName(),
162+
updateDeploymentErr,
163+
)
164+
}
165+
166+
return updateDeploymentErr
167+
}
168+
169+
return nil
170+
}
171+
172+
// List retrieves a list of resources, returning an error on failure.
173+
func (c *K8sClient) List(
174+
ctx context.Context,
175+
list client.ObjectList,
176+
listOpts ...client.ListOption,
177+
) error {
178+
var opts []client.ListOption
179+
for _, o := range listOpts {
180+
if o != nil {
181+
opts = append(opts, o)
182+
}
183+
}
184+
185+
err := c.inner.List(ctx, list, opts...)
186+
if err != nil {
187+
listErr := fmt.Errorf("error listing k8s resources: %w", err)
188+
GinkgoWriter.Printf("%v\n", listErr)
189+
190+
return listErr
191+
}
192+
return nil
193+
}

tests/framework/ngf.go

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import (
1414
apiext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
1515
apierrors "k8s.io/apimachinery/pkg/api/errors"
1616
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
17-
"sigs.k8s.io/controller-runtime/pkg/client"
1817
)
1918

2019
const (
@@ -101,7 +100,9 @@ func InstallNGF(cfg InstallationConfig, extraArgs ...string) ([]byte, error) {
101100
}
102101

103102
// CreateLicenseSecret creates the NGINX Plus JWT secret.
104-
func CreateLicenseSecret(k8sClient client.Client, namespace, filename string) error {
103+
func CreateLicenseSecret(k8sClient K8sClient, namespace, filename string) error {
104+
GinkgoWriter.Printf("Creating NGINX Plus license secret in namespace %q from file %q\n", namespace, filename)
105+
105106
conf, err := os.ReadFile(filename)
106107
if err != nil {
107108
readFileErr := fmt.Errorf("error reading file %q: %w", filename, err)
@@ -120,10 +121,7 @@ func CreateLicenseSecret(k8sClient client.Client, namespace, filename string) er
120121
}
121122

122123
if err := k8sClient.Create(ctx, ns); err != nil && !apierrors.IsAlreadyExists(err) {
123-
createNSErr := fmt.Errorf("error creating namespace: %w", err)
124-
GinkgoWriter.Printf("%v\n", createNSErr)
125-
126-
return createNSErr
124+
return fmt.Errorf("error creating namespace: %w", err)
127125
}
128126

129127
secret := &core.Secret{
@@ -183,7 +181,7 @@ func UpgradeNGF(cfg InstallationConfig, extraArgs ...string) ([]byte, error) {
183181
}
184182

185183
// UninstallNGF uninstalls NGF.
186-
func UninstallNGF(cfg InstallationConfig, k8sClient client.Client) ([]byte, error) {
184+
func UninstallNGF(cfg InstallationConfig, k8sClient K8sClient) ([]byte, error) {
187185
args := []string{
188186
"uninstall", cfg.ReleaseName, "--namespace", cfg.Namespace,
189187
}
@@ -197,20 +195,20 @@ func UninstallNGF(cfg InstallationConfig, k8sClient client.Client) ([]byte, erro
197195
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
198196
defer cancel()
199197

200-
err = k8sClient.Delete(ctx, &core.Namespace{ObjectMeta: metav1.ObjectMeta{Name: cfg.Namespace}})
198+
err = k8sClient.Delete(ctx, &core.Namespace{ObjectMeta: metav1.ObjectMeta{Name: cfg.Namespace}}, nil)
201199
if err != nil && !apierrors.IsNotFound(err) {
202200
return nil, err
203201
}
204202

205203
var crList apiext.CustomResourceDefinitionList
206-
if err := k8sClient.List(ctx, &crList); err != nil {
204+
if err := k8sClient.List(ctx, &crList, nil); err != nil {
207205
return nil, err
208206
}
209207

210208
for _, cr := range crList.Items {
211209
if strings.Contains(cr.Spec.Group, "gateway.nginx.org") {
212210
cr := cr
213-
if err := k8sClient.Delete(ctx, &cr); err != nil && !apierrors.IsNotFound(err) {
211+
if err := k8sClient.Delete(ctx, &cr, nil); err != nil && !apierrors.IsNotFound(err) {
214212
return nil, err
215213
}
216214
}

tests/framework/request.go

Lines changed: 0 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import (
1313
"time"
1414

1515
. "github.com/onsi/ginkgo/v2"
16-
k8sClient "sigs.k8s.io/controller-runtime/pkg/client"
1716
)
1817

1918
// Get sends a GET request to the specified url.
@@ -149,49 +148,3 @@ func makeRequest(
149148

150149
return resp, nil
151150
}
152-
153-
func K8sGet(
154-
ctx context.Context,
155-
client k8sClient.Client,
156-
key k8sClient.ObjectKey,
157-
obj k8sClient.Object,
158-
opts ...Option,
159-
) error {
160-
options := &Options{logEnabled: true}
161-
for _, opt := range opts {
162-
opt(options)
163-
}
164-
165-
err := client.Get(ctx, key, obj)
166-
if err != nil && options.logEnabled {
167-
return fmt.Errorf("ERROR getting resource %q: %w", obj.GetName(), err)
168-
}
169-
170-
return err
171-
}
172-
173-
func K8sList(
174-
ctx context.Context,
175-
client k8sClient.Client,
176-
list k8sClient.ObjectList,
177-
) error {
178-
err := client.List(ctx, list)
179-
if err != nil {
180-
return fmt.Errorf("ERROR listing resource %q: %w", list.GetObjectKind(), err)
181-
}
182-
183-
return err
184-
}
185-
186-
func K8sCreate(
187-
ctx context.Context,
188-
client k8sClient.Client,
189-
obj k8sClient.Object,
190-
) error {
191-
err := client.Create(ctx, obj)
192-
if err != nil {
193-
return fmt.Errorf("ERROR creating resource %q: %w", obj.GetName(), err)
194-
}
195-
196-
return err
197-
}

0 commit comments

Comments
 (0)