Skip to content

Commit 9f5afec

Browse files
authored
Merge pull request #2918 from sbueringer/pr-add-skip-name-validation
🌱 Add SkipNameValidation option
2 parents 96e8152 + 89bebe3 commit 9f5afec

File tree

3 files changed

+70
-4
lines changed

3 files changed

+70
-4
lines changed

pkg/config/controller.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ import "time"
2020

2121
// Controller contains configuration options for a controller.
2222
type Controller struct {
23+
// SkipNameValidation allows skipping the name validation that ensures that every controller name is unique.
24+
// Unique controller names are important to get unique metrics and logs for a controller.
25+
// Can be overwritten for a controller via the SkipNameValidation setting on the controller.
26+
// Defaults to false if SkipNameValidation setting on controller and Manager are unset.
27+
SkipNameValidation *bool
28+
2329
// GroupKindConcurrency is a map from a Kind to the number of concurrent reconciliation
2430
// allowed for that controller.
2531
//
@@ -40,8 +46,8 @@ type Controller struct {
4046
CacheSyncTimeout time.Duration
4147

4248
// RecoverPanic indicates whether the panic caused by reconcile should be recovered.
43-
// Defaults to the Controller.RecoverPanic setting from the Manager if unset.
44-
// Defaults to true if Controller.RecoverPanic setting from the Manager is also unset.
49+
// Can be overwritten for a controller via the RecoverPanic setting on the controller.
50+
// Defaults to true if RecoverPanic setting on controller and Manager are unset.
4551
RecoverPanic *bool
4652

4753
// NeedLeaderElection indicates whether the controller needs to use leader election.

pkg/controller/controller.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ type Options = TypedOptions[reconcile.Request]
3636

3737
// TypedOptions are the arguments for creating a new Controller.
3838
type TypedOptions[request comparable] struct {
39+
// SkipNameValidation allows skipping the name validation that ensures that every controller name is unique.
40+
// Unique controller names are important to get unique metrics and logs for a controller.
41+
// Defaults to the Controller.SkipNameValidation setting from the Manager if unset.
42+
// Defaults to false if Controller.SkipNameValidation setting from the Manager is also unset.
43+
SkipNameValidation *bool
44+
3945
// MaxConcurrentReconciles is the maximum number of concurrent Reconciles which can be run. Defaults to 1.
4046
MaxConcurrentReconciles int
4147

@@ -140,8 +146,14 @@ func NewTypedUnmanaged[request comparable](name string, mgr manager.Manager, opt
140146
return nil, fmt.Errorf("must specify Name for Controller")
141147
}
142148

143-
if err := checkName(name); err != nil {
144-
return nil, err
149+
if options.SkipNameValidation == nil {
150+
options.SkipNameValidation = mgr.GetControllerOptions().SkipNameValidation
151+
}
152+
153+
if options.SkipNameValidation == nil || !*options.SkipNameValidation {
154+
if err := checkName(name); err != nil {
155+
return nil, err
156+
}
145157
}
146158

147159
if options.LogConstructor == nil {

pkg/controller/controller_test.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,54 @@ var _ = Describe("controller.Controller", func() {
7474
Expect(c2).To(BeNil())
7575
})
7676

77+
It("should return an error if two controllers are registered with the same name and SkipNameValidation is set to false on the manager", func() {
78+
m, err := manager.New(cfg, manager.Options{
79+
Controller: config.Controller{
80+
SkipNameValidation: ptr.To(false),
81+
},
82+
})
83+
Expect(err).NotTo(HaveOccurred())
84+
85+
c1, err := controller.New("c4", m, controller.Options{Reconciler: rec})
86+
Expect(err).NotTo(HaveOccurred())
87+
Expect(c1).ToNot(BeNil())
88+
89+
c2, err := controller.New("c4", m, controller.Options{Reconciler: rec})
90+
Expect(err).To(HaveOccurred())
91+
Expect(err.Error()).To(ContainSubstring("controller with name c4 already exists"))
92+
Expect(c2).To(BeNil())
93+
})
94+
95+
It("should not return an error if two controllers are registered with the same name and SkipNameValidation is set on the manager", func() {
96+
m, err := manager.New(cfg, manager.Options{
97+
Controller: config.Controller{
98+
SkipNameValidation: ptr.To(true),
99+
},
100+
})
101+
Expect(err).NotTo(HaveOccurred())
102+
103+
c1, err := controller.New("c5", m, controller.Options{Reconciler: rec})
104+
Expect(err).NotTo(HaveOccurred())
105+
Expect(c1).ToNot(BeNil())
106+
107+
c2, err := controller.New("c5", m, controller.Options{Reconciler: rec})
108+
Expect(err).NotTo(HaveOccurred())
109+
Expect(c2).ToNot(BeNil())
110+
})
111+
112+
It("should not return an error if two controllers are registered with the same name and SkipNameValidation is set on the controller", func() {
113+
m, err := manager.New(cfg, manager.Options{})
114+
Expect(err).NotTo(HaveOccurred())
115+
116+
c1, err := controller.New("c6", m, controller.Options{Reconciler: rec})
117+
Expect(err).NotTo(HaveOccurred())
118+
Expect(c1).ToNot(BeNil())
119+
120+
c2, err := controller.New("c6", m, controller.Options{Reconciler: rec, SkipNameValidation: ptr.To(true)})
121+
Expect(err).NotTo(HaveOccurred())
122+
Expect(c2).ToNot(BeNil())
123+
})
124+
77125
It("should not return an error if two controllers are registered with different names", func() {
78126
m, err := manager.New(cfg, manager.Options{})
79127
Expect(err).NotTo(HaveOccurred())

0 commit comments

Comments
 (0)