Skip to content

Commit

Permalink
tailscale: fix default User-Agent header to include terraform version (
Browse files Browse the repository at this point in the history
…#361)

The `schema.Provider.UserAgent` helper function was previously being
called at a point in the plugin lifecycle before the `TerraformVersion`
for the provider was set by Terraform Core. This was resulting in the
Terraform version information being missing from the User-Agent header.
The call to `schema.Provider.UserAgent` has now been moved into the
`providerConfigure` func as this is called later in the configure
lifecycle where the Terraform version is properly set.

Fixes tailscale/corp#19630

Signed-off-by: Mario Minardi <mario@tailscale.com>
  • Loading branch information
mpminardi committed May 1, 2024
1 parent 79561c1 commit 380cf9a
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 18 deletions.
2 changes: 1 addition & 1 deletion .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ builds:
flags:
- -trimpath
ldflags:
- "-s -w -X main.version={{.Version}} -X main.commit={{.Commit}}"
- "-s -w -X github.com/tailscale/terraform-provider-tailscale/tailscale.providerVersion={{.Version}} -X main.commit={{.Commit}}"
goos:
- freebsd
- windows
Expand Down
16 changes: 1 addition & 15 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,10 @@ import (
"github.com/tailscale/terraform-provider-tailscale/tailscale"
)

// version is filled by goreleaser at build time.
var version = "dev"

func main() {
plugin.Serve(&plugin.ServeOpts{
ProviderFunc: func() *schema.Provider {
return tailscale.Provider(addUserAgent)
return tailscale.Provider()
},
})
}

// addUserAgent adds a `user_agent` configuration key to the provider with a
// default value based on provider version.
func addUserAgent(p *schema.Provider) {
p.Schema["user_agent"] = &schema.Schema{
Type: schema.TypeString,
Default: p.UserAgent("terraform-provider-tailscale", version),
Optional: true,
Description: "User-Agent header for API requests.",
}
}
18 changes: 16 additions & 2 deletions tailscale/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ import (
"github.com/tailscale/tailscale-client-go/tailscale"
)

// providerVersion is filled by goreleaser at build time.
var providerVersion = "dev"

type ProviderOption func(p *schema.Provider)

// Provider returns the *schema.Provider instance that implements the terraform provider.
Expand All @@ -24,7 +27,6 @@ func Provider(options ...ProviderOption) *schema.Provider {
oauthClientSecretEnvVars := []string{"TAILSCALE_OAUTH_CLIENT_SECRET", "OAUTH_CLIENT_SECRET"}

provider := &schema.Provider{
ConfigureContextFunc: providerConfigure,
Schema: map[string]*schema.Schema{
"api_key": {
Type: schema.TypeString,
Expand Down Expand Up @@ -64,6 +66,11 @@ func Provider(options ...ProviderOption) *schema.Provider {
Optional: true,
Description: "The base URL of the Tailscale API. Defaults to https://api.tailscale.com. Can be set via the TAILSCALE_BASE_URL environment variable.",
},
"user_agent": {
Type: schema.TypeString,
Optional: true,
Description: "User-Agent header for API requests.",
},
},
ResourcesMap: map[string]*schema.Resource{
"tailscale_acl": resourceACL(),
Expand All @@ -85,14 +92,18 @@ func Provider(options ...ProviderOption) *schema.Provider {
},
}

provider.ConfigureContextFunc = func(ctx context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) {
return providerConfigure(ctx, provider, d)
}

for _, option := range options {
option(provider)
}

return provider
}

func providerConfigure(_ context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) {
func providerConfigure(_ context.Context, provider *schema.Provider, d *schema.ResourceData) (interface{}, diag.Diagnostics) {
baseURL := d.Get("base_url").(string)
tailnet := d.Get("tailnet").(string)
if tailnet == "" {
Expand All @@ -114,6 +125,9 @@ func providerConfigure(_ context.Context, d *schema.ResourceData) (interface{},
}

userAgent := d.Get("user_agent").(string)
if userAgent == "" {
userAgent = provider.UserAgent("terraform-provider-tailscale", providerVersion)
}

if oauthClientID != "" && oauthClientSecret != "" {
var oauthScopes []string
Expand Down

0 comments on commit 380cf9a

Please sign in to comment.