From 2581918e21ec99f7bbd2fb62edf50947b1b36501 Mon Sep 17 00:00:00 2001 From: pranav-new-relic Date: Tue, 20 Aug 2024 23:52:53 +0530 Subject: [PATCH] feat(usermanagement): add data source to get current user details #2596 chore(usermanagement): minor refactor in a bid to improve reusability --- newrelic/data_source_newrelic_user_current.go | 48 +++++++++++++++++++ .../data_source_newrelic_user_current_test.go | 45 +++++++++++++++++ .../data_source_newrelic_user_management.go | 34 +++++++------ newrelic/helpers.go | 3 ++ newrelic/provider.go | 1 + website/docs/d/user.html.markdown | 2 + website/docs/d/user_current.html.markdown | 41 ++++++++++++++++ 7 files changed, 160 insertions(+), 14 deletions(-) create mode 100644 newrelic/data_source_newrelic_user_current.go create mode 100644 newrelic/data_source_newrelic_user_current_test.go create mode 100644 website/docs/d/user_current.html.markdown diff --git a/newrelic/data_source_newrelic_user_current.go b/newrelic/data_source_newrelic_user_current.go new file mode 100644 index 000000000..05f2e8094 --- /dev/null +++ b/newrelic/data_source_newrelic_user_current.go @@ -0,0 +1,48 @@ +package newrelic + +import ( + "context" + "fmt" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func dataSourceNewRelicCurrentUser() *schema.Resource { + return &schema.Resource{ + ReadContext: dataSourceNewRelicCurrentUserRead, + Schema: map[string]*schema.Schema{ + UserDataSourceUserNameAttrLabel: dataSourceNewRelicCurrentUserSchemaConstructor(UserDataSourceUserNameAttrLabel), + UserDataSourceUserEmailAttrLabel: dataSourceNewRelicCurrentUserSchemaConstructor(UserDataSourceUserEmailAttrLabel), + }, + } +} + +func dataSourceNewRelicCurrentUserSchemaConstructor(attributeLabel string) *schema.Schema { + return &schema.Schema{ + Type: schema.TypeString, + Computed: true, + Description: fmt.Sprintf("The %s of the current user, i.e. the user owning the API key the Terraform Provider has been initialised with.", attributeLabel), + } +} + +func dataSourceNewRelicCurrentUserRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + providerConfig := meta.(*ProviderConfig) + client := providerConfig.NewClient + + resp, err := client.CustomerAdministration.GetUser() + + if err != nil { + return diag.FromErr(err) + } + + if resp == nil { + return diag.FromErr(fmt.Errorf("failed to fetch current user")) + } + + d.SetId(strconv.Itoa(resp.ID)) + _ = d.Set(UserDataSourceUserNameAttrLabel, resp.Name) + _ = d.Set(UserDataSourceUserEmailAttrLabel, resp.Email) + return nil +} diff --git a/newrelic/data_source_newrelic_user_current_test.go b/newrelic/data_source_newrelic_user_current_test.go new file mode 100644 index 000000000..30b453cbd --- /dev/null +++ b/newrelic/data_source_newrelic_user_current_test.go @@ -0,0 +1,45 @@ +//go:build integration +// +build integration + +package newrelic + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +func TestAccNewRelicCurrentUserDataSource_Basic(t *testing.T) { + resource.ParallelTest(t, resource.TestCase{ + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccNewRelicCurrentUserDataSourceConfiguration(), + Check: resource.ComposeTestCheckFunc( + testAccNewRelicCheckCurrentUserDataSourceExists(t, "data.newrelic_current_user.foo"), + ), + }, + }, + }) +} + +func testAccNewRelicCheckCurrentUserDataSourceExists(t *testing.T, n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + r := s.RootModule().Resources[n] + a := r.Primary.Attributes + + if a["id"] == "" { + return fmt.Errorf("expected to get an ID of the matching user") + } + + return nil + } +} + +func testAccNewRelicCurrentUserDataSourceConfiguration() string { + return fmt.Sprintf(` +data "newrelic_current_user" "foo" { +}`) +} diff --git a/newrelic/data_source_newrelic_user_management.go b/newrelic/data_source_newrelic_user_management.go index 3972d5157..7a09b7b06 100644 --- a/newrelic/data_source_newrelic_user_management.go +++ b/newrelic/data_source_newrelic_user_management.go @@ -18,19 +18,25 @@ func dataSourceNewRelicUser() *schema.Resource { Required: true, Description: "The ID of the Authentication Domain the user being queried would belong to.", }, - "name": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "The name of the user to be queried.", - AtLeastOneOf: []string{"name", "email_id"}, + UserDataSourceUserNameAttrLabel: { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "The name of the user to be queried.", + AtLeastOneOf: []string{ + UserDataSourceUserNameAttrLabel, + UserDataSourceUserEmailAttrLabel, + }, }, - "email_id": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "The email ID of the user to be queried.", - AtLeastOneOf: []string{"name", "email_id"}, + UserDataSourceUserEmailAttrLabel: { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "The email ID of the user to be queried.", + AtLeastOneOf: []string{ + UserDataSourceUserNameAttrLabel, + UserDataSourceUserEmailAttrLabel, + }, }, "id": { Type: schema.TypeString, @@ -88,8 +94,8 @@ func dataSourceNewRelicUserRead(ctx context.Context, d *schema.ResourceData, met if authDomain.ID == authenticationDomainID { for _, u := range authDomain.Users.Users { d.SetId(u.ID) - _ = d.Set("name", u.Name) - _ = d.Set("email_id", u.Email) + _ = d.Set(UserDataSourceUserNameAttrLabel, u.Name) + _ = d.Set(UserDataSourceUserEmailAttrLabel, u.Email) return nil } } diff --git a/newrelic/helpers.go b/newrelic/helpers.go index 4229d5df8..ffb9b09af 100644 --- a/newrelic/helpers.go +++ b/newrelic/helpers.go @@ -159,3 +159,6 @@ func revertEscapedSingleQuote(name string) string { return name } + +const UserDataSourceUserNameAttrLabel = "name" +const UserDataSourceUserEmailAttrLabel = "email_id" diff --git a/newrelic/provider.go b/newrelic/provider.go index dfeecd2f6..af98cb74e 100755 --- a/newrelic/provider.go +++ b/newrelic/provider.go @@ -126,6 +126,7 @@ func Provider() *schema.Provider { "newrelic_application": dataSourceNewRelicApplication(), "newrelic_authentication_domain": dataSourceNewRelicAuthenticationDomain(), "newrelic_cloud_account": dataSourceNewRelicCloudAccount(), + "newrelic_current_user": dataSourceNewRelicCurrentUser(), "newrelic_entity": dataSourceNewRelicEntity(), "newrelic_group": dataSourceNewRelicGroup(), "newrelic_key_transaction": dataSourceNewRelicKeyTransaction(), diff --git a/website/docs/d/user.html.markdown b/website/docs/d/user.html.markdown index 9fc359773..38940f1ca 100644 --- a/website/docs/d/user.html.markdown +++ b/website/docs/d/user.html.markdown @@ -10,6 +10,8 @@ description: |- The `newrelic_user` data source helps search for a user by their name and/or email ID, and accordingly, fetch the ID of the matching user. +-> **NOTE:** If you would only like to fetch the details of the current user (the user owning the API key which has been used to initialize the New Relic Terraform Provider to run operations) and **not** search for a specific user within an authentication domain, please head over to the documentation of the [`newrelic_current_user`](https://registry.terraform.io/providers/newrelic/newrelic/latest/docs/data-sources/user_current) data source for more details and examples to do so. + ## Example Usage The below example illustrates fetching a the ID of a user (and other arguments) using the ID of the authentication domain the user belongs to, as well as a name and/or email ID, which can be used as criteria to search for a user who matches these specified parameters. diff --git a/website/docs/d/user_current.html.markdown b/website/docs/d/user_current.html.markdown new file mode 100644 index 000000000..32a9cc5ee --- /dev/null +++ b/website/docs/d/user_current.html.markdown @@ -0,0 +1,41 @@ +--- +layout: "newrelic" +page_title: "New Relic: newrelic_current_user" +sidebar_current: "docs-newrelic-datasource-current-user" +description: |- + This data source helps fetch the current user, i.e. the owning user of the credentials (API Key), using which the New Relic Terraform Provider has been initialized to perform operations. +--- + +# Data Source: newrelic_current_user + +The `newrelic_current_user` data source helps fetch the current user, i.e. the owning user of the credentials (API Key), using which the New Relic Terraform Provider has been initialized to perform operations. + +-> **NOTE:** If you would like to search for a specific user by `name` or `email_id` within a specific authentication domain, please head over to the documentation of the [`newrelic_user`](https://registry.terraform.io/providers/newrelic/newrelic/latest/docs/data-sources/user) data source for more details and examples to do so. + +## Example Usage + +The below example illustrates fetching the current user and associated metadata (the `name` and `email_id` of the current user) using the `newrelic_current_user` data source. The data source does not require any arguments to be specified. +```hcl +data "newrelic_current_user" "foo" { +} + +output "current_user_details" { + value = { + "user_id" : data.newrelic_current_user.foo.id + "user_email_id" : data.newrelic_current_user.foo.email_id + "user_name" : data.newrelic_current_user.foo.name + } +} +``` + +The ID of the current user fetched may be applied in other use cases within the New Relic Terraform Provider; for instance, this may be furnished as the value of the argument [`user_id`](https://registry.terraform.io/providers/newrelic/newrelic/latest/docs/resources/api_access_key#user_id) if required, to create `USER` API Keys with the same user's credentials using the [`newrelic_api_access_key`](https://registry.terraform.io/providers/newrelic/newrelic/latest/docs/resources/api_access_key) resource. + +## Argument Reference +This data source does not require any arguments to be specified. + +## Attributes Reference +The following attributes are exported by this data source. +* `id` - The ID of the current user. +* `name` - The name of the current user. +* `email_id` - The email ID of the current user. +