From 5900a6351ecd7f08fbcd774129f27d58556b7306 Mon Sep 17 00:00:00 2001 From: Alex Wilcox Date: Thu, 8 Dec 2022 16:31:40 +0000 Subject: [PATCH 1/2] Add basic roles data source --- docs/data-sources/directory_roles.md | 49 ++++++++ .../directory_roles_data_source.go | 109 ++++++++++++++++++ .../directory_roles_data_source_test.go | 39 +++++++ .../services/directoryroles/registration.go | 4 +- 4 files changed, 200 insertions(+), 1 deletion(-) create mode 100644 docs/data-sources/directory_roles.md create mode 100644 internal/services/directoryroles/directory_roles_data_source.go create mode 100644 internal/services/directoryroles/directory_roles_data_source_test.go diff --git a/docs/data-sources/directory_roles.md b/docs/data-sources/directory_roles.md new file mode 100644 index 0000000000..2ce4c59a2b --- /dev/null +++ b/docs/data-sources/directory_roles.md @@ -0,0 +1,49 @@ +--- +subcategory: "Directory Roles" +--- + +# Resource: azuread_directory_roles + +Use this data source to access information about activated directory roles within Azure Active Directory. + +## API Permissions + +The following API permissions are required in order to use this resource. + +When authenticated with a service principal, this resource requires one of the following application roles: `RoleManagement.Read.Directory` or `Directory.Read.All` + +When authenticated with a user principal, this data source does not require any additional roles. + +## Example Usage + +```terraform +data "azuread_directory_roles" "current" {} + +output "roles" { + value = data.azuread_directory_roles.current.object_ids +} +``` + +## Argument Reference + +This data source does not have any arguments. + +## Attributes Reference + +The following attributes are exported: + +* `object_ids` - The object IDs of the roles. +* `roles` - A list of users. Each `role` object provides the attributes documented below. + +--- + +`role` object exports the following: + +* `display_name` - The display name of the directory role. +* `template_id` - The template ID of the directory role. +* `description` - The description of the directory role. +* `object_id` - The object ID of the directory role. + +## Import + +This resource does not support importing. diff --git a/internal/services/directoryroles/directory_roles_data_source.go b/internal/services/directoryroles/directory_roles_data_source.go new file mode 100644 index 0000000000..8e228657f1 --- /dev/null +++ b/internal/services/directoryroles/directory_roles_data_source.go @@ -0,0 +1,109 @@ +package directoryroles + +import ( + "context" + "crypto/sha1" + "encoding/base64" + "errors" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/hashicorp/terraform-provider-azuread/internal/clients" + "github.com/hashicorp/terraform-provider-azuread/internal/tf" +) + +func directoryRoleDataSource() *schema.Resource { + return &schema.Resource{ + ReadContext: directoryRoleDataSourceRead, + + Timeouts: &schema.ResourceTimeout{ + Read: schema.DefaultTimeout(5 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "object_ids": { + Description: "The object IDs of the roles", + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + + "roles": { + Description: "A list of roles", + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "display_name": { + Description: "The display name of the directory role", + Type: schema.TypeString, + Computed: true, + }, + + "template_id": { + Description: "The object ID of the template associated with the directory role", + Type: schema.TypeString, + Computed: true, + }, + + "description": { + Description: "The description of the directory role", + Type: schema.TypeString, + Computed: true, + }, + + "object_id": { + Description: "The object ID of the directory role", + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + } +} + +func directoryRoleDataSourceRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*clients.Client).DirectoryRoles.DirectoryRolesClient + + directoryRoles, _, err := client.List(ctx) + if err != nil { + return tf.ErrorDiagF(err, "Could not retrieve roles") + } + if directoryRoles == nil { + return tf.ErrorDiagF(errors.New("API error: nil directoryRoles were returned"), "Retrieving all directory roles") + } + + objectIds := make([]string, 0) + roleList := make([]map[string]interface{}, 0) + + for _, r := range *directoryRoles { + objectIds = append(objectIds, *r.ID()) + + role := make(map[string]interface{}) + role["description"] = r.Description + role["display_name"] = r.DisplayName + role["object_id"] = r.ID() + role["template_id"] = r.RoleTemplateId + roleList = append(roleList, role) + } + + // Generate a unique ID based on result + h := sha1.New() + if _, err := h.Write([]byte(strings.Join(objectIds, "/"))); err != nil { + return tf.ErrorDiagF(err, "Unable to compute hash for Object IDs") + } + + d.SetId("roles#" + base64.URLEncoding.EncodeToString(h.Sum(nil))) + + tf.Set(d, "roles", roleList) + tf.Set(d, "object_ids", objectIds) + + return nil +} diff --git a/internal/services/directoryroles/directory_roles_data_source_test.go b/internal/services/directoryroles/directory_roles_data_source_test.go new file mode 100644 index 0000000000..270846cae9 --- /dev/null +++ b/internal/services/directoryroles/directory_roles_data_source_test.go @@ -0,0 +1,39 @@ +package directoryroles_test + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + + "github.com/hashicorp/terraform-provider-azuread/internal/acceptance" + "github.com/hashicorp/terraform-provider-azuread/internal/acceptance/check" +) + +type DirectoryRolesDataSource struct{} + +func TestAccDomainsDataSource_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "data.azuread_directory_roles", "test") + r := DirectoryRolesDataSource{} + + data.DataSourceTest(t, []resource.TestStep{ + { + Config: r.basic(), + Check: r.testCheckFunc(data), + }, + }) +} + +func (DirectoryRolesDataSource) testCheckFunc(data acceptance.TestData, additionalChecks ...resource.TestCheckFunc) resource.TestCheckFunc { + checks := []resource.TestCheckFunc{ + check.That(data.ResourceName).Key("roles.0.description").Exists(), + check.That(data.ResourceName).Key("roles.0.display_name").Exists(), + check.That(data.ResourceName).Key("roles.0.object_id").Exists(), + check.That(data.ResourceName).Key("roles.0.template_id").Exists(), + } + checks = append(checks, additionalChecks...) + return resource.ComposeTestCheckFunc(checks...) +} + +func (DirectoryRolesDataSource) basic() string { + return `data "azuread_directory_roles" "test" {}` +} diff --git a/internal/services/directoryroles/registration.go b/internal/services/directoryroles/registration.go index ed6d5e91a1..0db95596bf 100644 --- a/internal/services/directoryroles/registration.go +++ b/internal/services/directoryroles/registration.go @@ -20,7 +20,9 @@ func (r Registration) WebsiteCategories() []string { // SupportedDataSources returns the supported Data Sources supported by this Service func (r Registration) SupportedDataSources() map[string]*schema.Resource { - return map[string]*schema.Resource{} + return map[string]*schema.Resource{ + "azuread_directory_roles": directoryRoleDataSource(), + } } // SupportedResources returns the supported Resources supported by this Service From 632472ff6d7f088677f52356b393395003a229e1 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Wed, 11 Jan 2023 14:50:59 +0000 Subject: [PATCH 2/2] Apply suggestions from code review --- docs/data-sources/directory_roles.md | 4 ---- .../services/directoryroles/directory_roles_data_source.go | 6 +++--- .../directoryroles/directory_roles_data_source_test.go | 2 +- internal/services/directoryroles/registration.go | 2 +- 4 files changed, 5 insertions(+), 9 deletions(-) diff --git a/docs/data-sources/directory_roles.md b/docs/data-sources/directory_roles.md index 2ce4c59a2b..96539631f5 100644 --- a/docs/data-sources/directory_roles.md +++ b/docs/data-sources/directory_roles.md @@ -43,7 +43,3 @@ The following attributes are exported: * `template_id` - The template ID of the directory role. * `description` - The description of the directory role. * `object_id` - The object ID of the directory role. - -## Import - -This resource does not support importing. diff --git a/internal/services/directoryroles/directory_roles_data_source.go b/internal/services/directoryroles/directory_roles_data_source.go index 8e228657f1..1ba5cbb7ce 100644 --- a/internal/services/directoryroles/directory_roles_data_source.go +++ b/internal/services/directoryroles/directory_roles_data_source.go @@ -15,9 +15,9 @@ import ( "github.com/hashicorp/terraform-provider-azuread/internal/tf" ) -func directoryRoleDataSource() *schema.Resource { +func directoryRolesDataSource() *schema.Resource { return &schema.Resource{ - ReadContext: directoryRoleDataSourceRead, + ReadContext: directoryRolesDataSourceRead, Timeouts: &schema.ResourceTimeout{ Read: schema.DefaultTimeout(5 * time.Minute), @@ -69,7 +69,7 @@ func directoryRoleDataSource() *schema.Resource { } } -func directoryRoleDataSourceRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { +func directoryRolesDataSourceRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { client := meta.(*clients.Client).DirectoryRoles.DirectoryRolesClient directoryRoles, _, err := client.List(ctx) diff --git a/internal/services/directoryroles/directory_roles_data_source_test.go b/internal/services/directoryroles/directory_roles_data_source_test.go index 270846cae9..696184b990 100644 --- a/internal/services/directoryroles/directory_roles_data_source_test.go +++ b/internal/services/directoryroles/directory_roles_data_source_test.go @@ -11,7 +11,7 @@ import ( type DirectoryRolesDataSource struct{} -func TestAccDomainsDataSource_basic(t *testing.T) { +func TestAccDirectoryRolesDataSource_basic(t *testing.T) { data := acceptance.BuildTestData(t, "data.azuread_directory_roles", "test") r := DirectoryRolesDataSource{} diff --git a/internal/services/directoryroles/registration.go b/internal/services/directoryroles/registration.go index 0db95596bf..5bd2740f59 100644 --- a/internal/services/directoryroles/registration.go +++ b/internal/services/directoryroles/registration.go @@ -21,7 +21,7 @@ func (r Registration) WebsiteCategories() []string { // SupportedDataSources returns the supported Data Sources supported by this Service func (r Registration) SupportedDataSources() map[string]*schema.Resource { return map[string]*schema.Resource{ - "azuread_directory_roles": directoryRoleDataSource(), + "azuread_directory_roles": directoryRolesDataSource(), } }