diff --git a/internal/config/client.go b/internal/config/client.go index 229abd445b..bfd819e661 100644 --- a/internal/config/client.go +++ b/internal/config/client.go @@ -6,25 +6,25 @@ import ( "fmt" "net/http" "net/url" + "strings" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/logging" - "github.com/mongodb-forks/digest" - "github.com/mongodb/terraform-provider-mongodbatlas/version" - "github.com/spf13/cast" admin20231001002 "go.mongodb.org/atlas-sdk/v20231001002/admin" "go.mongodb.org/atlas-sdk/v20231115008/admin" matlasClient "go.mongodb.org/atlas/mongodbatlas" realmAuth "go.mongodb.org/realm/auth" "go.mongodb.org/realm/realm" -) -const ( - toolName = "terraform-provider-mongodbatlas" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/logging" + "github.com/mongodb-forks/digest" + "github.com/spf13/cast" + + "github.com/mongodb/terraform-provider-mongodbatlas/version" ) -var ( - userAgent = fmt.Sprintf("%s/%s", toolName, version.ProviderVersion) +const ( + toolName = "terraform-provider-mongodbatlas" + terraformPlatformName = "Terraform" ) // MongoDBClient contains the mongodbatlas clients and configurations @@ -37,12 +37,13 @@ type MongoDBClient struct { // Config contains the configurations needed to use SDKs type Config struct { - AssumeRole *AssumeRole - ProxyPort *int - PublicKey string - PrivateKey string - BaseURL string - RealmBaseURL string + AssumeRole *AssumeRole + ProxyPort *int + PublicKey string + PrivateKey string + BaseURL string + RealmBaseURL string + TerraformVersion string } type AssumeRole struct { @@ -62,6 +63,11 @@ type SecretData struct { PrivateKey string `json:"private_key"` } +type PlatformVersion struct { + Name string + Version string +} + // NewClient func... func (c *Config) NewClient(ctx context.Context) (any, error) { // setup a transport to handle digest @@ -83,7 +89,7 @@ func (c *Config) NewClient(ctx context.Context) (any, error) { client.Transport = logging.NewTransport("MongoDB Atlas", transport) - optsAtlas := []matlasClient.ClientOpt{matlasClient.SetUserAgent(userAgent)} + optsAtlas := []matlasClient.ClientOpt{matlasClient.SetUserAgent(userAgent(c))} if c.BaseURL != "" { optsAtlas = append(optsAtlas, matlasClient.SetBaseURL(c.BaseURL)) } @@ -116,7 +122,7 @@ func (c *Config) NewClient(ctx context.Context) (any, error) { func (c *Config) newSDKV2Client(client *http.Client) (*admin.APIClient, error) { opts := []admin.ClientModifier{ admin.UseHTTPClient(client), - admin.UseUserAgent(userAgent), + admin.UseUserAgent(userAgent(c)), admin.UseBaseURL(c.BaseURL), admin.UseDebug(false)} @@ -132,7 +138,7 @@ func (c *Config) newSDKV2Client(client *http.Client) (*admin.APIClient, error) { func (c *Config) newSDK20231001002Client(client *http.Client) (*admin20231001002.APIClient, error) { opts := []admin20231001002.ClientModifier{ admin20231001002.UseHTTPClient(client), - admin20231001002.UseUserAgent(userAgent), + admin20231001002.UseUserAgent(userAgent(c)), admin20231001002.UseBaseURL(c.BaseURL), admin20231001002.UseDebug(false)} @@ -151,7 +157,8 @@ func (c *MongoDBClient) GetRealmClient(ctx context.Context) (*realm.Client, erro return nil, errors.New("please set `public_key` and `private_key` in order to use the realm client") } - optsRealm := []realm.ClientOpt{realm.SetUserAgent(userAgent)} + optsRealm := []realm.ClientOpt{realm.SetUserAgent(userAgent(c.Config))} + authConfig := realmAuth.NewConfig(nil) if c.Config.BaseURL != "" && c.Config.RealmBaseURL != "" { adminURL := c.Config.RealmBaseURL + "api/admin/v3.0/" @@ -175,3 +182,18 @@ func (c *MongoDBClient) GetRealmClient(ctx context.Context) (*realm.Client, erro return realmClient, nil } + +func userAgent(c *Config) string { + platformVersions := []PlatformVersion{ + {toolName, version.ProviderVersion}, + {terraformPlatformName, c.TerraformVersion}, + } + + var parts []string + for _, info := range platformVersions { + part := fmt.Sprintf("%s/%s", info.Name, info.Version) + parts = append(parts, part) + } + + return strings.Join(parts, " ") +} diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 0c4c9ce832..c202eb40e8 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -227,11 +227,12 @@ func (p *MongodbtlasProvider) Configure(ctx context.Context, req provider.Config } cfg := config.Config{ - PublicKey: data.PublicKey.ValueString(), - PrivateKey: data.PrivateKey.ValueString(), - BaseURL: data.BaseURL.ValueString(), - RealmBaseURL: data.RealmBaseURL.ValueString(), - ProxyPort: p.proxyPort, + PublicKey: data.PublicKey.ValueString(), + PrivateKey: data.PrivateKey.ValueString(), + BaseURL: data.BaseURL.ValueString(), + RealmBaseURL: data.RealmBaseURL.ValueString(), + TerraformVersion: req.TerraformVersion, + ProxyPort: p.proxyPort, } var assumeRoles []tfAssumeRoleModel diff --git a/internal/provider/provider_sdk2.go b/internal/provider/provider_sdk2.go index 5953c99fa4..45abb2a2ec 100644 --- a/internal/provider/provider_sdk2.go +++ b/internal/provider/provider_sdk2.go @@ -133,11 +133,13 @@ func NewSdkV2Provider(proxyPort *int) *schema.Provider { Description: "AWS Security Token Service provided session token.", }, }, - DataSourcesMap: getDataSourcesMap(), - ResourcesMap: getResourcesMap(), - ConfigureContextFunc: providerConfigure(proxyPort), + DataSourcesMap: getDataSourcesMap(), + ResourcesMap: getResourcesMap(), } addPreviewFeatures(provider) + + provider.ConfigureContextFunc = providerConfigure(provider, proxyPort) + return provider } @@ -283,7 +285,7 @@ func addPreviewFeatures(provider *schema.Provider) { } } -func providerConfigure(proxyPort *int) func(ctx context.Context, d *schema.ResourceData) (any, diag.Diagnostics) { +func providerConfigure(provider *schema.Provider, proxyPort *int) func(ctx context.Context, d *schema.ResourceData) (any, diag.Diagnostics) { return func(ctx context.Context, d *schema.ResourceData) (any, diag.Diagnostics) { diagnostics := setDefaultsAndValidations(d) if diagnostics.HasError() { @@ -291,11 +293,12 @@ func providerConfigure(proxyPort *int) func(ctx context.Context, d *schema.Resou } cfg := config.Config{ - PublicKey: d.Get("public_key").(string), - PrivateKey: d.Get("private_key").(string), - BaseURL: d.Get("base_url").(string), - RealmBaseURL: d.Get("realm_base_url").(string), - ProxyPort: proxyPort, + PublicKey: d.Get("public_key").(string), + PrivateKey: d.Get("private_key").(string), + BaseURL: d.Get("base_url").(string), + RealmBaseURL: d.Get("realm_base_url").(string), + ProxyPort: proxyPort, + TerraformVersion: provider.TerraformVersion, } assumeRoleValue, ok := d.GetOk("assume_role") diff --git a/internal/service/organization/resource_organization.go b/internal/service/organization/resource_organization.go index aa81484ed6..2b7156909e 100644 --- a/internal/service/organization/resource_organization.go +++ b/internal/service/organization/resource_organization.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/mongodb/terraform-provider-mongodbatlas/internal/common/constant" "github.com/mongodb/terraform-provider-mongodbatlas/internal/common/conversion" "github.com/mongodb/terraform-provider-mongodbatlas/internal/config" @@ -100,9 +101,10 @@ func resourceMongoDBAtlasOrganizationCreate(ctx context.Context, d *schema.Resou // update settings using new keys for this created organization because // the provider/requesting API keys are not applicable for performing updates/delete for this new organization cfg := config.Config{ - PublicKey: *organization.ApiKey.PublicKey, - PrivateKey: *organization.ApiKey.PrivateKey, - BaseURL: meta.(*config.MongoDBClient).Config.BaseURL, + PublicKey: *organization.ApiKey.PublicKey, + PrivateKey: *organization.ApiKey.PrivateKey, + BaseURL: meta.(*config.MongoDBClient).Config.BaseURL, + TerraformVersion: meta.(*config.Config).TerraformVersion, } clients, _ := cfg.NewClient(ctx) @@ -140,9 +142,10 @@ func resourceMongoDBAtlasOrganizationCreate(ctx context.Context, d *schema.Resou func resourceMongoDBAtlasOrganizationRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { // Get client connection. cfg := config.Config{ - PublicKey: d.Get("public_key").(string), - PrivateKey: d.Get("private_key").(string), - BaseURL: meta.(*config.MongoDBClient).Config.BaseURL, + PublicKey: d.Get("public_key").(string), + PrivateKey: d.Get("private_key").(string), + BaseURL: meta.(*config.MongoDBClient).Config.BaseURL, + TerraformVersion: meta.(*config.Config).TerraformVersion, } clients, _ := cfg.NewClient(ctx) @@ -189,9 +192,10 @@ func resourceMongoDBAtlasOrganizationRead(ctx context.Context, d *schema.Resourc func resourceMongoDBAtlasOrganizationUpdate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { // Get client connection. cfg := config.Config{ - PublicKey: d.Get("public_key").(string), - PrivateKey: d.Get("private_key").(string), - BaseURL: meta.(*config.MongoDBClient).Config.BaseURL, + PublicKey: d.Get("public_key").(string), + PrivateKey: d.Get("private_key").(string), + BaseURL: meta.(*config.MongoDBClient).Config.BaseURL, + TerraformVersion: meta.(*config.Config).TerraformVersion, } clients, _ := cfg.NewClient(ctx) @@ -220,9 +224,10 @@ func resourceMongoDBAtlasOrganizationUpdate(ctx context.Context, d *schema.Resou func resourceMongoDBAtlasOrganizationDelete(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics { // Get client connection. cfg := config.Config{ - PublicKey: d.Get("public_key").(string), - PrivateKey: d.Get("private_key").(string), - BaseURL: meta.(*config.MongoDBClient).Config.BaseURL, + PublicKey: d.Get("public_key").(string), + PrivateKey: d.Get("private_key").(string), + BaseURL: meta.(*config.MongoDBClient).Config.BaseURL, + TerraformVersion: meta.(*config.Config).TerraformVersion, } clients, _ := cfg.NewClient(ctx)