Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SDK Migration 08: migrate directoryroles to go-azure-sdk #1482

Merged
merged 1 commit into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 59 additions & 27 deletions internal/services/directoryroles/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,44 +4,76 @@
package client

import (
"github.com/hashicorp/go-azure-sdk/microsoft-graph/directoryobjects/stable/directoryobject"
"github.com/hashicorp/go-azure-sdk/microsoft-graph/directoryroles/stable/directoryrole"
"github.com/hashicorp/go-azure-sdk/microsoft-graph/directoryroles/stable/member"
"github.com/hashicorp/go-azure-sdk/microsoft-graph/directoryroletemplates/stable/directoryroletemplate"
"github.com/hashicorp/go-azure-sdk/microsoft-graph/rolemanagement/stable/directoryroleassignment"
"github.com/hashicorp/go-azure-sdk/microsoft-graph/rolemanagement/stable/directoryroledefinition"
"github.com/hashicorp/go-azure-sdk/microsoft-graph/rolemanagement/stable/directoryroleeligibilityschedulerequest"
"github.com/hashicorp/terraform-provider-azuread/internal/common"
"github.com/manicminer/hamilton/msgraph"
)

type Client struct {
DirectoryObjectsClient *msgraph.DirectoryObjectsClient
DirectoryRolesClient *msgraph.DirectoryRolesClient
DirectoryRoleTemplatesClient *msgraph.DirectoryRoleTemplatesClient
RoleAssignmentsClient *msgraph.RoleAssignmentsClient
RoleDefinitionsClient *msgraph.RoleDefinitionsClient
RoleEligibilityScheduleRequestClient *msgraph.RoleEligibilityScheduleRequestClient
DirectoryObjectClient *directoryobject.DirectoryObjectClient
DirectoryRoleAssignmentClient *directoryroleassignment.DirectoryRoleAssignmentClient
DirectoryRoleClient *directoryrole.DirectoryRoleClient
DirectoryRoleDefinitionClient *directoryroledefinition.DirectoryRoleDefinitionClient
DirectoryRoleEligibilityScheduleRequestClient *directoryroleeligibilityschedulerequest.DirectoryRoleEligibilityScheduleRequestClient
DirectoryRoleMemberClient *member.MemberClient
DirectoryRoleTemplateClient *directoryroletemplate.DirectoryRoleTemplateClient
}

func NewClient(o *common.ClientOptions) *Client {
directoryObjectsClient := msgraph.NewDirectoryObjectsClient()
o.ConfigureClient(&directoryObjectsClient.BaseClient)
func NewClient(o *common.ClientOptions) (*Client, error) {
directoryObjectClient, err := directoryobject.NewDirectoryObjectClientWithBaseURI(o.Environment.MicrosoftGraph)
if err != nil {
return nil, err
}
o.Configure(directoryObjectClient.Client)

directoryRolesClient := msgraph.NewDirectoryRolesClient()
o.ConfigureClient(&directoryRolesClient.BaseClient)
directoryRoleClient, err := directoryrole.NewDirectoryRoleClientWithBaseURI(o.Environment.MicrosoftGraph)
if err != nil {
return nil, err
}
o.Configure(directoryRoleClient.Client)

directoryRoleTemplatesClient := msgraph.NewDirectoryRoleTemplatesClient()
o.ConfigureClient(&directoryRoleTemplatesClient.BaseClient)
directoryRoleAssignmentClient, err := directoryroleassignment.NewDirectoryRoleAssignmentClientWithBaseURI(o.Environment.MicrosoftGraph)
if err != nil {
return nil, err
}
o.Configure(directoryRoleAssignmentClient.Client)

roleAssignmentsClient := msgraph.NewRoleAssignmentsClient()
o.ConfigureClient(&roleAssignmentsClient.BaseClient)
directoryRoleDefinitionClient, err := directoryroledefinition.NewDirectoryRoleDefinitionClientWithBaseURI(o.Environment.MicrosoftGraph)
if err != nil {
return nil, err
}
o.Configure(directoryRoleDefinitionClient.Client)

roleDefinitionsClient := msgraph.NewRoleDefinitionsClient()
o.ConfigureClient(&roleDefinitionsClient.BaseClient)
directoryRoleMemberClient, err := member.NewMemberClientWithBaseURI(o.Environment.MicrosoftGraph)
if err != nil {
return nil, err
}
o.Configure(directoryRoleMemberClient.Client)

roleEligibilityScheduleRequestClient := msgraph.NewRoleEligibilityScheduleRequestClient()
o.ConfigureClient(&roleEligibilityScheduleRequestClient.BaseClient)
directoryRoleEligibilityScheduleRequestClient, err := directoryroleeligibilityschedulerequest.NewDirectoryRoleEligibilityScheduleRequestClientWithBaseURI(o.Environment.MicrosoftGraph)
if err != nil {
return nil, err
}
o.Configure(directoryRoleEligibilityScheduleRequestClient.Client)

return &Client{
DirectoryObjectsClient: directoryObjectsClient,
DirectoryRolesClient: directoryRolesClient,
DirectoryRoleTemplatesClient: directoryRoleTemplatesClient,
RoleAssignmentsClient: roleAssignmentsClient,
RoleDefinitionsClient: roleDefinitionsClient,
RoleEligibilityScheduleRequestClient: roleEligibilityScheduleRequestClient,
directoryRoleTemplateClient, err := directoryroletemplate.NewDirectoryRoleTemplateClientWithBaseURI(o.Environment.MicrosoftGraph)
if err != nil {
return nil, err
}
o.Configure(directoryRoleTemplateClient.Client)

return &Client{
DirectoryObjectClient: directoryObjectClient,
DirectoryRoleAssignmentClient: directoryRoleAssignmentClient,
DirectoryRoleClient: directoryRoleClient,
DirectoryRoleDefinitionClient: directoryRoleDefinitionClient,
DirectoryRoleEligibilityScheduleRequestClient: directoryRoleEligibilityScheduleRequestClient,
DirectoryRoleMemberClient: directoryRoleMemberClient,
DirectoryRoleTemplateClient: directoryRoleTemplateClient,
}, nil
}
3 changes: 3 additions & 0 deletions internal/services/directoryroles/constants.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package directoryroles

const directoryRoleMemberResourceName = "azuread_directory_role_member"
134 changes: 69 additions & 65 deletions internal/services/directoryroles/custom_directory_role_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@ import (
"errors"
"fmt"
"log"
"net/http"
"time"

"github.com/hashicorp/go-azure-helpers/lang/pointer"
"github.com/hashicorp/go-azure-sdk/sdk/odata"
"github.com/hashicorp/go-azure-helpers/lang/response"
"github.com/hashicorp/go-azure-sdk/microsoft-graph/common-types/stable"
"github.com/hashicorp/go-azure-sdk/microsoft-graph/rolemanagement/stable/directoryroledefinition"
"github.com/hashicorp/go-azure-sdk/sdk/nullable"
"github.com/hashicorp/go-uuid"
"github.com/hashicorp/terraform-provider-azuread/internal/clients"
"github.com/hashicorp/terraform-provider-azuread/internal/tf"
"github.com/hashicorp/terraform-provider-azuread/internal/tf/pluginsdk"
"github.com/hashicorp/terraform-provider-azuread/internal/tf/validation"
"github.com/manicminer/hamilton/msgraph"
"github.com/hashicorp/terraform-provider-azuread/internal/helpers/tf"
"github.com/hashicorp/terraform-provider-azuread/internal/helpers/tf/pluginsdk"
"github.com/hashicorp/terraform-provider-azuread/internal/helpers/tf/validation"
)

func customDirectoryRoleResource() *pluginsdk.Resource {
Expand All @@ -44,10 +44,10 @@ func customDirectoryRoleResource() *pluginsdk.Resource {

Schema: map[string]*pluginsdk.Schema{
"display_name": {
Description: "The display name of the custom directory role",
Type: pluginsdk.TypeString,
Required: true,
ValidateDiagFunc: validation.ValidateDiag(validation.StringIsNotEmpty),
Description: "The display name of the custom directory role",
Type: pluginsdk.TypeString,
Required: true,
ValidateFunc: validation.StringIsNotEmpty,
},

"enabled": {
Expand All @@ -67,19 +67,19 @@ func customDirectoryRoleResource() *pluginsdk.Resource {
Type: pluginsdk.TypeSet,
Required: true,
Elem: &pluginsdk.Schema{
Type: pluginsdk.TypeString,
ValidateDiagFunc: validation.ValidateDiag(validation.StringIsNotEmpty),
Type: pluginsdk.TypeString,
ValidateFunc: validation.StringIsNotEmpty,
},
},
},
},
},

"version": {
Description: "The version of the role definition.",
Type: pluginsdk.TypeString,
Required: true,
ValidateDiagFunc: validation.ValidateDiag(validation.StringLenBetween(1, 128)),
Description: "The version of the role definition.",
Type: pluginsdk.TypeString,
Required: true,
ValidateFunc: validation.StringLenBetween(1, 128),
},

"description": {
Expand All @@ -89,11 +89,11 @@ func customDirectoryRoleResource() *pluginsdk.Resource {
},

"template_id": {
Description: "Custom template identifier that is typically used if one needs an identifier to be the same across different directories.",
Type: pluginsdk.TypeString,
Optional: true,
Computed: true,
ValidateDiagFunc: validation.ValidateDiag(validation.IsUUID),
Description: "Custom template identifier that is typically used if one needs an identifier to be the same across different directories.",
Type: pluginsdk.TypeString,
Optional: true,
Computed: true,
ValidateFunc: validation.IsUUID,

// The template ID _can_ technically be changed but doing so mutates the role ID - essentially
// causing the equivalent of a ForceNew by the API :/
Expand All @@ -110,52 +110,54 @@ func customDirectoryRoleResource() *pluginsdk.Resource {
}

func customDirectoryRoleResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) pluginsdk.Diagnostics {
client := meta.(*clients.Client).DirectoryRoles.RoleDefinitionsClient
client := meta.(*clients.Client).DirectoryRoles.DirectoryRoleDefinitionClient

displayName := d.Get("display_name").(string)

properties := msgraph.UnifiedRoleDefinition{
Description: tf.NullableString(d.Get("description").(string)),
DisplayName: pointer.To(displayName),
IsEnabled: pointer.To(d.Get("enabled").(bool)),
properties := stable.UnifiedRoleDefinition{
Description: nullable.NoZero(d.Get("description").(string)),
DisplayName: nullable.Value(displayName),
IsEnabled: nullable.Value(d.Get("enabled").(bool)),
RolePermissions: expandCustomRolePermissions(d.Get("permissions").(*pluginsdk.Set).List()),
TemplateId: pointer.To(d.Get("template_id").(string)),
Version: pointer.To(d.Get("version").(string)),
TemplateId: nullable.Value(d.Get("template_id").(string)),
Version: nullable.Value(d.Get("version").(string)),
}

role, _, err := client.Create(ctx, properties)
resp, err := client.CreateDirectoryRoleDefinition(ctx, properties, directoryroledefinition.DefaultCreateDirectoryRoleDefinitionOperationOptions())
if err != nil {
return tf.ErrorDiagF(err, "Creating custom directory role %q", displayName)
}

if role.ID() == nil || *role.ID() == "" {
role := resp.Model
if role == nil {
return tf.ErrorDiagF(errors.New("model was nil"), "Creating custom directory role %q", displayName)
}

if role.Id == nil || *role.Id == "" {
return tf.ErrorDiagF(errors.New("API returned custom directory role with nil ID"), "Bad API Response")
}

d.SetId(*role.ID())
d.SetId(*role.Id)

return customDirectoryRoleResourceRead(ctx, d, meta)
}

func customDirectoryRoleResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) pluginsdk.Diagnostics {
client := meta.(*clients.Client).DirectoryRoles.RoleDefinitionsClient
roleId := d.Id()
client := meta.(*clients.Client).DirectoryRoles.DirectoryRoleDefinitionClient
id := stable.NewRoleManagementDirectoryRoleDefinitionID(d.Id())

displayName := d.Get("display_name").(string)

properties := msgraph.UnifiedRoleDefinition{
DirectoryObject: msgraph.DirectoryObject{
Id: &roleId,
},
Description: tf.NullableString(d.Get("description").(string)),
DisplayName: pointer.To(displayName),
IsEnabled: pointer.To(d.Get("enabled").(bool)),
properties := stable.UnifiedRoleDefinition{
Description: nullable.NoZero(d.Get("description").(string)),
DisplayName: nullable.Value(displayName),
IsEnabled: nullable.Value(d.Get("enabled").(bool)),
RolePermissions: expandCustomRolePermissions(d.Get("permissions").(*pluginsdk.Set).List()),
TemplateId: pointer.To(d.Get("template_id").(string)),
Version: pointer.To(d.Get("version").(string)),
TemplateId: nullable.Value(d.Get("template_id").(string)),
Version: nullable.Value(d.Get("version").(string)),
}

_, err := client.Update(ctx, properties)
_, err := client.UpdateDirectoryRoleDefinition(ctx, id, properties, directoryroledefinition.DefaultUpdateDirectoryRoleDefinitionOperationOptions())
if err != nil {
return tf.ErrorDiagF(err, "Updating custom directory role %q", displayName)
}
Expand All @@ -164,47 +166,49 @@ func customDirectoryRoleResourceUpdate(ctx context.Context, d *pluginsdk.Resourc
}

func customDirectoryRoleResourceRead(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) pluginsdk.Diagnostics {
client := meta.(*clients.Client).DirectoryRoles.RoleDefinitionsClient
roleId := d.Id()
client := meta.(*clients.Client).DirectoryRoles.DirectoryRoleDefinitionClient
id := stable.NewRoleManagementDirectoryRoleDefinitionID(d.Id())

role, status, err := client.Get(ctx, roleId, odata.Query{})
resp, err := client.GetDirectoryRoleDefinition(ctx, id, directoryroledefinition.DefaultGetDirectoryRoleDefinitionOperationOptions())
if err != nil {
if status == http.StatusNotFound {
log.Printf("[DEBUG] Custom Directory Role with ID %q was not found - removing from state", roleId)
if response.WasNotFound(resp.HttpResponse) {
log.Printf("[DEBUG] %s was not found - removing from state", id)
d.SetId("")
return nil
}
return tf.ErrorDiagPathF(err, "template_id", "Retrieving custom directory role with ID %q: %+v", roleId, err)
return tf.ErrorDiagPathF(err, "template_id", "Retrieving %s: %+v", id, err)
}

role := resp.Model
if role == nil {
return tf.ErrorDiagF(errors.New("API error: nil unifiedDirectoryRole was returned"), "Retrieving custom directory role with ID %q", roleId)
return tf.ErrorDiagF(errors.New("API error: nil unifiedDirectoryRole was returned"), "Retrieving %s", id)
}

tf.Set(d, "description", role.Description)
tf.Set(d, "display_name", role.DisplayName)
tf.Set(d, "enabled", role.IsEnabled)
tf.Set(d, "object_id", role.ID())
tf.Set(d, "description", role.Description.GetOrZero())
tf.Set(d, "display_name", role.DisplayName.GetOrZero())
tf.Set(d, "enabled", role.IsEnabled.GetOrZero())
tf.Set(d, "object_id", id.UnifiedRoleDefinitionId)
tf.Set(d, "permissions", flattenCustomRolePermissions(role.RolePermissions))
tf.Set(d, "template_id", role.TemplateId)
tf.Set(d, "version", role.Version)
tf.Set(d, "template_id", role.TemplateId.GetOrZero())
tf.Set(d, "version", role.Version.GetOrZero())

return nil
}

func customDirectoryRoleResourceDelete(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) pluginsdk.Diagnostics {
client := meta.(*clients.Client).DirectoryRoles.RoleDefinitionsClient
roleId := d.Id()
client := meta.(*clients.Client).DirectoryRoles.DirectoryRoleDefinitionClient
id := stable.NewRoleManagementDirectoryRoleDefinitionID(d.Id())

_, status, err := client.Get(ctx, roleId, odata.Query{})
resp, err := client.GetDirectoryRoleDefinition(ctx, id, directoryroledefinition.DefaultGetDirectoryRoleDefinitionOperationOptions())
if err != nil {
if status == http.StatusNotFound {
return tf.ErrorDiagPathF(fmt.Errorf("Custom Directory Role was not found"), "id", "Retrieving custom directory role with ID %q", roleId)
if response.WasNotFound(resp.HttpResponse) {
return tf.ErrorDiagPathF(fmt.Errorf("Custom Directory Role was not found"), "id", "Retrieving %s", id)
}
return tf.ErrorDiagPathF(err, "id", "Retrieving custom directory role with ID %q", roleId)
return tf.ErrorDiagPathF(err, "id", "Retrieving %s", id)
}

if status, err := client.Delete(ctx, roleId); err != nil {
return tf.ErrorDiagPathF(err, "id", "Deleting custom directory role with ID %q, got status %d", roleId, status)
if _, err = client.DeleteDirectoryRoleDefinition(ctx, id, directoryroledefinition.DefaultDeleteDirectoryRoleDefinitionOperationOptions()); err != nil {
return tf.ErrorDiagPathF(err, "id", "Deleting %s", id)
}

return nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ package directoryroles_test
import (
"context"
"fmt"
"net/http"
"testing"

"github.com/hashicorp/go-azure-helpers/lang/pointer"
"github.com/hashicorp/go-azure-sdk/sdk/odata"
"github.com/hashicorp/go-azure-helpers/lang/response"
"github.com/hashicorp/go-azure-sdk/microsoft-graph/common-types/stable"
"github.com/hashicorp/go-azure-sdk/microsoft-graph/rolemanagement/stable/directoryroledefinition"
"github.com/hashicorp/terraform-plugin-testing/terraform"
"github.com/hashicorp/terraform-provider-azuread/internal/acceptance"
"github.com/hashicorp/terraform-provider-azuread/internal/acceptance/check"
Expand Down Expand Up @@ -129,19 +130,18 @@ func TestAccCustomDirectoryRole_templateId(t *testing.T) {
}

func (r CustomDirectoryRoleResource) Exists(ctx context.Context, clients *clients.Client, state *terraform.InstanceState) (*bool, error) {
client := clients.DirectoryRoles.RoleDefinitionsClient
client.BaseClient.DisableRetries = true
defer func() { client.BaseClient.DisableRetries = false }()
client := clients.DirectoryRoles.DirectoryRoleDefinitionClient
id := stable.NewRoleManagementDirectoryRoleDefinitionID(state.ID)

role, status, err := client.Get(ctx, state.ID, odata.Query{})
resp, err := client.GetDirectoryRoleDefinition(ctx, id, directoryroledefinition.DefaultGetDirectoryRoleDefinitionOperationOptions())
if err != nil {
if status == http.StatusNotFound {
return nil, fmt.Errorf("Custom Directory Role with ID %q does not exist", state.ID)
if response.WasNotFound(resp.HttpResponse) {
return pointer.To(false), nil
}
return nil, fmt.Errorf("failed to retrieve Custom Directory Role with object ID %q: %+v", state.ID, err)
return nil, fmt.Errorf("failed to retrieve %s: %+v", id, err)
}

return pointer.To(role.ID() != nil && *role.ID() == state.ID), nil
return pointer.To(true), nil
}

func (r CustomDirectoryRoleResource) basic(data acceptance.TestData) string {
Expand Down
Loading
Loading