Skip to content

Commit 22dee73

Browse files
committed
controllercmd,certsyncpod: add UserAgentSuffix to distinguish clients
Add WithUserAgentSuffix to ControllerBuilder and expose UserAgentSuffix on ControllerCommandConfig so that static pod sidecar controllers using localhost can be identified by the kube-apiserver's pre-readiness request filter. The cert-syncer, which does not use controllercmd, sets its suffix directly in Complete().
1 parent d8750ed commit 22dee73

4 files changed

Lines changed: 72 additions & 4 deletions

File tree

pkg/controller/controllercmd/builder.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ package controllercmd
33
import (
44
"context"
55
"fmt"
6-
"k8s.io/utils/clock"
76
"os"
87
"strings"
98
"sync"
109
"time"
1110

11+
"k8s.io/utils/clock"
12+
1213
configv1 "github.com/openshift/api/config/v1"
1314
operatorv1alpha1 "github.com/openshift/api/operator/v1alpha1"
1415
"github.com/openshift/library-go/pkg/authorization/hardcodedauthorizer"
@@ -106,6 +107,10 @@ type ControllerBuilder struct {
106107
enableHTTP2 bool
107108

108109
skipInClusterAuthLookup bool
110+
111+
// userAgentSuffix is appended to the default UserAgent string on REST
112+
// clients created by this builder. Set via WithUserAgentSuffix.
113+
userAgentSuffix string
109114
}
110115

111116
type TopologyDetector interface {
@@ -251,6 +256,13 @@ func (b *ControllerBuilder) WithEventRecorderOptions(options record.CorrelatorOp
251256
return b
252257
}
253258

259+
// WithUserAgentSuffix appends the given suffix to the default UserAgent on REST
260+
// clients created by this builder, making requests distinguishable by component.
261+
func (b *ControllerBuilder) WithUserAgentSuffix(suffix string) *ControllerBuilder {
262+
b.userAgentSuffix = suffix
263+
return b
264+
}
265+
254266
// WithComponentOwnerReference overrides controller reference resolution for event recording
255267
func (b *ControllerBuilder) WithComponentOwnerReference(reference *corev1.ObjectReference) *ControllerBuilder {
256268
b.componentOwnerReference = reference
@@ -264,6 +276,10 @@ func (b *ControllerBuilder) Run(ctx context.Context, config *unstructured.Unstru
264276
return err
265277
}
266278

279+
if len(b.userAgentSuffix) > 0 {
280+
rest.AddUserAgent(clientConfig, b.userAgentSuffix)
281+
}
282+
267283
if b.fileObserver != nil {
268284
go b.fileObserver.Run(ctx.Done())
269285
}

pkg/controller/controllercmd/builder_test.go

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@ import (
88
"testing"
99
"time"
1010

11+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
12+
"k8s.io/client-go/rest"
13+
"k8s.io/utils/clock"
14+
1115
configv1 "github.com/openshift/api/config/v1"
1216
"github.com/openshift/library-go/pkg/operator/events/eventstesting"
13-
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1417
)
1518

1619
func TestControllerBuilder_getOnStartedLeadingFunc(t *testing.T) {
@@ -247,3 +250,44 @@ func TestInfraStatusTopologyLeaderElection(t *testing.T) {
247250
})
248251
}
249252
}
253+
254+
func TestWithUserAgentSuffix(t *testing.T) {
255+
tests := []struct {
256+
name string
257+
withUserAgentSuffix string
258+
wantSuffix string
259+
}{
260+
{
261+
name: "suffix is appended to default user agent",
262+
withUserAgentSuffix: "cert-recovery",
263+
wantSuffix: "/cert-recovery",
264+
},
265+
{
266+
name: "no suffix leaves user agent empty for default handling",
267+
withUserAgentSuffix: "",
268+
},
269+
}
270+
271+
for _, tt := range tests {
272+
t.Run(tt.name, func(t *testing.T) {
273+
b := NewController("test-component", nil, clock.RealClock{}).
274+
WithUserAgentSuffix(tt.withUserAgentSuffix)
275+
276+
cfg := &rest.Config{}
277+
if len(b.userAgentSuffix) > 0 {
278+
rest.AddUserAgent(cfg, b.userAgentSuffix)
279+
}
280+
281+
if tt.withUserAgentSuffix == "" {
282+
if cfg.UserAgent != "" {
283+
t.Errorf("expected empty UserAgent, got %q", cfg.UserAgent)
284+
}
285+
return
286+
}
287+
288+
if !strings.HasSuffix(cfg.UserAgent, tt.wantSuffix) {
289+
t.Errorf("expected UserAgent to end with %q, but UserAgent is %q", tt.wantSuffix, cfg.UserAgent)
290+
}
291+
})
292+
}
293+
}

pkg/controller/controllercmd/cmd.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ type ControllerCommandConfig struct {
8282
ComponentOwnerReference *corev1.ObjectReference
8383
healthChecks []healthz.HealthChecker
8484
eventRecorderOptions record.CorrelatorOptions
85+
86+
// UserAgentSuffix is appended to the default UserAgent on REST clients,
87+
// making requests from this component distinguishable.
88+
UserAgentSuffix string
8589
}
8690

8791
// NewControllerConfig returns a new ControllerCommandConfig which can be used to wire up all the boiler plate of a controller
@@ -341,7 +345,8 @@ func (c *ControllerCommandConfig) StartController(ctx context.Context) error {
341345
WithHealthChecks(c.healthChecks...).
342346
WithEventRecorderOptions(c.eventRecorderOptions).
343347
WithRestartOnChange(exitOnChangeReactorCh, startingFileContent, observedFiles...).
344-
WithComponentOwnerReference(c.ComponentOwnerReference)
348+
WithComponentOwnerReference(c.ComponentOwnerReference).
349+
WithUserAgentSuffix(c.UserAgentSuffix)
345350

346351
if !c.DisableServing {
347352
builder = builder.WithServer(config.ServingInfo, config.Authentication, config.Authorization)

pkg/operator/staticpod/certsyncpod/certsync_cmd.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@ package certsyncpod
22

33
import (
44
"context"
5-
"k8s.io/utils/clock"
65
"os"
76
"time"
87

8+
"k8s.io/utils/clock"
9+
910
"github.com/spf13/cobra"
1011
"k8s.io/klog/v2"
1112

@@ -119,6 +120,8 @@ func (o *CertSyncControllerOptions) Complete() error {
119120
return err
120121
}
121122

123+
rest.AddUserAgent(kubeConfig, "cert-syncer")
124+
122125
if len(o.Namespace) == 0 && len(os.Getenv("POD_NAMESPACE")) > 0 {
123126
o.Namespace = os.Getenv("POD_NAMESPACE")
124127
}

0 commit comments

Comments
 (0)