From 1dd23781d64d4cee31931ea0722672116bb165e9 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Mon, 19 Sep 2022 13:26:58 -0700 Subject: [PATCH] pkg/cincinnati: Set User-Agent for Cincinnati requests So that it's easier to guess at the fraction of requests that are CVOs vs. other clients. I'd like to set this for our signature requests too (vendor/github.com/openshift/library-go/pkg/verify/store/sigstore), but that would take some library-go requests first. --- pkg/cincinnati/cincinnati.go | 19 ++++++++++++++++--- pkg/cincinnati/cincinnati_test.go | 2 +- pkg/cvo/availableupdates.go | 8 +++++--- pkg/cvo/egress.go | 11 +++++++++++ 4 files changed, 33 insertions(+), 7 deletions(-) diff --git a/pkg/cincinnati/cincinnati.go b/pkg/cincinnati/cincinnati.go index da6af046e..0c866c2c4 100644 --- a/pkg/cincinnati/cincinnati.go +++ b/pkg/cincinnati/cincinnati.go @@ -32,11 +32,20 @@ const ( type Client struct { id uuid.UUID transport *http.Transport + + // userAgent configures the User-Agent header for upstream + // requests. If empty, the User-Agent header will not be + // populated. + userAgent string } // NewClient creates a new Cincinnati client with the given client identifier. -func NewClient(id uuid.UUID, transport *http.Transport) Client { - return Client{id: id, transport: transport} +func NewClient(id uuid.UUID, transport *http.Transport, userAgent string) Client { + return Client{ + id: id, + transport: transport, + userAgent: userAgent, + } } // Error is returned when are unable to get updates. @@ -92,7 +101,11 @@ func (c Client) GetUpdates(ctx context.Context, uri *url.URL, desiredArch, curre if err != nil { return current, nil, nil, &Error{Reason: "InvalidRequest", Message: err.Error(), cause: err} } - req.Header.Add("Accept", GraphMediaType) + + if c.userAgent != "" { + req.Header.Set("User-Agent", c.userAgent) + } + req.Header.Set("Accept", GraphMediaType) if c.transport != nil && c.transport.TLSClientConfig != nil { if c.transport.TLSClientConfig.ClientCAs == nil { klog.V(2).Infof("Using a root CA pool with 0 root CA subjects to request updates from %s", uri) diff --git a/pkg/cincinnati/cincinnati_test.go b/pkg/cincinnati/cincinnati_test.go index 55c97b4ae..aea8e4a94 100644 --- a/pkg/cincinnati/cincinnati_test.go +++ b/pkg/cincinnati/cincinnati_test.go @@ -745,7 +745,7 @@ func TestGetUpdates(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(handler)) defer ts.Close() - c := NewClient(clientID, nil) + c := NewClient(clientID, nil, "") uri, err := url.Parse(ts.URL) if err != nil { diff --git a/pkg/cvo/availableupdates.go b/pkg/cvo/availableupdates.go index 54f50e491..9e62dd5ba 100644 --- a/pkg/cvo/availableupdates.go +++ b/pkg/cvo/availableupdates.go @@ -67,8 +67,10 @@ func (optr *Operator) syncAvailableUpdates(ctx context.Context, config *configv1 return err } + userAgent := optr.getUserAgent() + current, updates, conditionalUpdates, condition := calculateAvailableUpdatesStatus(ctx, string(config.Spec.ClusterID), - transport, upstream, desiredArch, currentArch, channel, optr.release.Version) + transport, userAgent, upstream, desiredArch, currentArch, channel, optr.release.Version) if usedDefaultUpstream { upstream = "" @@ -211,7 +213,7 @@ func (optr *Operator) getDesiredArchitecture(update *configv1.Update) string { return "" } -func calculateAvailableUpdatesStatus(ctx context.Context, clusterID string, transport *http.Transport, upstream, desiredArch, +func calculateAvailableUpdatesStatus(ctx context.Context, clusterID string, transport *http.Transport, userAgent, upstream, desiredArch, currentArch, channel, version string) (configv1.Release, []configv1.Release, []configv1.ConditionalUpdate, configv1.ClusterOperatorStatusCondition) { @@ -269,7 +271,7 @@ func calculateAvailableUpdatesStatus(ctx context.Context, clusterID string, tran } } - current, updates, conditionalUpdates, err := cincinnati.NewClient(uuid, transport).GetUpdates(ctx, upstreamURI, desiredArch, + current, updates, conditionalUpdates, err := cincinnati.NewClient(uuid, transport, userAgent).GetUpdates(ctx, upstreamURI, desiredArch, currentArch, channel, currentVersion) if err != nil { diff --git a/pkg/cvo/egress.go b/pkg/cvo/egress.go index 57809dda1..c7d484b88 100644 --- a/pkg/cvo/egress.go +++ b/pkg/cvo/egress.go @@ -10,8 +10,19 @@ import ( "golang.org/x/net/http/httpproxy" apierrors "k8s.io/apimachinery/pkg/api/errors" + + "github.com/openshift/cluster-version-operator/pkg/version" ) +// Returns a User-Agent to be used for outgoing HTTP requests. +// +// https://www.rfc-editor.org/rfc/rfc7231#section-5.5.3 +func (optr *Operator) getUserAgent() string { + token := "ClusterVersionOperator" + productVersion := version.Version + return fmt.Sprintf("%s/%s", token, productVersion) +} + // getTransport constructs an HTTP transport configuration, including // any custom proxy configuration. func (optr *Operator) getTransport() (*http.Transport, error) {