diff --git a/pkg/issuer/acme/acme.go b/pkg/issuer/acme/acme.go index 74333c71b..3bd854c56 100644 --- a/pkg/issuer/acme/acme.go +++ b/pkg/issuer/acme/acme.go @@ -4,6 +4,7 @@ import ( "context" "fmt" nethttp "net/http" + "time" "github.com/golang/glog" "golang.org/x/crypto/acme" @@ -94,22 +95,6 @@ func New(issuer v1alpha1.GenericIssuer, }, nil } -// uaRoundTripper implements the http.RoundTripper interface and adds a User-Agent -// header. Note that this is a stopgap until upstream `crypto/acme` adds a -// facility for setting User-Agent. - -type uaRoundTripper struct { - nethttp.RoundTripper - ua string -} - -var acmeUserAgent = "jetstack-cert-manager/" + util.AppVersion - -func (uat uaRoundTripper) RoundTrip(req *nethttp.Request) (*nethttp.Response, error) { - req.Header.Add("User-Agent", acmeUserAgent) - return uat.RoundTripper.RoundTrip(req) -} - func (a *Acme) acmeClient() (*acme.Client, error) { secretName, secretKey := a.acmeAccountPrivateKeyMeta() glog.V(4).Infof("getting private key (%s->%s) for acme issuer %s/%s", secretName, secretKey, a.issuerResourcesNamespace, a.issuer.GetObjectMeta().Name) @@ -122,9 +107,10 @@ func (a *Acme) acmeClient() (*acme.Client, error) { Key: accountPrivKey, DirectoryURL: a.issuer.GetSpec().ACME.Server, HTTPClient: &nethttp.Client{ - Transport: uaRoundTripper{ - RoundTripper: nethttp.DefaultTransport, - }, + // Stopgap user-agent roundtripper until the upstream 'crypto/acme' + // provides a better method for setting user-agent. + Transport: util.UserAgentRoundTripper(nethttp.DefaultTransport), + Timeout: 30 * time.Second, }, } return cl, nil diff --git a/pkg/issuer/acme/dns/akamai/akamai.go b/pkg/issuer/acme/dns/akamai/akamai.go index 84d3f8d97..52a37c71b 100644 --- a/pkg/issuer/acme/dns/akamai/akamai.go +++ b/pkg/issuer/acme/dns/akamai/akamai.go @@ -15,6 +15,7 @@ import ( "github.com/golang/glog" "github.com/jetstack/cert-manager/pkg/issuer/acme/dns/util" + pkgutil "github.com/jetstack/cert-manager/pkg/util" "github.com/pkg/errors" ) @@ -165,6 +166,8 @@ func (a *DNSProvider) saveZoneData(domain string, data zoneData) error { } func (a *DNSProvider) makeRequest(req *http.Request) ([]byte, error) { + req.Header.Set("User-Agent", pkgutil.CertManagerUserAgent) + if err := a.auth.SignRequest(req); err != nil { return nil, errors.Wrap(err, "failed to sign HTTP request") } diff --git a/pkg/issuer/acme/dns/cloudflare/cloudflare.go b/pkg/issuer/acme/dns/cloudflare/cloudflare.go index 96408a287..f9151a1c0 100644 --- a/pkg/issuer/acme/dns/cloudflare/cloudflare.go +++ b/pkg/issuer/acme/dns/cloudflare/cloudflare.go @@ -12,6 +12,7 @@ import ( "time" "github.com/jetstack/cert-manager/pkg/issuer/acme/dns/util" + pkgutil "github.com/jetstack/cert-manager/pkg/util" ) // CloudFlareAPIURL represents the API endpoint to call. @@ -180,9 +181,11 @@ func (c *DNSProvider) makeRequest(method, uri string, body io.Reader) (json.RawM req.Header.Set("X-Auth-Email", c.authEmail) req.Header.Set("X-Auth-Key", c.authKey) - //req.Header.Set("User-Agent", userAgent()) + req.Header.Set("User-Agent", pkgutil.CertManagerUserAgent) - client := http.Client{Timeout: 30 * time.Second} + client := http.Client{ + Timeout: 30 * time.Second, + } resp, err := client.Do(req) if err != nil { return nil, fmt.Errorf("Error querying Cloudflare API -> %v", err) diff --git a/pkg/issuer/acme/dns/route53/route53.go b/pkg/issuer/acme/dns/route53/route53.go index 5ac972017..c57fc91aa 100644 --- a/pkg/issuer/acme/dns/route53/route53.go +++ b/pkg/issuer/acme/dns/route53/route53.go @@ -17,6 +17,7 @@ import ( "github.com/golang/glog" "github.com/jetstack/cert-manager/pkg/issuer/acme/dns/util" + pkgutil "github.com/jetstack/cert-manager/pkg/util" ) const ( @@ -93,6 +94,7 @@ func NewDNSProvider(accessKeyID, secretAccessKey, hostedZoneID, region string, a if err != nil { return nil, fmt.Errorf("unable to create aws session: %s", err) } + sess.Handlers.Build.PushBack(request.WithAppendUserAgent(pkgutil.CertManagerUserAgent)) client := route53.New(sess, config) return &DNSProvider{ diff --git a/pkg/util/kube/config.go b/pkg/util/kube/config.go index 31ae6de17..f323bf316 100644 --- a/pkg/util/kube/config.go +++ b/pkg/util/kube/config.go @@ -3,6 +3,7 @@ package kube import ( "fmt" + "github.com/jetstack/cert-manager/pkg/util" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" ) @@ -26,11 +27,11 @@ func KubeConfig(apiServerHost string) (*rest.Config, error) { } cfg, err = clientcmd.NewDefaultClientConfig(*apiCfg, &clientcmd.ConfigOverrides{}).ClientConfig() - if err != nil { return nil, fmt.Errorf("error loading cluster client config: %s", err.Error()) } } + cfg.UserAgent = util.CertManagerUserAgent return cfg, nil } diff --git a/pkg/util/useragent_roundtripper.go b/pkg/util/useragent_roundtripper.go new file mode 100644 index 000000000..96c96199f --- /dev/null +++ b/pkg/util/useragent_roundtripper.go @@ -0,0 +1,28 @@ +package util + +import ( + "net/http" +) + +// CertManagerUserAgent is the user agent that http clients in this codebase should use +var CertManagerUserAgent = "jetstack-cert-manager/" + version() + +// UserAgentRoundTripper implements the http.RoundTripper interface and adds a User-Agent +// header. +type userAgentRoundTripper struct { + inner http.RoundTripper +} + +// UserAgentRoundTripper returns a RoundTripper that functions identically to +// the provided 'inner' round tripper, other than also setting a user agent. +func UserAgentRoundTripper(inner http.RoundTripper) http.RoundTripper { + return userAgentRoundTripper{ + inner: inner, + } +} + +// RoundTrip implements http.RoundTripper +func (u userAgentRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { + req.Header.Add("User-Agent", CertManagerUserAgent) + return u.inner.RoundTrip(req) +} diff --git a/pkg/util/version.go b/pkg/util/version.go index 3ab75874b..c516efc06 100644 --- a/pkg/util/version.go +++ b/pkg/util/version.go @@ -1,7 +1,20 @@ package util +import "fmt" + var ( AppGitState = "" AppGitCommit = "" AppVersion = "canary" ) + +func version() string { + v := AppVersion + if AppGitCommit != "" { + v += "-" + AppGitCommit + } + if AppGitState != "" { + v += fmt.Sprintf(" (%v)", AppGitState) + } + return v +}