Skip to content

Commit 0610cc8

Browse files
authored
Merge pull request #2047 from Adirio/config-interface
⚠️ Decouple plugin requirements from Config interface
2 parents cfbf62d + 1586c2d commit 0610cc8

File tree

9 files changed

+173
-77
lines changed

9 files changed

+173
-77
lines changed

pkg/config/interface.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,10 @@ type Config interface {
8989

9090
// HasGroup checks if the provided group is the same as any of the tracked resources
9191
HasGroup(group string) bool
92-
// IsCRDVersionCompatible returns true if crdVersion can be added to the existing set of CRD versions.
93-
IsCRDVersionCompatible(crdVersion string) bool
94-
// IsWebhookVersionCompatible returns true if webhookVersion can be added to the existing set of Webhook versions.
95-
IsWebhookVersionCompatible(webhookVersion string) bool
92+
// ListCRDVersions returns a list of the CRD versions in use by the tracked resources
93+
ListCRDVersions() []string
94+
// ListWebhookVersions returns a list of the webhook versions in use by the tracked resources
95+
ListWebhookVersions() []string
9696

9797
/* Plugins */
9898

pkg/config/v2/config.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -222,14 +222,14 @@ func (c cfg) HasGroup(group string) bool {
222222
return false
223223
}
224224

225-
// IsCRDVersionCompatible implements config.Config
226-
func (c cfg) IsCRDVersionCompatible(crdVersion string) bool {
227-
return crdVersion == apiVersion
225+
// ListCRDVersions implements config.Config
226+
func (c cfg) ListCRDVersions() []string {
227+
return make([]string, 0)
228228
}
229229

230-
// IsWebhookVersionCompatible implements config.Config
231-
func (c cfg) IsWebhookVersionCompatible(webhookVersion string) bool {
232-
return webhookVersion == apiVersion
230+
// ListWebhookVersions implements config.Config
231+
func (c cfg) ListWebhookVersions() []string {
232+
return make([]string, 0)
233233
}
234234

235235
// DecodePluginConfig implements config.Config

pkg/config/v2/config_test.go

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -225,22 +225,12 @@ var _ = Describe("cfg", func() {
225225
Expect(c.HasGroup("other-group")).To(BeFalse())
226226
})
227227

228-
It("IsCRDVersionCompatible should return true for `v1beta1`", func() {
229-
Expect(c.IsCRDVersionCompatible("v1beta1")).To(BeTrue())
228+
It("ListCRDVersions should return an empty list", func() {
229+
Expect(c.ListCRDVersions()).To(BeEmpty())
230230
})
231231

232-
It("IsCRDVersionCompatible should return false for any other than `v1beta1`", func() {
233-
Expect(c.IsCRDVersionCompatible("v1")).To(BeFalse())
234-
Expect(c.IsCRDVersionCompatible("v2")).To(BeFalse())
235-
})
236-
237-
It("IsWebhookVersionCompatible should return true for `v1beta1`", func() {
238-
Expect(c.IsWebhookVersionCompatible("v1beta1")).To(BeTrue())
239-
})
240-
241-
It("IsWebhookVersionCompatible should return false for any other than `v1beta1`", func() {
242-
Expect(c.IsWebhookVersionCompatible("v1")).To(BeFalse())
243-
Expect(c.IsWebhookVersionCompatible("v2")).To(BeFalse())
232+
It("ListWebhookVersions should return an empty list", func() {
233+
Expect(c.ListWebhookVersions()).To(BeEmpty())
244234
})
245235
})
246236

pkg/config/v3/config.go

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -249,35 +249,40 @@ func (c cfg) HasGroup(group string) bool {
249249
return false
250250
}
251251

252-
// IsCRDVersionCompatible implements config.Config
253-
func (c cfg) IsCRDVersionCompatible(crdVersion string) bool {
254-
return c.resourceAPIVersionCompatible("crd", crdVersion)
255-
}
252+
// ListCRDVersions implements config.Config
253+
func (c cfg) ListCRDVersions() []string {
254+
// Make a map to remove duplicates
255+
versionSet := make(map[string]struct{})
256+
for _, r := range c.Resources {
257+
if r.API != nil && r.API.CRDVersion != "" {
258+
versionSet[r.API.CRDVersion] = struct{}{}
259+
}
260+
}
256261

257-
// IsWebhookVersionCompatible implements config.Config
258-
func (c cfg) IsWebhookVersionCompatible(webhookVersion string) bool {
259-
return c.resourceAPIVersionCompatible("webhook", webhookVersion)
262+
// Convert the map into a slice
263+
versions := make([]string, 0, len(versionSet))
264+
for version := range versionSet {
265+
versions = append(versions, version)
266+
}
267+
return versions
260268
}
261269

262-
func (c cfg) resourceAPIVersionCompatible(verType, version string) bool {
263-
for _, res := range c.Resources {
264-
var currVersion string
265-
switch verType {
266-
case "crd":
267-
if res.API != nil {
268-
currVersion = res.API.CRDVersion
269-
}
270-
case "webhook":
271-
if res.Webhooks != nil {
272-
currVersion = res.Webhooks.WebhookVersion
273-
}
274-
}
275-
if currVersion != "" && version != currVersion {
276-
return false
270+
// ListWebhookVersions implements config.Config
271+
func (c cfg) ListWebhookVersions() []string {
272+
// Make a map to remove duplicates
273+
versionSet := make(map[string]struct{})
274+
for _, r := range c.Resources {
275+
if r.Webhooks != nil && r.Webhooks.WebhookVersion != "" {
276+
versionSet[r.Webhooks.WebhookVersion] = struct{}{}
277277
}
278278
}
279279

280-
return true
280+
// Convert the map into a slice
281+
versions := make([]string, 0, len(versionSet))
282+
for version := range versionSet {
283+
versions = append(versions, version)
284+
}
285+
return versions
281286
}
282287

283288
// DecodePluginConfig implements config.Config

pkg/config/v3/config_test.go

Lines changed: 47 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package v3
1818

1919
import (
2020
"errors"
21+
"sort"
2122
"testing"
2223

2324
. "github.com/onsi/ginkgo"
@@ -302,42 +303,60 @@ var _ = Describe("cfg", func() {
302303
Expect(c.HasGroup("other-group")).To(BeFalse())
303304
})
304305

305-
It("IsCRDVersionCompatible should return true with no tracked resources", func() {
306-
Expect(c.IsCRDVersionCompatible("v1beta1")).To(BeTrue())
307-
Expect(c.IsCRDVersionCompatible("v1")).To(BeTrue())
306+
It("ListCRDVersions should return an empty list with no tracked resources", func() {
307+
Expect(c.ListCRDVersions()).To(BeEmpty())
308308
})
309309

310-
It("IsCRDVersionCompatible should return true only for matching CRD versions of tracked resources", func() {
311-
c.Resources = append(c.Resources, resource.Resource{
312-
GVK: resource.GVK{
313-
Group: res.Group,
314-
Version: res.Version,
315-
Kind: res.Kind,
310+
It("ListCRDVersions should return a list of tracked resources CRD versions", func() {
311+
c.Resources = append(c.Resources,
312+
resource.Resource{
313+
GVK: resource.GVK{
314+
Group: res.Group,
315+
Version: res.Version,
316+
Kind: res.Kind,
317+
},
318+
API: &resource.API{CRDVersion: "v1beta1"},
319+
},
320+
resource.Resource{
321+
GVK: resource.GVK{
322+
Group: res.Group,
323+
Version: res.Version,
324+
Kind: "OtherKind",
325+
},
326+
API: &resource.API{CRDVersion: "v1"},
316327
},
317-
API: &resource.API{CRDVersion: "v1beta1"},
318-
})
319-
Expect(c.IsCRDVersionCompatible("v1beta1")).To(BeTrue())
320-
Expect(c.IsCRDVersionCompatible("v1")).To(BeFalse())
321-
Expect(c.IsCRDVersionCompatible("v2")).To(BeFalse())
328+
)
329+
versions := c.ListCRDVersions()
330+
sort.Strings(versions) // ListCRDVersions has no order guarantee so sorting for reproducibility
331+
Expect(versions).To(Equal([]string{"v1", "v1beta1"}))
322332
})
323333

324-
It("IsWebhookVersionCompatible should return true with no tracked resources", func() {
325-
Expect(c.IsWebhookVersionCompatible("v1beta1")).To(BeTrue())
326-
Expect(c.IsWebhookVersionCompatible("v1")).To(BeTrue())
334+
It("ListWebhookVersions should return an empty list with no tracked resources", func() {
335+
Expect(c.ListWebhookVersions()).To(BeEmpty())
327336
})
328337

329-
It("IsWebhookVersionCompatible should return true only for matching webhook versions of tracked resources", func() {
330-
c.Resources = append(c.Resources, resource.Resource{
331-
GVK: resource.GVK{
332-
Group: res.Group,
333-
Version: res.Version,
334-
Kind: res.Kind,
338+
It("ListWebhookVersions should return a list of tracked resources webhook versions", func() {
339+
c.Resources = append(c.Resources,
340+
resource.Resource{
341+
GVK: resource.GVK{
342+
Group: res.Group,
343+
Version: res.Version,
344+
Kind: res.Kind,
345+
},
346+
Webhooks: &resource.Webhooks{WebhookVersion: "v1beta1"},
347+
},
348+
resource.Resource{
349+
GVK: resource.GVK{
350+
Group: res.Group,
351+
Version: res.Version,
352+
Kind: "OtherKind",
353+
},
354+
Webhooks: &resource.Webhooks{WebhookVersion: "v1"},
335355
},
336-
Webhooks: &resource.Webhooks{WebhookVersion: "v1beta1"},
337-
})
338-
Expect(c.IsWebhookVersionCompatible("v1beta1")).To(BeTrue())
339-
Expect(c.IsWebhookVersionCompatible("v1")).To(BeFalse())
340-
Expect(c.IsWebhookVersionCompatible("v2")).To(BeFalse())
356+
)
357+
versions := c.ListWebhookVersions()
358+
sort.Strings(versions) // ListWebhookVersions has no order guarantee so sorting for reproducibility
359+
Expect(versions).To(Equal([]string{"v1", "v1beta1"}))
341360
})
342361
})
343362

pkg/plugin/util/helpers.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
Copyright 2021 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package util
18+
19+
import (
20+
"sigs.k8s.io/kubebuilder/v3/pkg/config"
21+
)
22+
23+
// HasDifferentCRDVersion returns true if any other CRD version is tracked in the project configuration.
24+
func HasDifferentCRDVersion(config config.Config, crdVersion string) bool {
25+
return hasDifferentAPIVersion(config.ListCRDVersions(), crdVersion)
26+
}
27+
28+
// HasDifferentWebhookVersion returns true if any other webhook version is tracked in the project configuration.
29+
func HasDifferentWebhookVersion(config config.Config, webhookVersion string) bool {
30+
return hasDifferentAPIVersion(config.ListWebhookVersions(), webhookVersion)
31+
}
32+
33+
func hasDifferentAPIVersion(versions []string, version string) bool {
34+
return !(len(versions) == 0 || (len(versions) == 1 && versions[0] == version))
35+
}

pkg/plugin/util/helpers_test.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
Copyright 2021 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package util
18+
19+
import (
20+
"testing"
21+
22+
. "github.com/onsi/ginkgo"
23+
. "github.com/onsi/ginkgo/extensions/table"
24+
. "github.com/onsi/gomega"
25+
)
26+
27+
func TestPlugin(t *testing.T) {
28+
RegisterFailHandler(Fail)
29+
RunSpecs(t, "Plugin Util Suite")
30+
}
31+
32+
var _ = Describe("hasDifferentAPIVersion", func() {
33+
DescribeTable("should return false",
34+
func(versions []string) { Expect(hasDifferentAPIVersion(versions, "v1")).To(BeFalse()) },
35+
Entry("for an empty list of versions", []string{}),
36+
Entry("for a list of only that version", []string{"v1"}),
37+
)
38+
39+
DescribeTable("should return true",
40+
func(versions []string) { Expect(hasDifferentAPIVersion(versions, "v1")).To(BeTrue()) },
41+
Entry("for a list of only a different version", []string{"v2"}),
42+
Entry("for a list of several different versions", []string{"v2", "v3"}),
43+
Entry("for a list of several versions containing that version", []string{"v1", "v2"}),
44+
)
45+
})

pkg/plugins/golang/v3/api.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
"sigs.k8s.io/kubebuilder/v3/pkg/model"
3232
"sigs.k8s.io/kubebuilder/v3/pkg/model/resource"
3333
"sigs.k8s.io/kubebuilder/v3/pkg/plugin"
34+
pluginutil "sigs.k8s.io/kubebuilder/v3/pkg/plugin/util"
3435
goPlugin "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang"
3536
"sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v3/scaffolds"
3637
"sigs.k8s.io/kubebuilder/v3/pkg/plugins/internal/cmdutil"
@@ -189,7 +190,7 @@ func (p *createAPISubcommand) Validate() error {
189190
}
190191

191192
// Check CRDVersion against all other CRDVersions in p.config for compatibility.
192-
if !p.config.IsCRDVersionCompatible(p.resource.API.CRDVersion) {
193+
if pluginutil.HasDifferentCRDVersion(p.config, p.resource.API.CRDVersion) {
193194
return fmt.Errorf("only one CRD version can be used for all resources, cannot add %q",
194195
p.resource.API.CRDVersion)
195196
}

pkg/plugins/golang/v3/webhook.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"sigs.k8s.io/kubebuilder/v3/pkg/config"
2727
"sigs.k8s.io/kubebuilder/v3/pkg/model/resource"
2828
"sigs.k8s.io/kubebuilder/v3/pkg/plugin"
29+
pluginutil "sigs.k8s.io/kubebuilder/v3/pkg/plugin/util"
2930
goPlugin "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang"
3031
"sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v3/scaffolds"
3132
"sigs.k8s.io/kubebuilder/v3/pkg/plugins/internal/cmdutil"
@@ -121,7 +122,7 @@ func (p *createWebhookSubcommand) Validate() error {
121122
return fmt.Errorf("webhook resource already exists")
122123
}
123124

124-
if !p.config.IsWebhookVersionCompatible(p.resource.Webhooks.WebhookVersion) {
125+
if pluginutil.HasDifferentWebhookVersion(p.config, p.resource.Webhooks.WebhookVersion) {
125126
return fmt.Errorf("only one webhook version can be used for all resources, cannot add %q",
126127
p.resource.Webhooks.WebhookVersion)
127128
}

0 commit comments

Comments
 (0)