From b17b333e298e0fadc7d42b5370c725ce2be69144 Mon Sep 17 00:00:00 2001 From: Seth Vargo Date: Wed, 4 Apr 2018 19:24:21 -0700 Subject: [PATCH] Add a common package for specifying useragent and adopt that everywhere There were 5 different formats for the Packer useragent string. This fixes that and unifies it into a helper package. I did not touch oracle's user-agent, because it looked kinda special. --- builder/azure/arm/azure_client.go | 33 ++++++++++++----------------- builder/azure/common/devicelogin.go | 6 ++---- builder/googlecompute/driver_gce.go | 11 ++++------ builder/scaleway/config.go | 3 ++- common/step_download.go | 3 ++- helper/useragent/useragent.go | 29 +++++++++++++++++++++++++ helper/useragent/useragent_test.go | 18 ++++++++++++++++ 7 files changed, 71 insertions(+), 32 deletions(-) create mode 100644 helper/useragent/useragent.go create mode 100644 helper/useragent/useragent_test.go diff --git a/builder/azure/arm/azure_client.go b/builder/azure/arm/azure_client.go index c4d8b544dfe..faa0a4766a3 100644 --- a/builder/azure/arm/azure_client.go +++ b/builder/azure/arm/azure_client.go @@ -2,7 +2,6 @@ package arm import ( "encoding/json" - "fmt" "math" "net/http" "net/url" @@ -19,17 +18,13 @@ import ( "github.com/Azure/go-autorest/autorest/adal" "github.com/Azure/go-autorest/autorest/azure" "github.com/hashicorp/packer/builder/azure/common" - "github.com/hashicorp/packer/version" + "github.com/hashicorp/packer/helper/useragent" ) const ( EnvPackerLogAzureMaxLen = "PACKER_LOG_AZURE_MAXLEN" ) -var ( - packerUserAgent = fmt.Sprintf(";packer/%s", version.FormattedVersion()) -) - type AzureClient struct { storage.BlobStorageClient resources.DeploymentsClient @@ -137,67 +132,67 @@ func NewAzureClient(subscriptionID, resourceGroupName, storageAccountName string azureClient.DeploymentsClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.DeploymentsClient.RequestInspector = withInspection(maxlen) azureClient.DeploymentsClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) - azureClient.DeploymentsClient.UserAgent += packerUserAgent + azureClient.DeploymentsClient.UserAgent = useragent.String() azureClient.DeploymentOperationsClient = resources.NewDeploymentOperationsClientWithBaseURI(cloud.ResourceManagerEndpoint, subscriptionID) azureClient.DeploymentOperationsClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.DeploymentOperationsClient.RequestInspector = withInspection(maxlen) azureClient.DeploymentOperationsClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) - azureClient.DeploymentOperationsClient.UserAgent += packerUserAgent + azureClient.DeploymentOperationsClient.UserAgent = useragent.String() azureClient.DisksClient = disk.NewDisksClientWithBaseURI(cloud.ResourceManagerEndpoint, subscriptionID) azureClient.DisksClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.DisksClient.RequestInspector = withInspection(maxlen) azureClient.DisksClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) - azureClient.DisksClient.UserAgent += packerUserAgent + azureClient.DisksClient.UserAgent = useragent.String() azureClient.GroupsClient = resources.NewGroupsClientWithBaseURI(cloud.ResourceManagerEndpoint, subscriptionID) azureClient.GroupsClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.GroupsClient.RequestInspector = withInspection(maxlen) azureClient.GroupsClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) - azureClient.GroupsClient.UserAgent += packerUserAgent + azureClient.GroupsClient.UserAgent = useragent.String() azureClient.ImagesClient = compute.NewImagesClientWithBaseURI(cloud.ResourceManagerEndpoint, subscriptionID) azureClient.ImagesClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.ImagesClient.RequestInspector = withInspection(maxlen) azureClient.ImagesClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) - azureClient.ImagesClient.UserAgent += packerUserAgent + azureClient.ImagesClient.UserAgent = useragent.String() azureClient.InterfacesClient = network.NewInterfacesClientWithBaseURI(cloud.ResourceManagerEndpoint, subscriptionID) azureClient.InterfacesClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.InterfacesClient.RequestInspector = withInspection(maxlen) azureClient.InterfacesClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) - azureClient.InterfacesClient.UserAgent += packerUserAgent + azureClient.InterfacesClient.UserAgent = useragent.String() azureClient.SubnetsClient = network.NewSubnetsClientWithBaseURI(cloud.ResourceManagerEndpoint, subscriptionID) azureClient.SubnetsClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.SubnetsClient.RequestInspector = withInspection(maxlen) azureClient.SubnetsClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) - azureClient.SubnetsClient.UserAgent += packerUserAgent + azureClient.SubnetsClient.UserAgent = useragent.String() azureClient.VirtualNetworksClient = network.NewVirtualNetworksClientWithBaseURI(cloud.ResourceManagerEndpoint, subscriptionID) azureClient.VirtualNetworksClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.VirtualNetworksClient.RequestInspector = withInspection(maxlen) azureClient.VirtualNetworksClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) - azureClient.VirtualNetworksClient.UserAgent += packerUserAgent + azureClient.VirtualNetworksClient.UserAgent = useragent.String() azureClient.PublicIPAddressesClient = network.NewPublicIPAddressesClientWithBaseURI(cloud.ResourceManagerEndpoint, subscriptionID) azureClient.PublicIPAddressesClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.PublicIPAddressesClient.RequestInspector = withInspection(maxlen) azureClient.PublicIPAddressesClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) - azureClient.PublicIPAddressesClient.UserAgent += packerUserAgent + azureClient.PublicIPAddressesClient.UserAgent = useragent.String() azureClient.VirtualMachinesClient = compute.NewVirtualMachinesClientWithBaseURI(cloud.ResourceManagerEndpoint, subscriptionID) azureClient.VirtualMachinesClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.VirtualMachinesClient.RequestInspector = withInspection(maxlen) azureClient.VirtualMachinesClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), templateCapture(azureClient), errorCapture(azureClient)) - azureClient.VirtualMachinesClient.UserAgent += packerUserAgent + azureClient.VirtualMachinesClient.UserAgent = useragent.String() azureClient.AccountsClient = armStorage.NewAccountsClientWithBaseURI(cloud.ResourceManagerEndpoint, subscriptionID) azureClient.AccountsClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.AccountsClient.RequestInspector = withInspection(maxlen) azureClient.AccountsClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) - azureClient.AccountsClient.UserAgent += packerUserAgent + azureClient.AccountsClient.UserAgent = useragent.String() keyVaultURL, err := url.Parse(cloud.KeyVaultEndpoint) if err != nil { @@ -208,7 +203,7 @@ func NewAzureClient(subscriptionID, resourceGroupName, storageAccountName string azureClient.VaultClient.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalTokenVault) azureClient.VaultClient.RequestInspector = withInspection(maxlen) azureClient.VaultClient.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) - azureClient.VaultClient.UserAgent += packerUserAgent + azureClient.VaultClient.UserAgent = useragent.String() // TODO(boumenot) - SDK still does not have a full KeyVault client. // There are two ways that KeyVault has to be accessed, and each one has their own SPN. An authenticated SPN @@ -222,7 +217,7 @@ func NewAzureClient(subscriptionID, resourceGroupName, storageAccountName string azureClient.VaultClientDelete.Authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken) azureClient.VaultClientDelete.RequestInspector = withInspection(maxlen) azureClient.VaultClientDelete.ResponseInspector = byConcatDecorators(byInspecting(maxlen), errorCapture(azureClient)) - azureClient.VaultClientDelete.UserAgent += packerUserAgent + azureClient.VaultClientDelete.UserAgent = useragent.String() // If this is a managed disk build, this should be ignored. if resourceGroupName != "" && storageAccountName != "" { diff --git a/builder/azure/common/devicelogin.go b/builder/azure/common/devicelogin.go index 904bd157f23..8cf6896007b 100644 --- a/builder/azure/common/devicelogin.go +++ b/builder/azure/common/devicelogin.go @@ -12,7 +12,7 @@ import ( "github.com/Azure/go-autorest/autorest/adal" "github.com/Azure/go-autorest/autorest/azure" "github.com/Azure/go-autorest/autorest/to" - "github.com/hashicorp/packer/version" + "github.com/hashicorp/packer/helper/useragent" "github.com/mitchellh/go-homedir" ) @@ -21,8 +21,6 @@ var ( clientIDs = map[string]string{ azure.PublicCloud.Name: "04cc58ec-51ab-4833-ac0d-ce3a7912414b", } - - userAgent = fmt.Sprintf("packer/%s", version.FormattedVersion()) ) // NOTE(ahmetalpbalkan): Azure Active Directory implements OAuth 2.0 Device Flow @@ -138,7 +136,7 @@ func tokenFromFile(say func(string), oauthCfg adal.OAuthConfig, tokenPath, clien // endpoint is polled until user gives consent, denies or the flow times out. // Returned token must be saved. func tokenFromDeviceFlow(say func(string), oauthCfg adal.OAuthConfig, clientID, resource string) (*adal.ServicePrincipalToken, error) { - cl := autorest.NewClientWithUserAgent(userAgent) + cl := autorest.NewClientWithUserAgent(useragent.String()) deviceCode, err := adal.InitiateDeviceAuth(&cl, oauthCfg, clientID, resource) if err != nil { return nil, fmt.Errorf("Failed to start device auth: %v", err) diff --git a/builder/googlecompute/driver_gce.go b/builder/googlecompute/driver_gce.go index 8adbd833e6a..91f20a58a12 100644 --- a/builder/googlecompute/driver_gce.go +++ b/builder/googlecompute/driver_gce.go @@ -10,15 +10,14 @@ import ( "fmt" "log" "net/http" - "runtime" "strings" "time" "google.golang.org/api/compute/v1" "github.com/hashicorp/packer/common" + "github.com/hashicorp/packer/helper/useragent" "github.com/hashicorp/packer/packer" - "github.com/hashicorp/packer/version" "golang.org/x/oauth2" "golang.org/x/oauth2/google" @@ -81,15 +80,13 @@ func NewDriverGCE(ui packer.Ui, p string, a *AccountFile) (Driver, error) { log.Printf("[INFO] Instantiating GCE client...") service, err := compute.New(client) - // Set UserAgent - versionString := version.FormattedVersion() - service.UserAgent = fmt.Sprintf( - "(%s %s) Packer/%s", runtime.GOOS, runtime.GOARCH, versionString) - if err != nil { return nil, err } + // Set UserAgent + service.UserAgent = useragent.String() + return &driverGCE{ projectId: p, service: service, diff --git a/builder/scaleway/config.go b/builder/scaleway/config.go index f965e1ce00e..d658e1dad34 100644 --- a/builder/scaleway/config.go +++ b/builder/scaleway/config.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/packer/common/uuid" "github.com/hashicorp/packer/helper/communicator" "github.com/hashicorp/packer/helper/config" + "github.com/hashicorp/packer/helper/useragent" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" "github.com/mitchellh/mapstructure" @@ -51,7 +52,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { return nil, nil, err } - c.UserAgent = "Packer - Scaleway builder" + c.UserAgent = useragent.String() if c.Organization == "" { c.Organization = os.Getenv("SCALEWAY_API_ACCESS_KEY") diff --git a/common/step_download.go b/common/step_download.go index 5f5bb7dfec2..03340b974d3 100644 --- a/common/step_download.go +++ b/common/step_download.go @@ -9,6 +9,7 @@ import ( "time" "github.com/hashicorp/packer/helper/multistep" + "github.com/hashicorp/packer/helper/useragent" "github.com/hashicorp/packer/packer" ) @@ -91,7 +92,7 @@ func (s *StepDownload) Run(_ context.Context, state multistep.StateBag) multiste CopyFile: false, Hash: HashForType(s.ChecksumType), Checksum: checksum, - UserAgent: "Packer", + UserAgent: useragent.String(), } downloadConfigs[i] = config diff --git a/helper/useragent/useragent.go b/helper/useragent/useragent.go new file mode 100644 index 00000000000..bd433d0cb6e --- /dev/null +++ b/helper/useragent/useragent.go @@ -0,0 +1,29 @@ +package useragent + +import ( + "fmt" + "runtime" + + "github.com/hashicorp/packer/version" +) + +var ( + // projectURL is the project URL. + projectURL = "https://www.packer.io/" + + // rt is the runtime - variable for tests. + rt = runtime.Version() + + // versionFunc is the func that returns the current version. This is a + // function to take into account the different build processes and distinguish + // between enterprise and oss builds. + versionFunc = func() string { + return version.FormattedVersion() + } +) + +// String returns the consistent user-agent string for Packer. +func String() string { + return fmt.Sprintf("Packer/%s (+%s; %s)", + versionFunc(), projectURL, rt) +} diff --git a/helper/useragent/useragent_test.go b/helper/useragent/useragent_test.go new file mode 100644 index 00000000000..b193f77eb82 --- /dev/null +++ b/helper/useragent/useragent_test.go @@ -0,0 +1,18 @@ +package useragent + +import ( + "testing" +) + +func TestUserAgent(t *testing.T) { + projectURL = "https://packer-test.com" + rt = "go5.0" + versionFunc = func() string { return "1.2.3" } + + act := String() + + exp := "Packer/1.2.3 (+https://packer-test.com; go5.0)" + if exp != act { + t.Errorf("expected %q to be %q", act, exp) + } +}