From 90fc00ae5c80e7631171b3d3c208733e5bef1380 Mon Sep 17 00:00:00 2001 From: Josh Barker Date: Fri, 10 Feb 2023 11:43:23 +1100 Subject: [PATCH] feat: role management policy resource --- internal/provider/services.go | 1 + .../services/authorization/client/client.go | 14 +- .../parse/role_management_policy.go | 66 + .../services/authorization/registration.go | 12 + .../authorization/role_management_policy.go | 1410 +++++++++++++++++ .../role_management_policy_test.go | 861 ++++++++++ .../validate/role_management_policy.go | 37 + .../rolemanagementpolicies/README.md | 90 ++ .../rolemanagementpolicies/client.go | 18 + .../rolemanagementpolicies/constants.go | 43 + .../id_scopedrolemanagementpolicy.go | 110 ++ .../method_delete_autorest.go | 66 + .../method_get_autorest.go | 68 + .../method_listforscope_autorest.go | 193 +++ .../method_update_autorest.go | 69 + .../model_policyproperties.go | 8 + .../model_policypropertiesscope.go | 10 + .../rolemanagementpolicies/model_principal.go | 11 + .../model_rolemanagementpolicy.go | 11 + .../model_rolemanagementpolicyproperties.go | 94 ++ .../model_rolemanagementpolicyrule.go | 45 + .../model_rolemanagementpolicyruletarget.go | 13 + .../rolemanagementpolicies/predicates.go | 24 + .../rolemanagementpolicies/version.go | 12 + vendor/modules.txt | 1 + .../r/role_management_policy.html.markdown | 211 +++ 26 files changed, 3494 insertions(+), 4 deletions(-) create mode 100644 internal/services/authorization/parse/role_management_policy.go create mode 100644 internal/services/authorization/role_management_policy.go create mode 100644 internal/services/authorization/role_management_policy_test.go create mode 100644 internal/services/authorization/validate/role_management_policy.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/README.md create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/client.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/constants.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/id_scopedrolemanagementpolicy.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/method_delete_autorest.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/method_get_autorest.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/method_listforscope_autorest.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/method_update_autorest.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/model_policyproperties.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/model_policypropertiesscope.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/model_principal.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/model_rolemanagementpolicy.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/model_rolemanagementpolicyproperties.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/model_rolemanagementpolicyrule.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/model_rolemanagementpolicyruletarget.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/predicates.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/version.go create mode 100644 website/docs/r/role_management_policy.html.markdown diff --git a/internal/provider/services.go b/internal/provider/services.go index 719df7d4d1f83..042a436a04982 100644 --- a/internal/provider/services.go +++ b/internal/provider/services.go @@ -125,6 +125,7 @@ func SupportedTypedServices() []sdk.TypedServiceRegistration { appconfiguration.Registration{}, applicationinsights.Registration{}, appservice.Registration{}, + authorization.Registration{}, automation.Registration{}, batch.Registration{}, bot.Registration{}, diff --git a/internal/services/authorization/client/client.go b/internal/services/authorization/client/client.go index 2da83c9530f76..ac3791cfb788d 100644 --- a/internal/services/authorization/client/client.go +++ b/internal/services/authorization/client/client.go @@ -2,12 +2,14 @@ package client import ( "github.com/Azure/azure-sdk-for-go/services/preview/authorization/mgmt/2020-04-01-preview/authorization" // nolint: staticcheck // nolint: staticcheck + "github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies" "github.com/hashicorp/terraform-provider-azurerm/internal/common" ) type Client struct { - RoleAssignmentsClient *authorization.RoleAssignmentsClient - RoleDefinitionsClient *authorization.RoleDefinitionsClient + RoleAssignmentsClient *authorization.RoleAssignmentsClient + RoleDefinitionsClient *authorization.RoleDefinitionsClient + RoleManagementPoliciesClient *rolemanagementpolicies.RoleManagementPoliciesClient } func NewClient(o *common.ClientOptions) *Client { @@ -17,8 +19,12 @@ func NewClient(o *common.ClientOptions) *Client { roleDefinitionsClient := authorization.NewRoleDefinitionsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) o.ConfigureClient(&roleDefinitionsClient.Client, o.ResourceManagerAuthorizer) + roleManagementPoliciesClient := rolemanagementpolicies.NewRoleManagementPoliciesClientWithBaseURI(o.ResourceManagerEndpoint) + o.ConfigureClient(&roleManagementPoliciesClient.Client, o.ResourceManagerAuthorizer) + return &Client{ - RoleAssignmentsClient: &roleAssignmentsClient, - RoleDefinitionsClient: &roleDefinitionsClient, + RoleAssignmentsClient: &roleAssignmentsClient, + RoleDefinitionsClient: &roleDefinitionsClient, + RoleManagementPoliciesClient: &roleManagementPoliciesClient, } } diff --git a/internal/services/authorization/parse/role_management_policy.go b/internal/services/authorization/parse/role_management_policy.go new file mode 100644 index 0000000000000..ba05721cc5aa1 --- /dev/null +++ b/internal/services/authorization/parse/role_management_policy.go @@ -0,0 +1,66 @@ +package parse + +import ( + "fmt" + "strings" + + "github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies" +) + +type RoleManagementPolicyID struct { + Scope string + RoleManagementPolicyName string + RoleDefinitionId string +} + +func NewRoleManagementPolicyID(scope string, roleManagementPolicyName string, roleDefinitionId string) RoleManagementPolicyID { + return RoleManagementPolicyID{ + Scope: scope, + RoleManagementPolicyName: roleManagementPolicyName, + RoleDefinitionId: roleDefinitionId, + } +} + +func (id RoleManagementPolicyID) ID() string { + fmtString := "%s/providers/Microsoft.Authorization/roleManagementPolicies/%s|%s" + return fmt.Sprintf(fmtString, id.Scope, id.RoleManagementPolicyName, id.RoleDefinitionId) +} + +func (id RoleManagementPolicyID) ScopedRoleManagementPolicyId() rolemanagementpolicies.ScopedRoleManagementPolicyId { + return rolemanagementpolicies.NewScopedRoleManagementPolicyID(id.Scope, id.RoleManagementPolicyName) +} + +func (id RoleManagementPolicyID) String() string { + segments := []string{ + fmt.Sprintf("RoleManagementPolicyName %q", id.RoleManagementPolicyName), + fmt.Sprintf("Scope %q", id.Scope), + fmt.Sprintf("Role Definition Id %q", id.RoleDefinitionId), + } + segmentsStr := strings.Join(segments, " / ") + return fmt.Sprintf("%s: (%s)", "Role Management Policy", segmentsStr) +} + +// RoleManagementPolicyId is a pseudo ID for storing Scope parameter as this it not retrievable from API +// It is formed of the Azure Resource ID for the Role and the Scope it is created against +func RoleManagementPolicyId(input string) (*RoleManagementPolicyID, error) { + parts := strings.Split(input, "|") + if len(parts) != 2 { + return nil, fmt.Errorf("could not parse Role Management Policy ID, invalid format %q", input) + } + + roleManagementPolicyID := RoleManagementPolicyID{} + + rawRoleManagementPolicyId := parts[0] + rawRoleDefinitionId := parts[1] + + roleManagementPolicyId, err := rolemanagementpolicies.ParseScopedRoleManagementPolicyID(rawRoleManagementPolicyId) + if err != nil { + return nil, err + } + roleManagementPolicyID.Scope = *&roleManagementPolicyId.Scope + roleManagementPolicyID.RoleManagementPolicyName = *&roleManagementPolicyId.RoleManagementPolicyName + + roleManagementPolicyID.RoleDefinitionId = rawRoleDefinitionId + + return &roleManagementPolicyID, nil +} diff --git a/internal/services/authorization/registration.go b/internal/services/authorization/registration.go index bbb87b8c463aa..9f2f402d6043e 100644 --- a/internal/services/authorization/registration.go +++ b/internal/services/authorization/registration.go @@ -8,6 +8,7 @@ import ( type Registration struct{} var _ sdk.UntypedServiceRegistrationWithAGitHubLabel = Registration{} +var _ sdk.TypedServiceRegistrationWithAGitHubLabel = Registration{} func (r Registration) AssociatedGitHubLabel() string { return "service/authorization" @@ -40,3 +41,14 @@ func (r Registration) SupportedResources() map[string]*pluginsdk.Resource { "azurerm_role_definition": resourceArmRoleDefinition(), } } + +func (r Registration) DataSources() []sdk.DataSource { + return []sdk.DataSource{} +} + +func (r Registration) Resources() []sdk.Resource { + resources := []sdk.Resource{ + RoleManagementPolicyResource{}, + } + return resources +} diff --git a/internal/services/authorization/role_management_policy.go b/internal/services/authorization/role_management_policy.go new file mode 100644 index 0000000000000..fcee4deed55e4 --- /dev/null +++ b/internal/services/authorization/role_management_policy.go @@ -0,0 +1,1410 @@ +package authorization + +import ( + "context" + "fmt" + "log" + "regexp" + "strconv" + "time" + + "github.com/hashicorp/go-azure-helpers/lang/response" + "github.com/hashicorp/go-azure-helpers/resourcemanager/commonids" + "github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-provider-azurerm/internal/locks" + "github.com/hashicorp/terraform-provider-azurerm/internal/sdk" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/authorization/parse" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/authorization/validate" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" +) + +var _ sdk.Resource = RoleManagementPolicyResource{} + +var _ sdk.ResourceWithUpdate = RoleManagementPolicyResource{} + +var _ sdk.ResourceWithCustomizeDiff = RoleManagementPolicyResource{} + +type RoleManagementPolicyResource struct{} + +func (r RoleManagementPolicyResource) Arguments() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{ + "scope": { + Type: pluginsdk.TypeString, + Required: true, + Description: "The scope.", + }, + "role_definition_id": { + Type: pluginsdk.TypeString, + Required: true, + Description: "The role definition id.", + }, + "activation": { + Type: pluginsdk.TypeList, + MaxItems: 1, + Optional: true, + Description: "The activation settings for PIM on the scope and role definition.", + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "maximum_duration_hours": { + Type: pluginsdk.TypeInt, + Optional: true, + Computed: true, + Description: "The maximum duration in hours for an activation.", + }, + "require_multi_factor_authentication": { + Type: pluginsdk.TypeBool, + Optional: true, + Computed: true, + Description: "Is Multi Factor Authentication required for an activation?", + }, + "require_justification": { + Type: pluginsdk.TypeBool, + Optional: true, + Computed: true, + Description: "Is Justification required for an activation?", + }, + "require_ticket_information": { + Type: pluginsdk.TypeBool, + Optional: true, + Computed: true, + Description: "Is Ticket Information required for an activation?", + }, + "approvers": { + Type: pluginsdk.TypeList, + MaxItems: 1, + Optional: true, + Description: "A list of approvers for activation.", + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "group": { + Type: pluginsdk.TypeList, + Optional: true, + Description: "An approval group", + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "id": { + Type: pluginsdk.TypeString, + Required: true, + Description: "The object id of the AAD group.", + }, + "name": { + Type: pluginsdk.TypeString, + Required: true, + Description: "The name of the AAD group.", + }, + }, + }, + }, + "user": { + Type: pluginsdk.TypeList, + Optional: true, + Description: "An approval user", + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "id": { + Type: pluginsdk.TypeString, + Required: true, + Description: "The object id of a user.", + }, + "name": { + Type: pluginsdk.TypeString, + Required: true, + Description: "The name of a user.", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "assignment": { + Type: pluginsdk.TypeList, + MaxItems: 1, + Optional: true, + Description: "The assignment settings for PIM on the scope and role definition.", + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "eligible": { + Type: pluginsdk.TypeList, + MaxItems: 1, + Optional: true, + Description: "The eligible settings for an assignment.", + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "allow_permanent": { + Type: pluginsdk.TypeBool, + Optional: true, + Computed: true, + Description: "Allow permanent eligible assignment.", + ConflictsWith: []string{ + "assignment.0.eligible.0.expire_after_hours", + "assignment.0.eligible.0.expire_after_days", + }, + }, + "expire_after_hours": { + Type: pluginsdk.TypeInt, + Optional: true, + Computed: true, + Description: "The number of hours after an eligible assignments is expired.", + ConflictsWith: []string{ + "assignment.0.eligible.0.allow_permanent", + "assignment.0.eligible.0.expire_after_days", + }, + }, + "expire_after_days": { + Type: pluginsdk.TypeInt, + Optional: true, + Computed: true, + Description: "The number of days after an eligible assignments is expired.", + ConflictsWith: []string{ + "assignment.0.eligible.0.allow_permanent", + "assignment.0.eligible.0.expire_after_hours", + }, + }, + }, + }, + }, + "active": { + Type: pluginsdk.TypeList, + MaxItems: 1, + Optional: true, + Description: "The active settings for an assignment.", + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "allow_permanent": { + Type: pluginsdk.TypeBool, + Optional: true, + Computed: true, + Description: "Allow permanent active assignment.", + ConflictsWith: []string{ + "assignment.0.active.0.expire_after_days", + "assignment.0.active.0.expire_after_hours", + }, + }, + "expire_after_hours": { + Type: pluginsdk.TypeInt, + Optional: true, + Computed: true, + Description: "The number of hours after an active assignments is expired.", + ConflictsWith: []string{ + "assignment.0.active.0.allow_permanent", + "assignment.0.active.0.expire_after_days", + }, + }, + "expire_after_days": { + Type: pluginsdk.TypeInt, + Optional: true, + Computed: true, + Description: "The number of days after an active assignments is expired.", + ConflictsWith: []string{ + "assignment.0.active.0.allow_permanent", + "assignment.0.active.0.expire_after_hours", + }, + }, + "require_multi_factor_authentication": { + Type: pluginsdk.TypeBool, + Optional: true, + Computed: true, + Description: "Is Multi Factor Authentication required for an active assignment?", + }, + "require_justification": { + Type: pluginsdk.TypeBool, + Optional: true, + Computed: true, + Description: "Is Justification required for an active assignment?", + }, + }, + }, + }, + }, + }, + }, + "notifications": { + Type: pluginsdk.TypeList, + MaxItems: 1, + Optional: true, + Description: "The notification settings for PIM on the scope and role definition.", + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "member_assigned_eligible": { + Type: pluginsdk.TypeList, + MaxItems: 1, + Optional: true, + Computed: true, + Description: "Notifications settings when members are assigned as eligible to this role.", + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "role_assignment_alert": { + Type: pluginsdk.TypeList, + MaxItems: 1, + Optional: true, + Computed: true, + Description: "Notification settings for the Role assignment alerts.", + Elem: notificationConfiguration(), + }, + "assigned_user": { + Type: pluginsdk.TypeList, + MaxItems: 1, + Optional: true, + Computed: true, + Description: "Notification settings for the assigned user (assignee).", + Elem: notificationConfiguration(), + }, + "request_for_extension_or_approval": { + Type: pluginsdk.TypeList, + MaxItems: 1, + Optional: true, + Computed: true, + Description: "Notification settings for the Request to approve a role assignment renewal/extension.", + Elem: notificationConfiguration(), + }, + }, + }, + }, + "member_assigned_active": { + Type: pluginsdk.TypeList, + MaxItems: 1, + Optional: true, + Computed: true, + Description: "Notifications settings when members are assigned as active to this role. ", + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "role_assignment_alert": { + Type: pluginsdk.TypeList, + MaxItems: 1, + Optional: true, + Computed: true, + Description: "Notification settings for the Role assignment alerts.", + Elem: notificationConfiguration(), + }, + "assigned_user": { + Type: pluginsdk.TypeList, + MaxItems: 1, + Optional: true, + Computed: true, + Description: "Notification settings for the assigned user (assignee).", + Elem: notificationConfiguration(), + }, + "request_for_extension_or_approval": { + Type: pluginsdk.TypeList, + MaxItems: 1, + Optional: true, + Computed: true, + Description: "Notification settings for the Request to approve a role assignment renewal/extension.", + Elem: notificationConfiguration(), + }, + }, + }, + }, + "eligible_member_activate": { + Type: pluginsdk.TypeList, + MaxItems: 1, + Optional: true, + Computed: true, + Description: "Notifications settings when eligible members activate this role.", + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "role_assignment_alert": { + Type: pluginsdk.TypeList, + MaxItems: 1, + Optional: true, + Computed: true, + Description: "Notification settings for the Role assignment alerts.", + Elem: notificationConfiguration(), + }, + "assigned_user": { + Type: pluginsdk.TypeList, + MaxItems: 1, + Optional: true, + Computed: true, + Description: "Notification settings for the assigned user (assignee).", + Elem: notificationConfiguration(), + }, + "request_for_extension_or_approval": { + Type: pluginsdk.TypeList, + MaxItems: 1, + Optional: true, + Computed: true, + Description: "Notification settings for the Request to approve a role assignment renewal/extension.", + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "default_recipients": { + Type: pluginsdk.TypeBool, + Optional: true, + Computed: true, + Description: "Will notifications be sent to the default recipients?", + }, + "critical_emails_only": { + Type: pluginsdk.TypeBool, + Optional: true, + Computed: true, + Description: "Will critical emails only be sent?", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } +} + +func (r RoleManagementPolicyResource) CustomizeDiff() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 5 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + rd := metadata.ResourceDiff + // custom validation for multiple properties + + if rd.HasChange("notifications.0.eligible_member_activate.0.request_for_extension_or_approval") { + _, criticalEmailsAfter := rd.GetChange("notifications.0.eligible_member_activate.0.request_for_extension_or_approval.0.critical_emails_only") + _, defaultRecipientsAfter := rd.GetChange("notifications.0.eligible_member_activate.0.request_for_extension_or_approval.0.default_recipients") + + if criticalEmailsAfter.(bool) && !defaultRecipientsAfter.(bool) { + return fmt.Errorf("cannot enable critical emails and disable default recipients for `request_for_extension_or_approval` on `eligible_member_activate`") + } + } + + if rd.HasChange("assignment.0.eligible") { + _, assignmentEligibleAllowPermanent := rd.GetChange("assignment.0.eligible.0.allow_permanent") + _, assignmentEligibleExpireAfterHours := rd.GetChange("assignment.0.eligible.0.expire_after_hours") + _, assignmentEligibleExpireAfterDays := rd.GetChange("assignment.0.eligible.0.expire_after_days") + + if !assignmentEligibleAllowPermanent.(bool) && assignmentEligibleExpireAfterHours.(int) == 0 && assignmentEligibleExpireAfterDays.(int) == 0 { + return fmt.Errorf("cannot set allow permanent to false when expire after days and hours is 0 on `assignment` for `eligible`") + } + } + + if rd.HasChange("assignment.0.active") { + _, assignmentActiveAllowPermanent := rd.GetChange("assignment.0.active.0.allow_permanent") + _, assignmentActiveExpireAfterHours := rd.GetChange("assignment.0.active.0.expire_after_hours") + _, assignmentActiveExpireAfterDays := rd.GetChange("assignment.0.active.0.expire_after_days") + + if !assignmentActiveAllowPermanent.(bool) && assignmentActiveExpireAfterHours.(int) == 0 && assignmentActiveExpireAfterDays.(int) == 0 { + return fmt.Errorf("cannot set allow permanent to false when expire after days and hours is 0 on `assignment` for `active`") + } + } + + return nil + }, + } +} + +func notificationConfiguration() *pluginsdk.Resource { + return &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "default_recipients": { + Type: pluginsdk.TypeBool, + Optional: true, + Computed: true, + Description: "Will notifications be sent to the default recipients?", + }, + "additional_recipients": { + Type: pluginsdk.TypeSet, + Optional: true, + Computed: true, + Description: "List of additional recipients to email notifications", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "critical_emails_only": { + Type: pluginsdk.TypeBool, + Optional: true, + Computed: true, + Description: "Will critical emails only be sent?", + }, + }, + } +} + +func (r RoleManagementPolicyResource) Attributes() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{} +} + +func (r RoleManagementPolicyResource) ModelObject() interface{} { + return &RoleManagementPolicyResourceSchema{} +} + +func (r RoleManagementPolicyResource) ResourceType() string { + return "azurerm_role_management_policy" +} + +func (r RoleManagementPolicyResource) Create() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 30 * time.Minute, + + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + return r.createUpdate(ctx, metadata) + }, + } +} + +func (r RoleManagementPolicyResource) Update() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 30 * time.Minute, + + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + return r.createUpdate(ctx, metadata) + }, + } +} + +func (r RoleManagementPolicyResource) createUpdate(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Authorization.RoleManagementPoliciesClient + + var id rolemanagementpolicies.ScopedRoleManagementPolicyId + + roleDefinitionId := metadata.ResourceData.Get("role_definition_id").(string) + scope := metadata.ResourceData.Get("scope").(string) + + lockId := fmt.Sprintf("%s|%s", scope, roleDefinitionId) + + locks.ByName(lockId, r.ResourceType()) + defer locks.UnlockByName(lockId, r.ResourceType()) + + scopeId := &commonids.ScopeId{ + Scope: scope, + } + filter := "roleDefinitionId%20eq%20'" + roleDefinitionId + "'" + + // filter by role definition + result, err := client.ListForScopeComplete(ctx, *scopeId, filter) + if err != nil { + return fmt.Errorf("loading finding role management policy %q: %+v", scopeId, err) + } + + if len(result.Items) != 1 { + return fmt.Errorf("loading finding role management policy %q: %+v", scopeId, err) + } + + roleManagementPolicyId := *result.Items[0].Name + id = rolemanagementpolicies.NewScopedRoleManagementPolicyID(scope, roleManagementPolicyId) + + var config RoleManagementPolicyResourceSchema + if err := metadata.Decode(&config); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + var payload rolemanagementpolicies.RoleManagementPolicy + + if err := r.mapRoleManagementPolicyResourceSchemaToRoleManagementPolicy(config, &payload); err != nil { + return fmt.Errorf("mapping schema model to sdk model: %+v", err) + } + + res, err := client.Update(ctx, id, payload) + if err != nil { + return fmt.Errorf("updating %q: %+v", id.ID(), err) + } + + if res.Model == nil { + return fmt.Errorf("could not get role management policy") + } + policyID := res.Model.Name + stateId := parse.NewRoleManagementPolicyID(scope, *policyID, roleDefinitionId) + + metadata.ResourceData.SetId(stateId.ID()) + + return nil +} + +func (r RoleManagementPolicyResource) Read() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 5 * time.Minute, + + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Authorization.RoleManagementPoliciesClient + schema := RoleManagementPolicyResourceSchema{} + + id, err := parse.RoleManagementPolicyId(metadata.ResourceData.Id()) + if err != nil { + return err + } + + resp, err := client.Get(ctx, id.ScopedRoleManagementPolicyId()) + if err != nil { + if response.WasNotFound(resp.HttpResponse) { + log.Printf("[DEBUG] Role Management Policy %q was not found - removing from state", id) + metadata.MarkAsGone(id) + return nil + } + + return fmt.Errorf("loading Role Management Policy %q: %+v", id, err) + } + + if model := resp.Model; model != nil { + schema.Scope = id.Scope + schema.RoleDefinitionID = id.RoleDefinitionId + + var config RoleManagementPolicyResourceSchema + if err := metadata.Decode(&config); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + if err := r.mapRoleManagementPolicyToRoleManagementPolicyResourceSchema(*model, &schema, &config); err != nil { + return fmt.Errorf("flattening model: %+v", err) + } + } + + return metadata.Encode(&schema) + }, + } +} + +func (r RoleManagementPolicyResource) Delete() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 30 * time.Minute, + + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + // nothing to delete + id, err := parse.RoleManagementPolicyId(metadata.ResourceData.Id()) + if err != nil { + return fmt.Errorf("error parsing role management id: %v", err) + } + + metadata.MarkAsGone(id) + + return nil + }, + } +} + +func (r RoleManagementPolicyResource) IDValidationFunc() pluginsdk.SchemaValidateFunc { + return validate.ValidateRoleManagementPolicyId +} + +// functions to convert data from terraform structs to azure structs + +func (r RoleManagementPolicyResource) mapRoleManagementPolicyResourceSchemaToRoleManagementPolicy(input RoleManagementPolicyResourceSchema, output *rolemanagementpolicies.RoleManagementPolicy) error { + + if output.Properties == nil { + output.Properties = &rolemanagementpolicies.RoleManagementPolicyProperties{} + } + if err := r.mapRoleManagementPolicyResourceSchemaToProperties(input, output.Properties); err != nil { + return err + } + return nil +} + +func (r RoleManagementPolicyResource) mapRoleManagementPolicyResourceSchemaToProperties(input RoleManagementPolicyResourceSchema, output *rolemanagementpolicies.RoleManagementPolicyProperties) error { + output.Scope = &input.Scope + + if output.Rules == nil { + rules := make([]rolemanagementpolicies.RoleManagementPolicyRule, 0) + output.Rules = &rules + } + + if len(input.Activation) == 1 { + if err := r.mapRoleManagementPolicyResourceActivationSchemaToRoleManagementPolicyProperties(input.Activation[0], output); err != nil { + return err + } + } + if len(input.Assignment) == 1 { + if err := r.mapRoleManagementPolicyResourceAssignmentSchemaToRoleManagementPolicyProperties(input.Assignment[0], output); err != nil { + return err + } + } + if len(input.Notifications) == 1 { + if err := r.mapRoleManagementPolicyResourceSchemaNotificationsToRoleManagementPolicyProperties(input.Notifications[0], output); err != nil { + return err + } + } + + return nil +} + +func (r RoleManagementPolicyResource) mapRoleManagementPolicyResourceActivationSchemaToRoleManagementPolicyProperties(input RoleManagementPolicyResourceSchemaActivation, output *rolemanagementpolicies.RoleManagementPolicyProperties) error { + if input.MaximumDurationHours > 0 { + expirationRule := ExpirationRule{ + Id: "Expiration_EndUser_Assignment", + RuleType: "RoleManagementPolicyExpirationRule", + MaximumDuration: fmt.Sprintf("PT%dH", input.MaximumDurationHours), + IsExpirationRequired: true, + Target: &Target{ + Caller: "EndUser", + Operations: []string{"All"}, + Level: "Eligibility", + TargetObjects: nil, + InheritableSettings: nil, + EnforceSettings: nil, + }, + } + *output.Rules = append(*output.Rules, expirationRule) + } + + enabledRules := make([]string, 0) + + if input.RequireJustification { + enabledRules = append(enabledRules, "Justification") + } + if input.RequireMultiFactorAuthentication { + enabledRules = append(enabledRules, "MultiFactorAuthentication") + } + if input.RequireTicketInformation { + enabledRules = append(enabledRules, "Ticketing") + } + + enablementRule := EnablementRule{ + Id: "Enablement_EndUser_Assignment", + RuleType: "RoleManagementPolicyEnablementRule", + + EnabledRules: enabledRules, + + Target: &Target{ + Caller: "EndUser", + Operations: []string{"All"}, + Level: "Assignment", + TargetObjects: nil, + InheritableSettings: nil, + EnforceSettings: nil, + }, + } + *output.Rules = append(*output.Rules, enablementRule) + + primaryApprovers := make([]PrimaryApprovers, 0) + + if input.Approvers != nil && len(input.Approvers) > 0 { + approvers := input.Approvers[0] + + if approvers.Groups != nil { + for _, approver := range approvers.Groups { + primaryApprovers = append(primaryApprovers, PrimaryApprovers{ + Id: approver.Id, + Description: approver.Name, + IsBackup: false, + UserType: "Group", + }) + } + } + + if approvers.Users != nil { + for _, approver := range approvers.Users { + primaryApprovers = append(primaryApprovers, PrimaryApprovers{ + Id: approver.Id, + Description: approver.Name, + IsBackup: false, + UserType: "User", + }) + } + } + } + + isApprovalRequired := len(primaryApprovers) > 0 + approvalStages := make([]ApprovalStages, 1) + approvalStages[0] = ApprovalStages{ + ApprovalStageTimeOutInDays: 1, + EscalationTimeInMinutes: 0, + IsEscalationEnabled: false, + IsApproverJustificationRequired: true, + PrimaryApprovers: &primaryApprovers, + } + approvalRule := ApprovalRule{ + Id: "Approval_EndUser_Assignment", + RuleType: "RoleManagementPolicyApprovalRule", + Setting: &Settings{ + ApprovalMode: "SingleStage", + IsApprovalRequired: isApprovalRequired, + IsApprovalRequiredForExtension: false, + IsRequestorJustificationRequired: true, + ApprovalStages: &approvalStages, + }, + Target: &Target{ + Caller: "EndUser", + Operations: []string{"All"}, + Level: "Assignment", + TargetObjects: nil, + InheritableSettings: nil, + EnforceSettings: nil, + }, + } + *output.Rules = append(*output.Rules, approvalRule) + + return nil +} + +func (r RoleManagementPolicyResource) mapRoleManagementPolicyResourceAssignmentSchemaToRoleManagementPolicyProperties(input RoleManagementPolicyResourceSchemaAssignment, output *rolemanagementpolicies.RoleManagementPolicyProperties) error { + if len(input.Active) == 1 { + if err := r.mapRoleManagementPolicyResourceSchemaAssignmentActiveToRoleManagementPolicyProperties(input.Active[0], output); err != nil { + return err + } + } + + if len(input.Eligible) == 1 { + if err := r.mapRoleManagementPolicyResourceSchemaAssignmentEligibleToRoleManagementPolicyProperties(input.Eligible[0], output); err != nil { + return err + } + } + + return nil +} + +func (r RoleManagementPolicyResource) mapRoleManagementPolicyResourceSchemaAssignmentActiveToRoleManagementPolicyProperties(input RoleManagementPolicyResourceSchemaAssignmentActive, output *rolemanagementpolicies.RoleManagementPolicyProperties) error { + maximumDuration := "" + if input.ExpireAfterDays > 0 { + maximumDuration = fmt.Sprintf("P%dD", input.ExpireAfterDays) + } else if input.ExpireAfterHours > 0 { + maximumDuration = fmt.Sprintf("PT%dH", input.ExpireAfterHours) + } + expirationRule := ExpirationRule{ + Id: "Expiration_Admin_Assignment", + RuleType: "RoleManagementPolicyExpirationRule", + MaximumDuration: maximumDuration, + IsExpirationRequired: !input.AllowPermanent, + Target: &Target{ + Caller: "Admin", + Operations: []string{"All"}, + Level: "Assignment", + TargetObjects: nil, + InheritableSettings: nil, + EnforceSettings: nil, + }, + } + *output.Rules = append(*output.Rules, expirationRule) + + enabledRules := make([]string, 0) + + if input.RequireJustification { + enabledRules = append(enabledRules, "Justification") + } + if input.RequireMultiFactorAuthentication { + enabledRules = append(enabledRules, "MultiFactorAuthentication") + } + + enablementRule := EnablementRule{ + Id: "Enablement_Admin_Assignment", + RuleType: "RoleManagementPolicyEnablementRule", + + EnabledRules: enabledRules, + + Target: &Target{ + Caller: "Admin", + Operations: []string{"All"}, + Level: "Assignment", + TargetObjects: nil, + InheritableSettings: nil, + EnforceSettings: nil, + }, + } + *output.Rules = append(*output.Rules, enablementRule) + + return nil +} + +func (r RoleManagementPolicyResource) mapRoleManagementPolicyResourceSchemaAssignmentEligibleToRoleManagementPolicyProperties(input RoleManagementPolicyResourceSchemaAssignmentEligible, output *rolemanagementpolicies.RoleManagementPolicyProperties) error { + maximumDuration := "" + if input.ExpireAfterDays > 0 { + maximumDuration = fmt.Sprintf("P%dD", input.ExpireAfterDays) + } else if input.ExpireAfterHours > 0 { + maximumDuration = fmt.Sprintf("PT%dH", input.ExpireAfterHours) + } + expirationRule := ExpirationRule{ + Id: "Expiration_Admin_Eligibility", + RuleType: "RoleManagementPolicyExpirationRule", + MaximumDuration: maximumDuration, + IsExpirationRequired: !input.AllowPermanent, + Target: &Target{ + Caller: "Admin", + Operations: []string{"All"}, + Level: "Eligibility", + TargetObjects: nil, + InheritableSettings: nil, + EnforceSettings: nil, + }, + } + *output.Rules = append(*output.Rules, expirationRule) + + return nil +} + +func (r RoleManagementPolicyResource) mapRoleManagementPolicyResourceSchemaNotificationsToRoleManagementPolicyProperties(input RoleManagementPolicyResourceSchemaNotifications, output *rolemanagementpolicies.RoleManagementPolicyProperties) error { + if len(input.MembersAssignedEligible) == 1 { + if err := r.mapRoleManagementPolicyResourceSchemaNotificationsEligibleToRoleManagementPolicyProperties(input.MembersAssignedEligible[0], "Eligibility", output); err != nil { + return err + } + } + if len(input.MembersAssignedActive) == 1 { + if err := r.mapRoleManagementPolicyResourceSchemaNotificationsEligibleToRoleManagementPolicyProperties(input.MembersAssignedActive[0], "Assignment", output); err != nil { + return err + } + } + if len(input.EligibleMemberActivate) == 1 { + if err := r.mapRoleManagementPolicyResourceSchemaNotificationsEligibleMemberActivateToRoleManagementPolicyProperties(input.EligibleMemberActivate[0], output); err != nil { + return err + } + } + + return nil +} + +func (r RoleManagementPolicyResource) mapRoleManagementPolicyResourceSchemaNotificationsEligibleToRoleManagementPolicyProperties(input RoleManagementPolicyResourceSchemaNotificationsEligible, level string, output *rolemanagementpolicies.RoleManagementPolicyProperties) error { + if len(input.RoleAssignmentAlert) == 1 { + if err := r.mapRoleManagementPolicyResourceSchemaNotificationToRoleManagementPolicyProperties(input.RoleAssignmentAlert[0], "Admin", "Admin", level, output); err != nil { + return err + } + } + if len(input.AssignedUser) == 1 { + if err := r.mapRoleManagementPolicyResourceSchemaNotificationToRoleManagementPolicyProperties(input.AssignedUser[0], "Requestor", "Admin", level, output); err != nil { + return err + } + } + if len(input.RequestForExtensionOrApproval) == 1 { + if err := r.mapRoleManagementPolicyResourceSchemaNotificationToRoleManagementPolicyProperties(input.RequestForExtensionOrApproval[0], "Approver", "Admin", level, output); err != nil { + return err + } + } + + return nil +} + +func (r RoleManagementPolicyResource) mapRoleManagementPolicyResourceSchemaNotificationsEligibleMemberActivateToRoleManagementPolicyProperties(input RoleManagementPolicyResourceSchemaNotificationsActivate, output *rolemanagementpolicies.RoleManagementPolicyProperties) error { + if len(input.RoleAssignmentAlert) == 1 { + if err := r.mapRoleManagementPolicyResourceSchemaNotificationToRoleManagementPolicyProperties(input.RoleAssignmentAlert[0], "Admin", "EndUser", "Assignment", output); err != nil { + return err + } + } + if len(input.AssignedUser) == 1 { + if err := r.mapRoleManagementPolicyResourceSchemaNotificationToRoleManagementPolicyProperties(input.AssignedUser[0], "Requestor", "EndUser", "Assignment", output); err != nil { + return err + } + } + if len(input.RequestForExtensionOrApproval) == 1 { + if err := r.mapRoleManagementPolicyResourceSchemaNotificationWithoutRecipientsToRoleManagementPolicyProperties(input.RequestForExtensionOrApproval[0], "Approver", "EndUser", "Assignment", output); err != nil { + return err + } + } + + return nil +} + +func (r RoleManagementPolicyResource) mapRoleManagementPolicyResourceSchemaNotificationToRoleManagementPolicyProperties(input RoleManagementPolicyResourceSchemaNotification, recipientType string, caller string, level string, output *rolemanagementpolicies.RoleManagementPolicyProperties) error { + id := fmt.Sprintf("Notification_%s_%s_%s", recipientType, caller, level) + notificationLevel := "All" + if input.CriticalEmailsOnly { + notificationLevel = "Critical" + } + + notificationRule := NotificationRule{ + Id: id, + RuleType: "RoleManagementPolicyNotificationRule", + NotificationRecipients: input.AdditionalRecipients, + RecipientType: recipientType, + NotificationLevel: notificationLevel, + NotificationType: "Email", + IsDefaultRecipientsEnabled: input.DefaultRecipients, + Target: &Target{ + Caller: caller, + Operations: []string{"All"}, + Level: level, + TargetObjects: nil, + InheritableSettings: nil, + EnforceSettings: nil, + }, + } + *output.Rules = append(*output.Rules, notificationRule) + + return nil +} + +func (r RoleManagementPolicyResource) mapRoleManagementPolicyResourceSchemaNotificationWithoutRecipientsToRoleManagementPolicyProperties(input RoleManagementPolicyResourceSchemaNotificationWithoutRecipients, recipientType string, caller string, level string, output *rolemanagementpolicies.RoleManagementPolicyProperties) error { + id := fmt.Sprintf("Notification_%s_%s_%s", recipientType, caller, level) + notificationLevel := "All" + if input.CriticalEmailsOnly { + notificationLevel = "Critical" + } + + notificationRule := NotificationRule{ + Id: id, + RuleType: "RoleManagementPolicyNotificationRule", + RecipientType: recipientType, + NotificationLevel: notificationLevel, + IsDefaultRecipientsEnabled: input.DefaultRecipients, + NotificationType: "Email", + Target: &Target{ + Caller: caller, + Operations: []string{"All"}, + Level: level, + TargetObjects: nil, + InheritableSettings: nil, + EnforceSettings: nil, + }, + } + *output.Rules = append(*output.Rules, notificationRule) + + return nil +} + +// functions to convert data from azure structs to terraform structs + +func (r RoleManagementPolicyResource) mapRoleManagementPolicyToRoleManagementPolicyResourceSchema(input rolemanagementpolicies.RoleManagementPolicy, output *RoleManagementPolicyResourceSchema, config *RoleManagementPolicyResourceSchema) error { + if input.Properties == nil { + input.Properties = &rolemanagementpolicies.RoleManagementPolicyProperties{} + } + if err := r.mapRoleManagementPolicyPropertiesToRoleManagementPolicyResourceSchema(input.Properties, output, config); err != nil { + return err + } + return nil +} + +func (r RoleManagementPolicyResource) mapRoleManagementPolicyPropertiesToRoleManagementPolicyResourceSchema(input *rolemanagementpolicies.RoleManagementPolicyProperties, output *RoleManagementPolicyResourceSchema, config *RoleManagementPolicyResourceSchema) error { + if config.Activation != nil && len(config.Activation) == 1 { + tmpActivation := &RoleManagementPolicyResourceSchemaActivation{} + if err := r.mapRoleManagementPolicyPropertiesToRoleManagementPolicyResourceSchemaActivation(input, tmpActivation, &config.Activation[0]); err != nil { + return err + } else { + output.Activation = make([]RoleManagementPolicyResourceSchemaActivation, 0) + output.Activation = append(output.Activation, *tmpActivation) + } + } + + if config.Assignment != nil && len(config.Assignment) == 1 { + tmpAssignment := &RoleManagementPolicyResourceSchemaAssignment{} + if err := r.mapRoleManagementPolicyPropertiesToRoleManagementPolicyResourceSchemaAssignment(input, tmpAssignment); err != nil { + return err + } else { + output.Assignment = make([]RoleManagementPolicyResourceSchemaAssignment, 0) + output.Assignment = append(output.Assignment, *tmpAssignment) + } + } + + if config.Notifications != nil && len(config.Notifications) == 1 { + tmpNotifications := &RoleManagementPolicyResourceSchemaNotifications{} + if err := r.mapRoleManagementPolicyPropertiesToRoleManagementPolicyResourceSchemaNotifications(input, tmpNotifications, &config.Notifications[0]); err != nil { + return err + } else { + output.Notifications = make([]RoleManagementPolicyResourceSchemaNotifications, 0) + output.Notifications = append(output.Notifications, *tmpNotifications) + } + } + + return nil +} + +func (r RoleManagementPolicyResource) mapRoleManagementPolicyPropertiesToRoleManagementPolicyResourceSchemaActivation(input *rolemanagementpolicies.RoleManagementPolicyProperties, output *RoleManagementPolicyResourceSchemaActivation, config *RoleManagementPolicyResourceSchemaActivation) error { + if input.Rules != nil { + for _, r := range *input.Rules { + rule := r.(rolemanagementpolicies.RawRoleManagementPolicyRuleImpl) + switch rule.Values["id"].(string) { + case "Expiration_EndUser_Assignment": + if config.MaximumDurationHours == 0 { + continue + } + + maximumDurationRaw := rule.Values["maximumDuration"].(string) + re := regexp.MustCompile(`\d+`) + maxDuration, err := strconv.Atoi(re.FindString(maximumDurationRaw)) + if err != nil { + return err + } + output.MaximumDurationHours = maxDuration + + case "Enablement_EndUser_Assignment": + enabledRules := rule.Values["enabledRules"].([]interface{}) + for _, r := range enabledRules { + switch r { + case "Justification": + output.RequireJustification = true + + case "MultiFactorAuthentication": + output.RequireMultiFactorAuthentication = true + + case "Ticketing": + output.RequireTicketInformation = true + } + } + case "Approval_EndUser_Assignment": + if config.Approvers == nil || len(config.Approvers) == 0 { + continue + } + + output.Approvers = make([]RoleManagementPolicyResourceSchemaApprovers, 1) + approvers := &RoleManagementPolicyResourceSchemaApprovers{} + approvers.Groups = make([]RoleManagementPolicyResourceSchemaApproversApprover, 0) + approvers.Users = make([]RoleManagementPolicyResourceSchemaApproversApprover, 0) + + setting := rule.Values["setting"].(map[string]interface{}) + approvalStages := setting["approvalStages"].([]interface{}) + if len(approvalStages) == 1 { + approvalStage := approvalStages[0].(map[string]interface{}) + if approvalStage["primaryApprovers"] != nil { + for _, approver := range approvalStage["primaryApprovers"].([]interface{}) { + approverMap := approver.(map[string]interface{}) + switch approverMap["userType"] { + case "User": + approvers.Users = append(approvers.Users, RoleManagementPolicyResourceSchemaApproversApprover{ + Id: approverMap["id"].(string), + Name: approverMap["description"].(string), + }) + case "Group": + approvers.Groups = append(approvers.Groups, RoleManagementPolicyResourceSchemaApproversApprover{ + Id: approverMap["id"].(string), + Name: approverMap["description"].(string), + }) + } + } + } + } + output.Approvers[0] = *approvers + } + } + } + return nil +} + +func (r RoleManagementPolicyResource) mapRoleManagementPolicyPropertiesToRoleManagementPolicyResourceSchemaAssignment(input *rolemanagementpolicies.RoleManagementPolicyProperties, output *RoleManagementPolicyResourceSchemaAssignment) error { + tmpActive := &RoleManagementPolicyResourceSchemaAssignmentActive{} + tmpEligible := &RoleManagementPolicyResourceSchemaAssignmentEligible{} + + if input.Rules != nil { + for _, r := range *input.Rules { + rule := r.(rolemanagementpolicies.RawRoleManagementPolicyRuleImpl) + switch rule.Values["id"].(string) { + case "Expiration_Admin_Eligibility": + maximumDurationRaw := rule.Values["maximumDuration"].(string) + reHours := regexp.MustCompile(`PT(\d+)H`) + hours := reHours.FindStringSubmatch(maximumDurationRaw) + if len(hours) == 2 { + maxDurationHours, err := strconv.Atoi(hours[1]) + if err != nil { + return err + } + tmpEligible.ExpireAfterHours = maxDurationHours + } + reDays := regexp.MustCompile(`P(\d+)D`) + days := reDays.FindStringSubmatch(maximumDurationRaw) + if len(days) == 2 { + maxDurationDays, err := strconv.Atoi(days[1]) + if err != nil { + return err + } + tmpEligible.ExpireAfterDays = maxDurationDays + } + + tmpEligible.AllowPermanent = !rule.Values["isExpirationRequired"].(bool) + + case "Expiration_Admin_Assignment": + maximumDurationRaw := rule.Values["maximumDuration"].(string) + reHours := regexp.MustCompile(`PT(\d+)H`) + hours := reHours.FindStringSubmatch(maximumDurationRaw) + if len(hours) == 2 { + maxDurationHours, err := strconv.Atoi(hours[1]) + if err != nil { + return err + } + tmpActive.ExpireAfterHours = maxDurationHours + } + reDays := regexp.MustCompile(`P(\d+)D`) + days := reDays.FindStringSubmatch(maximumDurationRaw) + if len(days) == 2 { + maxDurationDays, err := strconv.Atoi(days[1]) + if err != nil { + return err + } + tmpActive.ExpireAfterDays = maxDurationDays + } + + tmpActive.AllowPermanent = !rule.Values["isExpirationRequired"].(bool) + + case "Enablement_Admin_Assignment": + enabledRules := rule.Values["enabledRules"].([]interface{}) + for _, r := range enabledRules { + switch r { + case "Justification": + tmpActive.RequireJustification = true + + case "MultiFactorAuthentication": + tmpActive.RequireMultiFactorAuthentication = true + } + } + + } + } + } + + output.Active = make([]RoleManagementPolicyResourceSchemaAssignmentActive, 0) + output.Active = append(output.Active, *tmpActive) + + output.Eligible = make([]RoleManagementPolicyResourceSchemaAssignmentEligible, 0) + output.Eligible = append(output.Eligible, *tmpEligible) + + return nil +} + +func (r RoleManagementPolicyResource) mapRoleManagementPolicyPropertiesToRoleManagementPolicyResourceSchemaNotifications(input *rolemanagementpolicies.RoleManagementPolicyProperties, output *RoleManagementPolicyResourceSchemaNotifications, config *RoleManagementPolicyResourceSchemaNotifications) error { + var tmpMembersAssignedEligible *RoleManagementPolicyResourceSchemaNotificationsEligible + var tmpMembersAssignedActive *RoleManagementPolicyResourceSchemaNotificationsEligible + var tmpEligibleMemberActivate *RoleManagementPolicyResourceSchemaNotificationsActivate + + if config.MembersAssignedEligible != nil && len(config.MembersAssignedEligible) == 1 { + tmpMembersAssignedEligible = &RoleManagementPolicyResourceSchemaNotificationsEligible{} + } + if config.MembersAssignedActive != nil && len(config.MembersAssignedActive) == 1 { + tmpMembersAssignedActive = &RoleManagementPolicyResourceSchemaNotificationsEligible{} + } + if config.EligibleMemberActivate != nil && len(config.EligibleMemberActivate) == 1 { + tmpEligibleMemberActivate = &RoleManagementPolicyResourceSchemaNotificationsActivate{} + } + + if input.Rules != nil { + for _, r := range *input.Rules { + rule := r.(rolemanagementpolicies.RawRoleManagementPolicyRuleImpl) + + if rule.Values["ruleType"].(string) != "RoleManagementPolicyNotificationRule" { + continue + } + + notificationLevel := rule.Values["notificationLevel"].(string) + criticalEmailsOnly := false + if notificationLevel == "Critical" { + criticalEmailsOnly = true + } + + notificationRecipients := rule.Values["notificationRecipients"] + additionalRecipients := make([]string, 0) + if notificationRecipients != nil { + for _, rec := range notificationRecipients.([]interface{}) { + additionalRecipients = append(additionalRecipients, rec.(string)) + } + } + + switch rule.Values["id"].(string) { + + case "Notification_Admin_Admin_Eligibility": + if config.MembersAssignedEligible != nil && len(config.MembersAssignedEligible) == 1 && config.MembersAssignedEligible[0].RoleAssignmentAlert != nil && len(config.MembersAssignedEligible[0].RoleAssignmentAlert) == 1 { + tmpMembersAssignedEligible.RoleAssignmentAlert = make([]RoleManagementPolicyResourceSchemaNotification, 1) + tmpMembersAssignedEligible.RoleAssignmentAlert[0].AdditionalRecipients = additionalRecipients + tmpMembersAssignedEligible.RoleAssignmentAlert[0].CriticalEmailsOnly = criticalEmailsOnly + tmpMembersAssignedEligible.RoleAssignmentAlert[0].DefaultRecipients = rule.Values["isDefaultRecipientsEnabled"].(bool) + } + + case "Notification_Requestor_Admin_Eligibility": + if config.MembersAssignedEligible != nil && len(config.MembersAssignedEligible) == 1 && config.MembersAssignedEligible[0].AssignedUser != nil && len(config.MembersAssignedEligible[0].AssignedUser) == 1 { + tmpMembersAssignedEligible.AssignedUser = make([]RoleManagementPolicyResourceSchemaNotification, 1) + tmpMembersAssignedEligible.AssignedUser[0].AdditionalRecipients = additionalRecipients + tmpMembersAssignedEligible.AssignedUser[0].CriticalEmailsOnly = criticalEmailsOnly + tmpMembersAssignedEligible.AssignedUser[0].DefaultRecipients = rule.Values["isDefaultRecipientsEnabled"].(bool) + } + + case "Notification_Approver_Admin_Eligibility": + if config.MembersAssignedEligible != nil && len(config.MembersAssignedEligible) == 1 && config.MembersAssignedEligible[0].RequestForExtensionOrApproval != nil && len(config.MembersAssignedEligible[0].RequestForExtensionOrApproval) == 1 { + tmpMembersAssignedEligible.RequestForExtensionOrApproval = make([]RoleManagementPolicyResourceSchemaNotification, 1) + tmpMembersAssignedEligible.RequestForExtensionOrApproval[0].AdditionalRecipients = additionalRecipients + tmpMembersAssignedEligible.RequestForExtensionOrApproval[0].CriticalEmailsOnly = criticalEmailsOnly + tmpMembersAssignedEligible.RequestForExtensionOrApproval[0].DefaultRecipients = rule.Values["isDefaultRecipientsEnabled"].(bool) + } + + case "Notification_Admin_Admin_Assignment": + if config.MembersAssignedActive != nil && len(config.MembersAssignedActive) == 1 && config.MembersAssignedActive[0].RoleAssignmentAlert != nil && len(config.MembersAssignedActive[0].RoleAssignmentAlert) == 1 { + tmpMembersAssignedActive.RoleAssignmentAlert = make([]RoleManagementPolicyResourceSchemaNotification, 1) + tmpMembersAssignedActive.RoleAssignmentAlert[0].AdditionalRecipients = additionalRecipients + tmpMembersAssignedActive.RoleAssignmentAlert[0].CriticalEmailsOnly = criticalEmailsOnly + tmpMembersAssignedActive.RoleAssignmentAlert[0].DefaultRecipients = rule.Values["isDefaultRecipientsEnabled"].(bool) + } + + case "Notification_Requestor_Admin_Assignment": + if config.MembersAssignedActive != nil && len(config.MembersAssignedActive) == 1 && config.MembersAssignedActive[0].AssignedUser != nil && len(config.MembersAssignedActive[0].AssignedUser) == 1 { + tmpMembersAssignedActive.AssignedUser = make([]RoleManagementPolicyResourceSchemaNotification, 1) + tmpMembersAssignedActive.AssignedUser[0].AdditionalRecipients = additionalRecipients + tmpMembersAssignedActive.AssignedUser[0].CriticalEmailsOnly = criticalEmailsOnly + tmpMembersAssignedActive.AssignedUser[0].DefaultRecipients = rule.Values["isDefaultRecipientsEnabled"].(bool) + } + + case "Notification_Approver_Admin_Assignment": + if config.MembersAssignedActive != nil && len(config.MembersAssignedActive) == 1 && config.MembersAssignedActive[0].RequestForExtensionOrApproval != nil && len(config.MembersAssignedActive[0].RequestForExtensionOrApproval) == 1 { + tmpMembersAssignedActive.RequestForExtensionOrApproval = make([]RoleManagementPolicyResourceSchemaNotification, 1) + tmpMembersAssignedActive.RequestForExtensionOrApproval[0].AdditionalRecipients = additionalRecipients + tmpMembersAssignedActive.RequestForExtensionOrApproval[0].CriticalEmailsOnly = criticalEmailsOnly + tmpMembersAssignedActive.RequestForExtensionOrApproval[0].DefaultRecipients = rule.Values["isDefaultRecipientsEnabled"].(bool) + } + + case "Notification_Admin_EndUser_Assignment": + if config.EligibleMemberActivate != nil && len(config.EligibleMemberActivate) == 1 && config.EligibleMemberActivate[0].RoleAssignmentAlert != nil && len(config.EligibleMemberActivate[0].RoleAssignmentAlert) == 1 { + tmpEligibleMemberActivate.RoleAssignmentAlert = make([]RoleManagementPolicyResourceSchemaNotification, 1) + tmpEligibleMemberActivate.RoleAssignmentAlert[0].AdditionalRecipients = additionalRecipients + tmpEligibleMemberActivate.RoleAssignmentAlert[0].CriticalEmailsOnly = criticalEmailsOnly + tmpEligibleMemberActivate.RoleAssignmentAlert[0].DefaultRecipients = rule.Values["isDefaultRecipientsEnabled"].(bool) + } + + case "Notification_Requestor_EndUser_Assignment": + if config.EligibleMemberActivate != nil && len(config.EligibleMemberActivate) == 1 && config.EligibleMemberActivate[0].AssignedUser != nil && len(config.EligibleMemberActivate[0].AssignedUser) == 1 { + tmpEligibleMemberActivate.AssignedUser = make([]RoleManagementPolicyResourceSchemaNotification, 1) + tmpEligibleMemberActivate.AssignedUser[0].AdditionalRecipients = additionalRecipients + tmpEligibleMemberActivate.AssignedUser[0].CriticalEmailsOnly = criticalEmailsOnly + tmpEligibleMemberActivate.AssignedUser[0].DefaultRecipients = rule.Values["isDefaultRecipientsEnabled"].(bool) + } + + case "Notification_Approver_EndUser_Assignment": + if config.EligibleMemberActivate != nil && len(config.EligibleMemberActivate) == 1 && config.EligibleMemberActivate[0].RequestForExtensionOrApproval != nil && len(config.EligibleMemberActivate[0].RequestForExtensionOrApproval) == 1 { + tmpEligibleMemberActivate.RequestForExtensionOrApproval = make([]RoleManagementPolicyResourceSchemaNotificationWithoutRecipients, 1) + tmpEligibleMemberActivate.RequestForExtensionOrApproval[0].CriticalEmailsOnly = criticalEmailsOnly + tmpEligibleMemberActivate.RequestForExtensionOrApproval[0].DefaultRecipients = rule.Values["isDefaultRecipientsEnabled"].(bool) + } + + } + + } + } + + if tmpMembersAssignedEligible != nil { + output.MembersAssignedEligible = make([]RoleManagementPolicyResourceSchemaNotificationsEligible, 0) + output.MembersAssignedEligible = append(output.MembersAssignedEligible, *tmpMembersAssignedEligible) + } + if tmpMembersAssignedActive != nil { + output.MembersAssignedActive = make([]RoleManagementPolicyResourceSchemaNotificationsEligible, 0) + output.MembersAssignedActive = append(output.MembersAssignedActive, *tmpMembersAssignedActive) + } + if tmpEligibleMemberActivate != nil { + output.EligibleMemberActivate = make([]RoleManagementPolicyResourceSchemaNotificationsActivate, 0) + output.EligibleMemberActivate = append(output.EligibleMemberActivate, *tmpEligibleMemberActivate) + } + return nil +} + +type RoleManagementPolicyResourceSchema struct { + RoleDefinitionID string `tfschema:"role_definition_id"` + Scope string `tfschema:"scope"` + Activation []RoleManagementPolicyResourceSchemaActivation `tfschema:"activation"` + Assignment []RoleManagementPolicyResourceSchemaAssignment `tfschema:"assignment"` + Notifications []RoleManagementPolicyResourceSchemaNotifications `tfschema:"notifications"` +} + +type RoleManagementPolicyResourceSchemaActivation struct { + MaximumDurationHours int `tfschema:"maximum_duration_hours"` + RequireMultiFactorAuthentication bool `tfschema:"require_multi_factor_authentication"` + RequireJustification bool `tfschema:"require_justification"` + RequireTicketInformation bool `tfschema:"require_ticket_information"` + Approvers []RoleManagementPolicyResourceSchemaApprovers `tfschema:"approvers"` +} + +type RoleManagementPolicyResourceSchemaApprovers struct { + Groups []RoleManagementPolicyResourceSchemaApproversApprover `tfschema:"group"` + Users []RoleManagementPolicyResourceSchemaApproversApprover `tfschema:"user"` +} + +type RoleManagementPolicyResourceSchemaApproversApprover struct { + Id string `tfschema:"id"` + Name string `tfschema:"name"` +} + +type RoleManagementPolicyResourceSchemaAssignment struct { + Active []RoleManagementPolicyResourceSchemaAssignmentActive `tfschema:"active"` + Eligible []RoleManagementPolicyResourceSchemaAssignmentEligible `tfschema:"eligible"` +} + +type RoleManagementPolicyResourceSchemaAssignmentActive struct { + AllowPermanent bool `tfschema:"allow_permanent"` + ExpireAfterDays int `tfschema:"expire_after_days"` + ExpireAfterHours int `tfschema:"expire_after_hours"` + RequireMultiFactorAuthentication bool `tfschema:"require_multi_factor_authentication"` + RequireJustification bool `tfschema:"require_justification"` +} + +type RoleManagementPolicyResourceSchemaAssignmentEligible struct { + AllowPermanent bool `tfschema:"allow_permanent"` + ExpireAfterDays int `tfschema:"expire_after_days"` + ExpireAfterHours int `tfschema:"expire_after_hours"` +} + +type RoleManagementPolicyResourceSchemaNotifications struct { + MembersAssignedEligible []RoleManagementPolicyResourceSchemaNotificationsEligible `tfschema:"member_assigned_eligible"` + MembersAssignedActive []RoleManagementPolicyResourceSchemaNotificationsEligible `tfschema:"member_assigned_active"` + EligibleMemberActivate []RoleManagementPolicyResourceSchemaNotificationsActivate `tfschema:"eligible_member_activate"` +} + +type RoleManagementPolicyResourceSchemaNotificationsEligible struct { + RoleAssignmentAlert []RoleManagementPolicyResourceSchemaNotification `tfschema:"role_assignment_alert"` + AssignedUser []RoleManagementPolicyResourceSchemaNotification `tfschema:"assigned_user"` + RequestForExtensionOrApproval []RoleManagementPolicyResourceSchemaNotification `tfschema:"request_for_extension_or_approval"` +} + +type RoleManagementPolicyResourceSchemaNotificationsActivate struct { + RoleAssignmentAlert []RoleManagementPolicyResourceSchemaNotification `tfschema:"role_assignment_alert"` + AssignedUser []RoleManagementPolicyResourceSchemaNotification `tfschema:"assigned_user"` + RequestForExtensionOrApproval []RoleManagementPolicyResourceSchemaNotificationWithoutRecipients `tfschema:"request_for_extension_or_approval"` +} + +type RoleManagementPolicyResourceSchemaNotification struct { + AdditionalRecipients []string `tfschema:"additional_recipients"` + CriticalEmailsOnly bool `tfschema:"critical_emails_only"` + DefaultRecipients bool `tfschema:"default_recipients"` +} + +type RoleManagementPolicyResourceSchemaNotificationWithoutRecipients struct { + CriticalEmailsOnly bool `tfschema:"critical_emails_only"` + DefaultRecipients bool `tfschema:"default_recipients"` +} + +type ApprovalRule struct { + Id string `json:"id"` + RuleType string `json:"ruleType"` + Target *Target `json:"target"` + + Setting *Settings `json:"setting"` +} + +type ExpirationRule struct { + Id string `json:"id"` + RuleType string `json:"ruleType"` + Target *Target `json:"target"` + + IsExpirationRequired bool `json:"isExpirationRequired"` + MaximumDuration string `json:"maximumDuration"` +} + +type EnablementRule struct { + Id string `json:"id"` + RuleType string `json:"ruleType"` + Target *Target `json:"target"` + + EnabledRules []string `json:"enabledRules"` +} + +type NotificationRule struct { + Id string `json:"id"` + RuleType string `json:"ruleType"` + Target *Target `json:"target"` + + NotificationType string `json:"notificationType"` + RecipientType string `json:"recipientType"` + IsDefaultRecipientsEnabled bool `json:"isDefaultRecipientsEnabled"` + NotificationLevel string `json:"notificationLevel"` + NotificationRecipients []string `json:"notificationRecipients"` +} + +type Target struct { + Caller string `json:"caller"` + Operations []string `json:"operations"` + Level string `json:"level"` + TargetObjects interface{} `json:"targetObjects"` + InheritableSettings interface{} `json:"inheritableSettings"` + EnforceSettings interface{} `json:"enforceSettings"` +} + +type Settings struct { + ApprovalMode string `json:"approvalMode"` + IsApprovalRequired bool `json:"isApprovalRequired"` + IsApprovalRequiredForExtension bool `json:"isApprovalRequiredForExtension"` + IsRequestorJustificationRequired bool `json:"isRequestorJustificationRequired"` + ApprovalStages *[]ApprovalStages `json:"approvalStages"` +} + +type ApprovalStages struct { + ApprovalStageTimeOutInDays int `json:"approvalStageTimeOutInDays"` + EscalationTimeInMinutes int `json:"escalationTimeInMinutes"` + IsApproverJustificationRequired bool `json:"isApproverJustificationRequired"` + IsEscalationEnabled bool `json:"isEscalationEnabled"` + PrimaryApprovers *[]PrimaryApprovers `json:"primaryApprovers"` +} + +type PrimaryApprovers struct { + Id string `json:"id"` + Description string `json:"description"` + IsBackup bool `json:"isBackup"` + UserType string `json:"userType"` +} diff --git a/internal/services/authorization/role_management_policy_test.go b/internal/services/authorization/role_management_policy_test.go new file mode 100644 index 0000000000000..d7cd3bf4641b7 --- /dev/null +++ b/internal/services/authorization/role_management_policy_test.go @@ -0,0 +1,861 @@ +package authorization_test + +import ( + "context" + "fmt" + "testing" + + "github.com/hashicorp/go-azure-helpers/lang/response" + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" + "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/authorization/parse" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" + "github.com/hashicorp/terraform-provider-azurerm/utils" +) + +type RoleManagementPolicyResource struct{} + +func TestAccRoleManagementPolicy_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_role_management_policy", "test") + r := RoleManagementPolicyResource{} + + data.ResourceTestSkipCheckDestroyed(t, []acceptance.TestStep{ + { + Config: r.basic(), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("scope").Exists(), + check.That(data.ResourceName).Key("role_definition_id").Exists(), + check.That(data.ResourceName).Key("activation.0.maximum_duration_hours").HasValue("12"), + ), + }, + }) +} + +func TestAccRoleManagementPolicy_partial(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_role_management_policy", "test") + r := RoleManagementPolicyResource{} + ri := acceptance.RandTimeInt() + rPassword := fmt.Sprintf("%s%s", "p@$$Wd", acceptance.RandString(6)) + + data.ResourceTestSkipCheckDestroyed(t, []acceptance.TestStep{ + { + Config: r.partial1(ri), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("scope").Exists(), + check.That(data.ResourceName).Key("role_definition_id").Exists(), + + check.That(data.ResourceName).Key("activation.0.require_multi_factor_authentication").HasValue("true"), + + check.That(data.ResourceName).Key("assignment.0.eligible.0.expire_after_hours").HasValue("6"), + check.That(data.ResourceName).Key("assignment.0.active.0.expire_after_hours").HasValue("5"), + + check.That(data.ResourceName).Key("notifications.0.member_assigned_eligible.0.role_assignment_alert.0.default_recipients").HasValue("false"), + + check.That(data.ResourceName).Key("notifications.0.member_assigned_active.0.role_assignment_alert.0.default_recipients").HasValue("false"), + check.That(data.ResourceName).Key("notifications.0.member_assigned_active.0.role_assignment_alert.0.additional_recipients.#").HasValue("1"), + check.That(data.ResourceName).Key("notifications.0.member_assigned_active.0.role_assignment_alert.0.critical_emails_only").HasValue("false"), + + check.That(data.ResourceName).Key("activation.0.approvers.0.group.#").HasValue("1"), + check.That(data.ResourceName).Key("activation.0.approvers.0.user.#").HasValue("0"), + ), + }, + { + Config: r.partial2(ri, rPassword), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("scope").Exists(), + check.That(data.ResourceName).Key("role_definition_id").Exists(), + + check.That(data.ResourceName).Key("activation.0.require_justification").HasValue("true"), + check.That(data.ResourceName).Key("activation.0.require_multi_factor_authentication").HasValue("true"), + + check.That(data.ResourceName).Key("assignment.0.eligible.0.expire_after_days").HasValue("7"), + check.That(data.ResourceName).Key("assignment.0.active.0.expire_after_days").HasValue("4"), + check.That(data.ResourceName).Key("assignment.0.active.0.require_justification").HasValue("true"), + check.That(data.ResourceName).Key("assignment.0.active.0.require_multi_factor_authentication").HasValue("true"), + + check.That(data.ResourceName).Key("notifications.0.member_assigned_eligible.0.role_assignment_alert.0.default_recipients").HasValue("false"), + check.That(data.ResourceName).Key("notifications.0.member_assigned_eligible.0.role_assignment_alert.0.critical_emails_only").HasValue("false"), + + check.That(data.ResourceName).Key("notifications.0.member_assigned_active.0.role_assignment_alert.0.default_recipients").HasValue("false"), + check.That(data.ResourceName).Key("notifications.0.member_assigned_active.0.role_assignment_alert.0.additional_recipients.#").HasValue("1"), + check.That(data.ResourceName).Key("notifications.0.member_assigned_active.0.role_assignment_alert.0.critical_emails_only").HasValue("false"), + + check.That(data.ResourceName).Key("notifications.0.eligible_member_activate.0.role_assignment_alert.0.default_recipients").HasValue("false"), + check.That(data.ResourceName).Key("notifications.0.eligible_member_activate.0.role_assignment_alert.0.additional_recipients.#").HasValue("1"), + check.That(data.ResourceName).Key("notifications.0.eligible_member_activate.0.role_assignment_alert.0.critical_emails_only").HasValue("false"), + + check.That(data.ResourceName).Key("activation.0.approvers.0.group.#").HasValue("0"), + check.That(data.ResourceName).Key("activation.0.approvers.0.user.#").HasValue("1"), + ), + }, + }) +} + +func TestAccRoleManagementPolicy_managementGroup(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_role_management_policy", "test") + r := RoleManagementPolicyResource{} + + data.ResourceTestSkipCheckDestroyed(t, []acceptance.TestStep{ + { + Config: r.managementGroup(), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("scope").Exists(), + check.That(data.ResourceName).Key("role_definition_id").Exists(), + check.That(data.ResourceName).Key("activation.0.maximum_duration_hours").HasValue("12"), + ), + }, + }) +} + +func TestAccRoleManagementPolicy_complete(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_role_management_policy", "test") + r := RoleManagementPolicyResource{} + ri := acceptance.RandTimeInt() + rPassword := fmt.Sprintf("%s%s", "p@$$Wd", acceptance.RandString(6)) + + data.ResourceTestSkipCheckDestroyed(t, []acceptance.TestStep{ + { + Config: r.basic(), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("scope").Exists(), + check.That(data.ResourceName).Key("role_definition_id").Exists(), + check.That(data.ResourceName).Key("activation.0.maximum_duration_hours").HasValue("12"), + ), + }, + { + Config: r.complete(ri, rPassword), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("scope").Exists(), + check.That(data.ResourceName).Key("role_definition_id").Exists(), + + check.That(data.ResourceName).Key("activation.0.maximum_duration_hours").HasValue("4"), + check.That(data.ResourceName).Key("activation.0.require_multi_factor_authentication").HasValue("true"), + check.That(data.ResourceName).Key("activation.0.require_justification").HasValue("true"), + check.That(data.ResourceName).Key("activation.0.require_ticket_information").HasValue("true"), + check.That(data.ResourceName).Key("activation.0.require_ticket_information").HasValue("true"), + check.That(data.ResourceName).Key("activation.0.approvers.0.group.#").HasValue("2"), + check.That(data.ResourceName).Key("activation.0.approvers.0.user.#").HasValue("2"), + + check.That(data.ResourceName).Key("assignment.0.eligible.0.allow_permanent").HasValue("true"), + check.That(data.ResourceName).Key("assignment.0.active.0.allow_permanent").HasValue("true"), + check.That(data.ResourceName).Key("assignment.0.active.0.require_multi_factor_authentication").HasValue("true"), + check.That(data.ResourceName).Key("assignment.0.active.0.require_justification").HasValue("true"), + + check.That(data.ResourceName).Key("notifications.0.member_assigned_eligible.0.role_assignment_alert.0.default_recipients").HasValue("true"), + check.That(data.ResourceName).Key("notifications.0.member_assigned_eligible.0.role_assignment_alert.0.additional_recipients.#").HasValue("1"), + check.That(data.ResourceName).Key("notifications.0.member_assigned_eligible.0.role_assignment_alert.0.critical_emails_only").HasValue("true"), + check.That(data.ResourceName).Key("notifications.0.member_assigned_eligible.0.assigned_user.0.default_recipients").HasValue("true"), + check.That(data.ResourceName).Key("notifications.0.member_assigned_eligible.0.assigned_user.0.additional_recipients.#").HasValue("1"), + check.That(data.ResourceName).Key("notifications.0.member_assigned_eligible.0.assigned_user.0.critical_emails_only").HasValue("true"), + check.That(data.ResourceName).Key("notifications.0.member_assigned_eligible.0.request_for_extension_or_approval.0.default_recipients").HasValue("true"), + check.That(data.ResourceName).Key("notifications.0.member_assigned_eligible.0.request_for_extension_or_approval.0.additional_recipients.#").HasValue("1"), + check.That(data.ResourceName).Key("notifications.0.member_assigned_eligible.0.request_for_extension_or_approval.0.critical_emails_only").HasValue("true"), + + check.That(data.ResourceName).Key("notifications.0.member_assigned_active.0.role_assignment_alert.0.default_recipients").HasValue("true"), + check.That(data.ResourceName).Key("notifications.0.member_assigned_active.0.role_assignment_alert.0.additional_recipients.#").HasValue("1"), + check.That(data.ResourceName).Key("notifications.0.member_assigned_active.0.role_assignment_alert.0.critical_emails_only").HasValue("true"), + check.That(data.ResourceName).Key("notifications.0.member_assigned_active.0.assigned_user.0.default_recipients").HasValue("true"), + check.That(data.ResourceName).Key("notifications.0.member_assigned_active.0.assigned_user.0.additional_recipients.#").HasValue("1"), + check.That(data.ResourceName).Key("notifications.0.member_assigned_active.0.assigned_user.0.critical_emails_only").HasValue("true"), + check.That(data.ResourceName).Key("notifications.0.member_assigned_active.0.request_for_extension_or_approval.0.default_recipients").HasValue("true"), + check.That(data.ResourceName).Key("notifications.0.member_assigned_active.0.request_for_extension_or_approval.0.additional_recipients.#").HasValue("1"), + check.That(data.ResourceName).Key("notifications.0.member_assigned_active.0.request_for_extension_or_approval.0.critical_emails_only").HasValue("true"), + + check.That(data.ResourceName).Key("notifications.0.eligible_member_activate.0.role_assignment_alert.0.default_recipients").HasValue("true"), + check.That(data.ResourceName).Key("notifications.0.eligible_member_activate.0.role_assignment_alert.0.additional_recipients.#").HasValue("1"), + check.That(data.ResourceName).Key("notifications.0.eligible_member_activate.0.role_assignment_alert.0.critical_emails_only").HasValue("true"), + check.That(data.ResourceName).Key("notifications.0.eligible_member_activate.0.assigned_user.0.default_recipients").HasValue("true"), + check.That(data.ResourceName).Key("notifications.0.eligible_member_activate.0.assigned_user.0.additional_recipients.#").HasValue("1"), + check.That(data.ResourceName).Key("notifications.0.eligible_member_activate.0.assigned_user.0.critical_emails_only").HasValue("true"), + check.That(data.ResourceName).Key("notifications.0.eligible_member_activate.0.request_for_extension_or_approval.0.default_recipients").HasValue("true"), + check.That(data.ResourceName).Key("notifications.0.eligible_member_activate.0.request_for_extension_or_approval.0.critical_emails_only").HasValue("true"), + ), + }, + { + Config: r.basic(), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("scope").Exists(), + check.That(data.ResourceName).Key("role_definition_id").Exists(), + check.That(data.ResourceName).Key("activation.0.maximum_duration_hours").HasValue("12"), + check.That(data.ResourceName).Key("activation.0.approvers.0.group.#").HasValue("0"), + check.That(data.ResourceName).Key("activation.0.approvers.0.user.#").HasValue("0"), + ), + }, + }) +} + +func TestAccRoleManagementPolicy_allOff(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_role_management_policy", "test") + r := RoleManagementPolicyResource{} + + data.ResourceTestSkipCheckDestroyed(t, []acceptance.TestStep{ + { + Config: r.allOff(), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("scope").Exists(), + check.That(data.ResourceName).Key("role_definition_id").Exists(), + + check.That(data.ResourceName).Key("activation.0.maximum_duration_hours").HasValue("3"), + check.That(data.ResourceName).Key("activation.0.require_multi_factor_authentication").HasValue("false"), + check.That(data.ResourceName).Key("activation.0.require_justification").HasValue("false"), + check.That(data.ResourceName).Key("activation.0.require_ticket_information").HasValue("false"), + check.That(data.ResourceName).Key("activation.0.approvers.0.group.#").HasValue("0"), + check.That(data.ResourceName).Key("activation.0.approvers.0.user.#").HasValue("0"), + + check.That(data.ResourceName).Key("assignment.0.eligible.0.expire_after_hours").HasValue("3"), + check.That(data.ResourceName).Key("assignment.0.active.0.expire_after_days").HasValue("15"), + check.That(data.ResourceName).Key("assignment.0.active.0.require_multi_factor_authentication").HasValue("false"), + check.That(data.ResourceName).Key("assignment.0.active.0.require_justification").HasValue("false"), + + check.That(data.ResourceName).Key("notifications.0.member_assigned_eligible.0.role_assignment_alert.0.default_recipients").HasValue("false"), + check.That(data.ResourceName).Key("notifications.0.member_assigned_eligible.0.role_assignment_alert.0.additional_recipients.#").HasValue("0"), + check.That(data.ResourceName).Key("notifications.0.member_assigned_eligible.0.role_assignment_alert.0.critical_emails_only").HasValue("false"), + check.That(data.ResourceName).Key("notifications.0.member_assigned_eligible.0.assigned_user.0.default_recipients").HasValue("false"), + check.That(data.ResourceName).Key("notifications.0.member_assigned_eligible.0.assigned_user.0.additional_recipients.#").HasValue("0"), + check.That(data.ResourceName).Key("notifications.0.member_assigned_eligible.0.assigned_user.0.critical_emails_only").HasValue("false"), + check.That(data.ResourceName).Key("notifications.0.member_assigned_eligible.0.request_for_extension_or_approval.0.default_recipients").HasValue("false"), + check.That(data.ResourceName).Key("notifications.0.member_assigned_eligible.0.request_for_extension_or_approval.0.additional_recipients.#").HasValue("0"), + check.That(data.ResourceName).Key("notifications.0.member_assigned_eligible.0.request_for_extension_or_approval.0.critical_emails_only").HasValue("false"), + + check.That(data.ResourceName).Key("notifications.0.member_assigned_active.0.role_assignment_alert.0.default_recipients").HasValue("false"), + check.That(data.ResourceName).Key("notifications.0.member_assigned_active.0.role_assignment_alert.0.additional_recipients.#").HasValue("0"), + check.That(data.ResourceName).Key("notifications.0.member_assigned_active.0.role_assignment_alert.0.critical_emails_only").HasValue("false"), + check.That(data.ResourceName).Key("notifications.0.member_assigned_active.0.assigned_user.0.default_recipients").HasValue("false"), + check.That(data.ResourceName).Key("notifications.0.member_assigned_active.0.assigned_user.0.additional_recipients.#").HasValue("0"), + check.That(data.ResourceName).Key("notifications.0.member_assigned_active.0.assigned_user.0.critical_emails_only").HasValue("false"), + check.That(data.ResourceName).Key("notifications.0.member_assigned_active.0.request_for_extension_or_approval.0.default_recipients").HasValue("false"), + check.That(data.ResourceName).Key("notifications.0.member_assigned_active.0.request_for_extension_or_approval.0.additional_recipients.#").HasValue("0"), + check.That(data.ResourceName).Key("notifications.0.member_assigned_active.0.request_for_extension_or_approval.0.critical_emails_only").HasValue("false"), + + check.That(data.ResourceName).Key("notifications.0.eligible_member_activate.0.role_assignment_alert.0.default_recipients").HasValue("false"), + check.That(data.ResourceName).Key("notifications.0.eligible_member_activate.0.role_assignment_alert.0.additional_recipients.#").HasValue("0"), + check.That(data.ResourceName).Key("notifications.0.eligible_member_activate.0.role_assignment_alert.0.critical_emails_only").HasValue("false"), + check.That(data.ResourceName).Key("notifications.0.eligible_member_activate.0.assigned_user.0.default_recipients").HasValue("false"), + check.That(data.ResourceName).Key("notifications.0.eligible_member_activate.0.assigned_user.0.additional_recipients.#").HasValue("0"), + check.That(data.ResourceName).Key("notifications.0.eligible_member_activate.0.assigned_user.0.critical_emails_only").HasValue("false"), + check.That(data.ResourceName).Key("notifications.0.eligible_member_activate.0.request_for_extension_or_approval.0.default_recipients").HasValue("false"), + check.That(data.ResourceName).Key("notifications.0.eligible_member_activate.0.request_for_extension_or_approval.0.critical_emails_only").HasValue("false"), + ), + }, + }) +} + +func TestAccRoleManagementPolicy_resourceGroup(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_role_management_policy", "test") + r := RoleManagementPolicyResource{} + ri := acceptance.RandTimeInt() + + data.ResourceTestSkipCheckDestroyed(t, []acceptance.TestStep{ + { + Config: r.resourceGroup(data, ri), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("scope").Exists(), + check.That(data.ResourceName).Key("role_definition_id").Exists(), + ), + }, + }) +} + +func TestAccRoleManagementPolicy_resource(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_role_management_policy", "test") + r := RoleManagementPolicyResource{} + ri := acceptance.RandTimeInt() + + data.ResourceTestSkipCheckDestroyed(t, []acceptance.TestStep{ + { + Config: r.resource(data, ri), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("scope").Exists(), + check.That(data.ResourceName).Key("role_definition_id").Exists(), + ), + }, + }) +} + +func (r RoleManagementPolicyResource) Exists(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { + id, err := parse.RoleManagementPolicyId(state.ID) + + if err != nil { + return nil, err + } + + resp, err := client.Authorization.RoleManagementPoliciesClient.Get(ctx, id.ScopedRoleManagementPolicyId()) + if err != nil { + if response.WasNotFound(resp.HttpResponse) { + return nil, nil + } + + return nil, fmt.Errorf("loading Role Management Policy %q: %+v", id, err) + } + + return utils.Bool(true), nil +} + +func (RoleManagementPolicyResource) basic() string { + return ` +provider "azurerm" { + features {} +} + +data "azurerm_subscription" "primary" {} + +data "azurerm_role_definition" "test" { + name = "Monitoring Reader" +} + +resource "azurerm_role_management_policy" "test" { + scope = data.azurerm_subscription.primary.id + role_definition_id = "${data.azurerm_subscription.primary.id}${data.azurerm_role_definition.test.id}" + + activation { + maximum_duration_hours = 12 + } +}` + +} + +func (RoleManagementPolicyResource) partial1(id int) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +data "azurerm_subscription" "primary" {} + +data "azurerm_role_definition" "test" { + name = "Backup Reader" +} + +resource "azuread_group" "test1" { + display_name = "acctest-group-%[1]d1" + security_enabled = true +} + +resource "azurerm_role_management_policy" "test" { + scope = data.azurerm_subscription.primary.id + role_definition_id = "${data.azurerm_subscription.primary.id}${data.azurerm_role_definition.test.id}" + + activation { + require_multi_factor_authentication = true + + approvers { + group { + name = azuread_group.test1.display_name + id = azuread_group.test1.id + } + } + } + + assignment { + eligible { + expire_after_hours = 6 + } + active { + expire_after_hours = 5 + require_multi_factor_authentication = true + } + } + + notifications { + member_assigned_eligible { + role_assignment_alert { + default_recipients = false + } + } + + member_assigned_active { + role_assignment_alert { + default_recipients = false + additional_recipients = ["role_assignment_alert@member_assigned_active.com"] + critical_emails_only = false + } + } + } +}`, id) + +} + +func (RoleManagementPolicyResource) partial2(id int, password string) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +data "azurerm_subscription" "primary" {} + +data "azurerm_role_definition" "test" { + name = "Backup Reader" +} + +data "azuread_client_config" "test" {} + +data "azuread_domains" "test" { + only_initial = true +} + +resource "azuread_user" "test1" { + user_principal_name = "acctestUser-%[1]d1@${data.azuread_domains.test.domains.0.domain_name}" + display_name = "acctestUser-%[1]d1" + password = "%[2]s" +} + +resource "azurerm_role_management_policy" "test" { + scope = data.azurerm_subscription.primary.id + role_definition_id = "${data.azurerm_subscription.primary.id}${data.azurerm_role_definition.test.id}" + + activation { + require_justification = true + + approvers { + user { + name = azuread_user.test1.display_name + id = azuread_user.test1.id + } + } + } + + assignment { + eligible { + expire_after_days = 7 + } + active { + expire_after_days = 4 + require_justification = true + } + } + + notifications { + member_assigned_eligible { + role_assignment_alert { + critical_emails_only = false + } + } + + eligible_member_activate { + role_assignment_alert { + default_recipients = false + additional_recipients = ["role_assignment_alert@eligible_member_activate.com"] + critical_emails_only = false + } + } + } +}`, id, password) + +} + +func (RoleManagementPolicyResource) managementGroup() string { + return ` +provider "azurerm" { + features {} +} + +data "azurerm_subscription" "primary" {} + +data "azurerm_role_definition" "test" { + name = "Monitoring Reader" +} + +resource "azurerm_management_group" "test" { +} + +resource "azurerm_role_management_policy" "test" { + scope = azurerm_management_group.test.id + role_definition_id = "${data.azurerm_subscription.primary.id}${data.azurerm_role_definition.test.id}" + + activation { + maximum_duration_hours = 12 + } +}` + +} + +func (RoleManagementPolicyResource) complete(id int, password string) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +data "azurerm_subscription" "primary" {} + +data "azurerm_role_definition" "test" { + name = "Monitoring Reader" +} + +data "azuread_client_config" "test" {} + +data "azuread_domains" "test" { + only_initial = true +} + +resource "azuread_user" "test1" { + user_principal_name = "acctestUser-%[1]d1@${data.azuread_domains.test.domains.0.domain_name}" + display_name = "acctestUser-%[1]d1" + password = "%[2]s" +} + +resource "azuread_user" "test2" { + user_principal_name = "acctestUser-%[1]d2@${data.azuread_domains.test.domains.0.domain_name}" + display_name = "acctestUser-%[1]d2" + password = "%[2]s" +} + +resource "azuread_group" "test1" { + display_name = "acctest-group-%[1]d1" + security_enabled = true +} + +resource "azuread_group" "test2" { + display_name = "acctest-group-%[1]d2" + security_enabled = true +} + +resource "azurerm_role_management_policy" "test" { + scope = data.azurerm_subscription.primary.id + role_definition_id = "${data.azurerm_subscription.primary.id}${data.azurerm_role_definition.test.id}" + + activation { + maximum_duration_hours = 4 + + require_multi_factor_authentication = true + require_justification = true + require_ticket_information = true + + approvers { + group { + name = azuread_group.test1.display_name + id = azuread_group.test1.id + } + group { + name = azuread_group.test2.display_name + id = azuread_group.test2.id + } + user { + name = azuread_user.test1.display_name + id = azuread_user.test1.id + } + user { + name = azuread_user.test2.display_name + id = azuread_user.test2.id + } + } + } + + assignment { + eligible { + allow_permanent = true + } + + active { + allow_permanent = true + require_multi_factor_authentication = true + require_justification = true + } + } + + notifications { + member_assigned_eligible { + role_assignment_alert { + default_recipients = true + additional_recipients = ["role_assignment_alert@member_assigned_eligible.com"] + critical_emails_only = true + } + assigned_user { + default_recipients = true + additional_recipients = ["assigned_user@member_assigned_eligible.com"] + critical_emails_only = true + } + request_for_extension_or_approval { + default_recipients = true + additional_recipients = ["request_for_extension_or_approval@member_assigned_eligible.com"] + critical_emails_only = true + } + } + member_assigned_active { + role_assignment_alert { + default_recipients = true + additional_recipients = ["role_assignment_alert@member_assigned_active.com"] + critical_emails_only = true + } + assigned_user { + default_recipients = true + additional_recipients = ["assigned_user@member_assigned_active.com"] + critical_emails_only = true + } + request_for_extension_or_approval { + default_recipients = true + additional_recipients = ["request_for_extension_or_approval@member_assigned_active.com"] + critical_emails_only = true + } + } + eligible_member_activate { + role_assignment_alert { + default_recipients = true + additional_recipients = ["role_assignment_alert@eligible_member_activate.com"] + critical_emails_only = true + } + assigned_user { + default_recipients = true + additional_recipients = ["assigned_user@eligible_member_activate.com"] + critical_emails_only = true + } + request_for_extension_or_approval { + default_recipients = true + critical_emails_only = true + } + } + } +} + +`, id, password) +} + +func (RoleManagementPolicyResource) allOff() string { + return ` +provider "azurerm" { + features {} +} + +data "azurerm_subscription" "primary" {} + +data "azurerm_role_definition" "test" { + name = "Reader" +} + +resource "azurerm_role_management_policy" "test" { + scope = data.azurerm_subscription.primary.id + role_definition_id = "${data.azurerm_subscription.primary.id}${data.azurerm_role_definition.test.id}" + + activation { + maximum_duration_hours = 3 + + require_multi_factor_authentication = false + require_justification = false + require_ticket_information = false + } + + assignment { + eligible { + expire_after_hours = 3 + } + + active { + expire_after_days = 15 + require_multi_factor_authentication = false + require_justification = false + } + } + + notifications { + member_assigned_eligible { + role_assignment_alert { + default_recipients = false + additional_recipients = [] + critical_emails_only = false + } + assigned_user { + default_recipients = false + additional_recipients = [] + critical_emails_only = false + } + request_for_extension_or_approval { + default_recipients = false + additional_recipients = [] + critical_emails_only = false + } + } + member_assigned_active { + role_assignment_alert { + default_recipients = false + additional_recipients = [] + critical_emails_only = false + } + assigned_user { + default_recipients = false + additional_recipients = [] + critical_emails_only = false + } + request_for_extension_or_approval { + default_recipients = false + additional_recipients = [] + critical_emails_only = false + } + } + eligible_member_activate { + role_assignment_alert { + default_recipients = false + additional_recipients = [] + critical_emails_only = false + } + assigned_user { + default_recipients = false + additional_recipients = [] + critical_emails_only = false + } + request_for_extension_or_approval { + default_recipients = false + critical_emails_only = false + } + } + } +}` +} + +func (RoleManagementPolicyResource) resourceGroup(data acceptance.TestData, id int) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +data "azurerm_subscription" "primary" {} + +data "azurerm_role_definition" "test" { + name = "Monitoring Reader" +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-%[1]d" + location = "%[2]s" +} + +resource "azurerm_role_management_policy" "test" { + scope = azurerm_resource_group.test.id + role_definition_id = "${data.azurerm_subscription.primary.id}${data.azurerm_role_definition.test.id}" + + activation { + maximum_duration_hours = 8 + + require_multi_factor_authentication = true + require_justification = true + require_ticket_information = true + } + + assignment { + eligible { + allow_permanent = true + } + + active { + allow_permanent = true + require_multi_factor_authentication = true + require_justification = true + } + } + + notifications { + member_assigned_eligible { + role_assignment_alert { + default_recipients = true + additional_recipients = ["role_assignment_alert@member_assigned_eligible.com"] + critical_emails_only = true + } + assigned_user { + default_recipients = true + additional_recipients = ["assigned_user@member_assigned_eligible.com"] + critical_emails_only = true + } + request_for_extension_or_approval { + default_recipients = true + additional_recipients = ["request_for_extension_or_approval@member_assigned_eligible.com"] + critical_emails_only = true + } + } + member_assigned_active { + role_assignment_alert { + default_recipients = true + additional_recipients = ["role_assignment_alert@member_assigned_active.com"] + critical_emails_only = true + } + assigned_user { + default_recipients = true + additional_recipients = ["assigned_user@member_assigned_active.com"] + critical_emails_only = true + } + request_for_extension_or_approval { + default_recipients = true + additional_recipients = ["request_for_extension_or_approval@member_assigned_active.com"] + critical_emails_only = true + } + } + eligible_member_activate { + role_assignment_alert { + default_recipients = true + additional_recipients = ["role_assignment_alert@eligible_member_activate.com"] + critical_emails_only = true + } + assigned_user { + default_recipients = true + additional_recipients = ["assigned_user@eligible_member_activate.com"] + critical_emails_only = true + } + request_for_extension_or_approval { + default_recipients = true + critical_emails_only = true + } + } + } +} + +`, id, data.Locations.Primary) +} + +func (RoleManagementPolicyResource) resource(data acceptance.TestData, id int) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +data "azurerm_subscription" "primary" {} + +data "azurerm_role_definition" "test" { + name = "Monitoring Reader" +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-%[1]d" + location = "%[2]s" +} + +resource "azurerm_virtual_network" "test" { + name = "amtestVNET1-%[1]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + address_space = ["10.0.0.0/16"] +} + +resource "azurerm_role_management_policy" "test" { + scope = azurerm_virtual_network.test.id + role_definition_id = "${data.azurerm_subscription.primary.id}${data.azurerm_role_definition.test.id}" + + activation { + maximum_duration_hours = 16 + + require_multi_factor_authentication = false + require_justification = false + require_ticket_information = false + } + + assignment { + eligible { + allow_permanent = true + } + + active { + allow_permanent = true + require_multi_factor_authentication = false + require_justification = false + } + } +} +`, id, data.Locations.Primary) +} diff --git a/internal/services/authorization/validate/role_management_policy.go b/internal/services/authorization/validate/role_management_policy.go new file mode 100644 index 0000000000000..2bfd4a13e5484 --- /dev/null +++ b/internal/services/authorization/validate/role_management_policy.go @@ -0,0 +1,37 @@ +package validate + +import ( + "fmt" + "strings" + + "github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/authorization/parse" +) + +func ValidateRoleManagementPolicyId(input interface{}, key string) (warnings []string, errors []error) { + v, ok := input.(string) + if !ok { + errors = append(errors, fmt.Errorf("expected %q to be a string", key)) + return + } + + ids := strings.Split(v, "|") + if len(ids) != 2 { + errors = append(errors, fmt.Errorf("expected %q to be in format roleManagementPolicyId|roleDefinitionId", v)) + return + } + + _, err := rolemanagementpolicies.ParseScopedRoleManagementPolicyID(ids[0]) + if err != nil { + errors = append(errors, fmt.Errorf("expected %s to be in format roleManagementPolicyId, %+v", ids[0], err)) + return + } + + _, err = parse.RoleDefinitionId(ids[1]) + if err != nil { + errors = append(errors, fmt.Errorf("expected %s to be in format roleManagementPolicyId, %+v", ids[1], err)) + return + } + + return +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/README.md b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/README.md new file mode 100644 index 0000000000000..f76624e15ad2e --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/README.md @@ -0,0 +1,90 @@ + +## `github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies` Documentation + +The `rolemanagementpolicies` SDK allows for interaction with the Azure Resource Manager Service `authorization` (API Version `2020-10-01`). + +This readme covers example usages, but further information on [using this SDK can be found in the project root](https://github.com/hashicorp/go-azure-sdk/tree/main/docs). + +### Import Path + +```go +import "github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies" +``` + + +### Client Initialization + +```go +client := rolemanagementpolicies.NewRoleManagementPoliciesClientWithBaseURI("https://management.azure.com") +client.Client.Authorizer = authorizer +``` + + +### Example Usage: `RoleManagementPoliciesClient.Delete` + +```go +ctx := context.TODO() +id := rolemanagementpolicies.NewScopedRoleManagementPolicyID("/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/some-resource-group", "roleManagementPolicyValue") + +read, err := client.Delete(ctx, id) +if err != nil { + // handle the error +} +if model := read.Model; model != nil { + // do something with the model/response object +} +``` + + +### Example Usage: `RoleManagementPoliciesClient.Get` + +```go +ctx := context.TODO() +id := rolemanagementpolicies.NewScopedRoleManagementPolicyID("/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/some-resource-group", "roleManagementPolicyValue") + +read, err := client.Get(ctx, id) +if err != nil { + // handle the error +} +if model := read.Model; model != nil { + // do something with the model/response object +} +``` + + +### Example Usage: `RoleManagementPoliciesClient.ListForScope` + +```go +ctx := context.TODO() +id := rolemanagementpolicies.NewScopeID("/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/some-resource-group") + +// alternatively `client.ListForScope(ctx, id)` can be used to do batched pagination +items, err := client.ListForScopeComplete(ctx, id) +if err != nil { + // handle the error +} +for _, item := range items { + // do something +} +``` + + +### Example Usage: `RoleManagementPoliciesClient.Update` + +```go +ctx := context.TODO() +id := rolemanagementpolicies.NewScopedRoleManagementPolicyID("/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/some-resource-group", "roleManagementPolicyValue") + +payload := rolemanagementpolicies.RoleManagementPolicy{ + // ... +} + + +read, err := client.Update(ctx, id, payload) +if err != nil { + // handle the error +} +if model := read.Model; model != nil { + // do something with the model/response object +} +``` diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/client.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/client.go new file mode 100644 index 0000000000000..2a5bed5331418 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/client.go @@ -0,0 +1,18 @@ +package rolemanagementpolicies + +import "github.com/Azure/go-autorest/autorest" + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type RoleManagementPoliciesClient struct { + Client autorest.Client + baseUri string +} + +func NewRoleManagementPoliciesClientWithBaseURI(endpoint string) RoleManagementPoliciesClient { + return RoleManagementPoliciesClient{ + Client: autorest.NewClientWithUserAgent(userAgent()), + baseUri: endpoint, + } +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/constants.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/constants.go new file mode 100644 index 0000000000000..54428162407af --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/constants.go @@ -0,0 +1,43 @@ +package rolemanagementpolicies + +import "strings" + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type RoleManagementPolicyRuleType string + +const ( + RoleManagementPolicyRuleTypeRoleManagementPolicyApprovalRule RoleManagementPolicyRuleType = "RoleManagementPolicyApprovalRule" + RoleManagementPolicyRuleTypeRoleManagementPolicyAuthenticationContextRule RoleManagementPolicyRuleType = "RoleManagementPolicyAuthenticationContextRule" + RoleManagementPolicyRuleTypeRoleManagementPolicyEnablementRule RoleManagementPolicyRuleType = "RoleManagementPolicyEnablementRule" + RoleManagementPolicyRuleTypeRoleManagementPolicyExpirationRule RoleManagementPolicyRuleType = "RoleManagementPolicyExpirationRule" + RoleManagementPolicyRuleTypeRoleManagementPolicyNotificationRule RoleManagementPolicyRuleType = "RoleManagementPolicyNotificationRule" +) + +func PossibleValuesForRoleManagementPolicyRuleType() []string { + return []string{ + string(RoleManagementPolicyRuleTypeRoleManagementPolicyApprovalRule), + string(RoleManagementPolicyRuleTypeRoleManagementPolicyAuthenticationContextRule), + string(RoleManagementPolicyRuleTypeRoleManagementPolicyEnablementRule), + string(RoleManagementPolicyRuleTypeRoleManagementPolicyExpirationRule), + string(RoleManagementPolicyRuleTypeRoleManagementPolicyNotificationRule), + } +} + +func parseRoleManagementPolicyRuleType(input string) (*RoleManagementPolicyRuleType, error) { + vals := map[string]RoleManagementPolicyRuleType{ + "rolemanagementpolicyapprovalrule": RoleManagementPolicyRuleTypeRoleManagementPolicyApprovalRule, + "rolemanagementpolicyauthenticationcontextrule": RoleManagementPolicyRuleTypeRoleManagementPolicyAuthenticationContextRule, + "rolemanagementpolicyenablementrule": RoleManagementPolicyRuleTypeRoleManagementPolicyEnablementRule, + "rolemanagementpolicyexpirationrule": RoleManagementPolicyRuleTypeRoleManagementPolicyExpirationRule, + "rolemanagementpolicynotificationrule": RoleManagementPolicyRuleTypeRoleManagementPolicyNotificationRule, + } + if v, ok := vals[strings.ToLower(input)]; ok { + return &v, nil + } + + // otherwise presume it's an undefined value and best-effort it + out := RoleManagementPolicyRuleType(input) + return &out, nil +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/id_scopedrolemanagementpolicy.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/id_scopedrolemanagementpolicy.go new file mode 100644 index 0000000000000..be359eabcab52 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/id_scopedrolemanagementpolicy.go @@ -0,0 +1,110 @@ +package rolemanagementpolicies + +import ( + "fmt" + "strings" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" +) + +var _ resourceids.ResourceId = ScopedRoleManagementPolicyId{} + +// ScopedRoleManagementPolicyId is a struct representing the Resource ID for a Scoped Role Management Policy +type ScopedRoleManagementPolicyId struct { + Scope string + RoleManagementPolicyName string +} + +// NewScopedRoleManagementPolicyID returns a new ScopedRoleManagementPolicyId struct +func NewScopedRoleManagementPolicyID(scope string, roleManagementPolicyName string) ScopedRoleManagementPolicyId { + return ScopedRoleManagementPolicyId{ + Scope: scope, + RoleManagementPolicyName: roleManagementPolicyName, + } +} + +// ParseScopedRoleManagementPolicyID parses 'input' into a ScopedRoleManagementPolicyId +func ParseScopedRoleManagementPolicyID(input string) (*ScopedRoleManagementPolicyId, error) { + parser := resourceids.NewParserFromResourceIdType(ScopedRoleManagementPolicyId{}) + parsed, err := parser.Parse(input, false) + if err != nil { + return nil, fmt.Errorf("parsing %q: %+v", input, err) + } + + var ok bool + id := ScopedRoleManagementPolicyId{} + + if id.Scope, ok = parsed.Parsed["scope"]; !ok { + return nil, fmt.Errorf("the segment 'scope' was not found in the resource id %q", input) + } + + if id.RoleManagementPolicyName, ok = parsed.Parsed["roleManagementPolicyName"]; !ok { + return nil, fmt.Errorf("the segment 'roleManagementPolicyName' was not found in the resource id %q", input) + } + + return &id, nil +} + +// ParseScopedRoleManagementPolicyIDInsensitively parses 'input' case-insensitively into a ScopedRoleManagementPolicyId +// note: this method should only be used for API response data and not user input +func ParseScopedRoleManagementPolicyIDInsensitively(input string) (*ScopedRoleManagementPolicyId, error) { + parser := resourceids.NewParserFromResourceIdType(ScopedRoleManagementPolicyId{}) + parsed, err := parser.Parse(input, true) + if err != nil { + return nil, fmt.Errorf("parsing %q: %+v", input, err) + } + + var ok bool + id := ScopedRoleManagementPolicyId{} + + if id.Scope, ok = parsed.Parsed["scope"]; !ok { + return nil, fmt.Errorf("the segment 'scope' was not found in the resource id %q", input) + } + + if id.RoleManagementPolicyName, ok = parsed.Parsed["roleManagementPolicyName"]; !ok { + return nil, fmt.Errorf("the segment 'roleManagementPolicyName' was not found in the resource id %q", input) + } + + return &id, nil +} + +// ValidateScopedRoleManagementPolicyID checks that 'input' can be parsed as a Scoped Role Management Policy ID +func ValidateScopedRoleManagementPolicyID(input interface{}, key string) (warnings []string, errors []error) { + v, ok := input.(string) + if !ok { + errors = append(errors, fmt.Errorf("expected %q to be a string", key)) + return + } + + if _, err := ParseScopedRoleManagementPolicyID(v); err != nil { + errors = append(errors, err) + } + + return +} + +// ID returns the formatted Scoped Role Management Policy ID +func (id ScopedRoleManagementPolicyId) ID() string { + fmtString := "/%s/providers/Microsoft.Authorization/roleManagementPolicies/%s" + return fmt.Sprintf(fmtString, strings.TrimPrefix(id.Scope, "/"), id.RoleManagementPolicyName) +} + +// Segments returns a slice of Resource ID Segments which comprise this Scoped Role Management Policy ID +func (id ScopedRoleManagementPolicyId) Segments() []resourceids.Segment { + return []resourceids.Segment{ + resourceids.ScopeSegment("scope", "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/some-resource-group"), + resourceids.StaticSegment("staticProviders", "providers", "providers"), + resourceids.ResourceProviderSegment("staticMicrosoftAuthorization", "Microsoft.Authorization", "Microsoft.Authorization"), + resourceids.StaticSegment("staticRoleManagementPolicies", "roleManagementPolicies", "roleManagementPolicies"), + resourceids.UserSpecifiedSegment("roleManagementPolicyName", "roleManagementPolicyValue"), + } +} + +// String returns a human-readable description of this Scoped Role Management Policy ID +func (id ScopedRoleManagementPolicyId) String() string { + components := []string{ + fmt.Sprintf("Scope: %q", id.Scope), + fmt.Sprintf("Role Management Policy Name: %q", id.RoleManagementPolicyName), + } + return fmt.Sprintf("Scoped Role Management Policy (%s)", strings.Join(components, "\n")) +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/method_delete_autorest.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/method_delete_autorest.go new file mode 100644 index 0000000000000..33fd2df9d0229 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/method_delete_autorest.go @@ -0,0 +1,66 @@ +package rolemanagementpolicies + +import ( + "context" + "net/http" + + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type DeleteOperationResponse struct { + HttpResponse *http.Response +} + +// Delete ... +func (c RoleManagementPoliciesClient) Delete(ctx context.Context, id ScopedRoleManagementPolicyId) (result DeleteOperationResponse, err error) { + req, err := c.preparerForDelete(ctx, id) + if err != nil { + err = autorest.NewErrorWithError(err, "rolemanagementpolicies.RoleManagementPoliciesClient", "Delete", nil, "Failure preparing request") + return + } + + result.HttpResponse, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) + if err != nil { + err = autorest.NewErrorWithError(err, "rolemanagementpolicies.RoleManagementPoliciesClient", "Delete", result.HttpResponse, "Failure sending request") + return + } + + result, err = c.responderForDelete(result.HttpResponse) + if err != nil { + err = autorest.NewErrorWithError(err, "rolemanagementpolicies.RoleManagementPoliciesClient", "Delete", result.HttpResponse, "Failure responding to request") + return + } + + return +} + +// preparerForDelete prepares the Delete request. +func (c RoleManagementPoliciesClient) preparerForDelete(ctx context.Context, id ScopedRoleManagementPolicyId) (*http.Request, error) { + queryParameters := map[string]interface{}{ + "api-version": defaultApiVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsDelete(), + autorest.WithBaseURL(c.baseUri), + autorest.WithPath(id.ID()), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// responderForDelete handles the response to the Delete request. The method always +// closes the http.Response Body. +func (c RoleManagementPoliciesClient) responderForDelete(resp *http.Response) (result DeleteOperationResponse, err error) { + err = autorest.Respond( + resp, + azure.WithErrorUnlessStatusCode(http.StatusNoContent, http.StatusOK), + autorest.ByClosing()) + result.HttpResponse = resp + + return +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/method_get_autorest.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/method_get_autorest.go new file mode 100644 index 0000000000000..78f0bd7cd39ed --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/method_get_autorest.go @@ -0,0 +1,68 @@ +package rolemanagementpolicies + +import ( + "context" + "net/http" + + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type GetOperationResponse struct { + HttpResponse *http.Response + Model *RoleManagementPolicy +} + +// Get ... +func (c RoleManagementPoliciesClient) Get(ctx context.Context, id ScopedRoleManagementPolicyId) (result GetOperationResponse, err error) { + req, err := c.preparerForGet(ctx, id) + if err != nil { + err = autorest.NewErrorWithError(err, "rolemanagementpolicies.RoleManagementPoliciesClient", "Get", nil, "Failure preparing request") + return + } + + result.HttpResponse, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) + if err != nil { + err = autorest.NewErrorWithError(err, "rolemanagementpolicies.RoleManagementPoliciesClient", "Get", result.HttpResponse, "Failure sending request") + return + } + + result, err = c.responderForGet(result.HttpResponse) + if err != nil { + err = autorest.NewErrorWithError(err, "rolemanagementpolicies.RoleManagementPoliciesClient", "Get", result.HttpResponse, "Failure responding to request") + return + } + + return +} + +// preparerForGet prepares the Get request. +func (c RoleManagementPoliciesClient) preparerForGet(ctx context.Context, id ScopedRoleManagementPolicyId) (*http.Request, error) { + queryParameters := map[string]interface{}{ + "api-version": defaultApiVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsGet(), + autorest.WithBaseURL(c.baseUri), + autorest.WithPath(id.ID()), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// responderForGet handles the response to the Get request. The method always +// closes the http.Response Body. +func (c RoleManagementPoliciesClient) responderForGet(resp *http.Response) (result GetOperationResponse, err error) { + err = autorest.Respond( + resp, + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Model), + autorest.ByClosing()) + result.HttpResponse = resp + + return +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/method_listforscope_autorest.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/method_listforscope_autorest.go new file mode 100644 index 0000000000000..3d0be9e3ea689 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/method_listforscope_autorest.go @@ -0,0 +1,193 @@ +package rolemanagementpolicies + +import ( + "context" + "fmt" + "net/http" + "net/url" + + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/hashicorp/go-azure-helpers/resourcemanager/commonids" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ListForScopeOperationResponse struct { + HttpResponse *http.Response + Model *[]RoleManagementPolicy + + nextLink *string + nextPageFunc func(ctx context.Context, nextLink string) (ListForScopeOperationResponse, error) +} + +type ListForScopeCompleteResult struct { + Items []RoleManagementPolicy +} + +func (r ListForScopeOperationResponse) HasMore() bool { + return r.nextLink != nil +} + +func (r ListForScopeOperationResponse) LoadMore(ctx context.Context) (resp ListForScopeOperationResponse, err error) { + if !r.HasMore() { + err = fmt.Errorf("no more pages returned") + return + } + return r.nextPageFunc(ctx, *r.nextLink) +} + +// ListForScope ... +// JOSH: added filter string +func (c RoleManagementPoliciesClient) ListForScope(ctx context.Context, id commonids.ScopeId, filter string) (resp ListForScopeOperationResponse, err error) { + req, err := c.preparerForListForScope(ctx, id, filter) + if err != nil { + err = autorest.NewErrorWithError(err, "rolemanagementpolicies.RoleManagementPoliciesClient", "ListForScope", nil, "Failure preparing request") + return + } + + resp.HttpResponse, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) + if err != nil { + err = autorest.NewErrorWithError(err, "rolemanagementpolicies.RoleManagementPoliciesClient", "ListForScope", resp.HttpResponse, "Failure sending request") + return + } + + resp, err = c.responderForListForScope(resp.HttpResponse) + if err != nil { + err = autorest.NewErrorWithError(err, "rolemanagementpolicies.RoleManagementPoliciesClient", "ListForScope", resp.HttpResponse, "Failure responding to request") + return + } + return +} + +// preparerForListForScope prepares the ListForScope request. +// JOSH: added filter string +func (c RoleManagementPoliciesClient) preparerForListForScope(ctx context.Context, id commonids.ScopeId, filter string) (*http.Request, error) { + queryParameters := map[string]interface{}{ + "api-version": defaultApiVersion, + } + + if filter != "" { + queryParameters["$filter"] = filter + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsGet(), + autorest.WithBaseURL(c.baseUri), + autorest.WithPath(fmt.Sprintf("%s/providers/Microsoft.Authorization/roleManagementPolicies", id.ID())), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// preparerForListForScopeWithNextLink prepares the ListForScope request with the given nextLink token. +func (c RoleManagementPoliciesClient) preparerForListForScopeWithNextLink(ctx context.Context, nextLink string) (*http.Request, error) { + uri, err := url.Parse(nextLink) + if err != nil { + return nil, fmt.Errorf("parsing nextLink %q: %+v", nextLink, err) + } + queryParameters := map[string]interface{}{} + for k, v := range uri.Query() { + if len(v) == 0 { + continue + } + val := v[0] + val = autorest.Encode("query", val) + queryParameters[k] = val + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsGet(), + autorest.WithBaseURL(c.baseUri), + autorest.WithPath(uri.Path), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// responderForListForScope handles the response to the ListForScope request. The method always +// closes the http.Response Body. +func (c RoleManagementPoliciesClient) responderForListForScope(resp *http.Response) (result ListForScopeOperationResponse, err error) { + type page struct { + Values []RoleManagementPolicy `json:"value"` + NextLink *string `json:"nextLink"` + } + var respObj page + err = autorest.Respond( + resp, + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&respObj), + autorest.ByClosing()) + result.HttpResponse = resp + result.Model = &respObj.Values + result.nextLink = respObj.NextLink + if respObj.NextLink != nil { + result.nextPageFunc = func(ctx context.Context, nextLink string) (result ListForScopeOperationResponse, err error) { + req, err := c.preparerForListForScopeWithNextLink(ctx, nextLink) + if err != nil { + err = autorest.NewErrorWithError(err, "rolemanagementpolicies.RoleManagementPoliciesClient", "ListForScope", nil, "Failure preparing request") + return + } + + result.HttpResponse, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) + if err != nil { + err = autorest.NewErrorWithError(err, "rolemanagementpolicies.RoleManagementPoliciesClient", "ListForScope", result.HttpResponse, "Failure sending request") + return + } + + result, err = c.responderForListForScope(result.HttpResponse) + if err != nil { + err = autorest.NewErrorWithError(err, "rolemanagementpolicies.RoleManagementPoliciesClient", "ListForScope", result.HttpResponse, "Failure responding to request") + return + } + + return + } + } + return +} + +// ListForScopeComplete retrieves all of the results into a single object +func (c RoleManagementPoliciesClient) ListForScopeComplete(ctx context.Context, id commonids.ScopeId, filter string) (ListForScopeCompleteResult, error) { + return c.ListForScopeCompleteMatchingPredicate(ctx, id, filter, RoleManagementPolicyOperationPredicate{}) +} + +// ListForScopeCompleteMatchingPredicate retrieves all of the results and then applied the predicate +func (c RoleManagementPoliciesClient) ListForScopeCompleteMatchingPredicate(ctx context.Context, id commonids.ScopeId, filter string, predicate RoleManagementPolicyOperationPredicate) (resp ListForScopeCompleteResult, err error) { + items := make([]RoleManagementPolicy, 0) + + page, err := c.ListForScope(ctx, id, filter) + if err != nil { + err = fmt.Errorf("loading the initial page: %+v", err) + return + } + if page.Model != nil { + for _, v := range *page.Model { + if predicate.Matches(v) { + items = append(items, v) + } + } + } + + for page.HasMore() { + page, err = page.LoadMore(ctx) + if err != nil { + err = fmt.Errorf("loading the next page: %+v", err) + return + } + + if page.Model != nil { + for _, v := range *page.Model { + if predicate.Matches(v) { + items = append(items, v) + } + } + } + } + + out := ListForScopeCompleteResult{ + Items: items, + } + return out, nil +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/method_update_autorest.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/method_update_autorest.go new file mode 100644 index 0000000000000..39567252879c3 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/method_update_autorest.go @@ -0,0 +1,69 @@ +package rolemanagementpolicies + +import ( + "context" + "net/http" + + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type UpdateOperationResponse struct { + HttpResponse *http.Response + Model *RoleManagementPolicy +} + +// Update ... +func (c RoleManagementPoliciesClient) Update(ctx context.Context, id ScopedRoleManagementPolicyId, input RoleManagementPolicy) (result UpdateOperationResponse, err error) { + req, err := c.preparerForUpdate(ctx, id, input) + if err != nil { + err = autorest.NewErrorWithError(err, "rolemanagementpolicies.RoleManagementPoliciesClient", "Update", nil, "Failure preparing request") + return + } + + result.HttpResponse, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) + if err != nil { + err = autorest.NewErrorWithError(err, "rolemanagementpolicies.RoleManagementPoliciesClient", "Update", result.HttpResponse, "Failure sending request") + return + } + + result, err = c.responderForUpdate(result.HttpResponse) + if err != nil { + err = autorest.NewErrorWithError(err, "rolemanagementpolicies.RoleManagementPoliciesClient", "Update", result.HttpResponse, "Failure responding to request") + return + } + + return +} + +// preparerForUpdate prepares the Update request. +func (c RoleManagementPoliciesClient) preparerForUpdate(ctx context.Context, id ScopedRoleManagementPolicyId, input RoleManagementPolicy) (*http.Request, error) { + queryParameters := map[string]interface{}{ + "api-version": defaultApiVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsPatch(), + autorest.WithBaseURL(c.baseUri), + autorest.WithPath(id.ID()), + autorest.WithJSON(input), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// responderForUpdate handles the response to the Update request. The method always +// closes the http.Response Body. +func (c RoleManagementPoliciesClient) responderForUpdate(resp *http.Response) (result UpdateOperationResponse, err error) { + err = autorest.Respond( + resp, + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Model), + autorest.ByClosing()) + result.HttpResponse = resp + + return +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/model_policyproperties.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/model_policyproperties.go new file mode 100644 index 0000000000000..af2bc58ecd1d6 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/model_policyproperties.go @@ -0,0 +1,8 @@ +package rolemanagementpolicies + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type PolicyProperties struct { + Scope *PolicyPropertiesScope `json:"scope,omitempty"` +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/model_policypropertiesscope.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/model_policypropertiesscope.go new file mode 100644 index 0000000000000..5a70ff199bd62 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/model_policypropertiesscope.go @@ -0,0 +1,10 @@ +package rolemanagementpolicies + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type PolicyPropertiesScope struct { + DisplayName *string `json:"displayName,omitempty"` + Id *string `json:"id,omitempty"` + Type *string `json:"type,omitempty"` +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/model_principal.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/model_principal.go new file mode 100644 index 0000000000000..ad3771f02ce06 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/model_principal.go @@ -0,0 +1,11 @@ +package rolemanagementpolicies + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type Principal struct { + DisplayName *string `json:"displayName,omitempty"` + Email *string `json:"email,omitempty"` + Id *string `json:"id,omitempty"` + Type *string `json:"type,omitempty"` +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/model_rolemanagementpolicy.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/model_rolemanagementpolicy.go new file mode 100644 index 0000000000000..9c5cc478fd167 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/model_rolemanagementpolicy.go @@ -0,0 +1,11 @@ +package rolemanagementpolicies + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type RoleManagementPolicy struct { + Id *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Properties *RoleManagementPolicyProperties `json:"properties,omitempty"` + Type *string `json:"type,omitempty"` +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/model_rolemanagementpolicyproperties.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/model_rolemanagementpolicyproperties.go new file mode 100644 index 0000000000000..310d9b0cf6824 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/model_rolemanagementpolicyproperties.go @@ -0,0 +1,94 @@ +package rolemanagementpolicies + +import ( + "encoding/json" + "fmt" + "time" + + "github.com/hashicorp/go-azure-helpers/lang/dates" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type RoleManagementPolicyProperties struct { + Description *string `json:"description,omitempty"` + DisplayName *string `json:"displayName,omitempty"` + EffectiveRules *[]RoleManagementPolicyRule `json:"effectiveRules,omitempty"` + IsOrganizationDefault *bool `json:"isOrganizationDefault,omitempty"` + LastModifiedBy *Principal `json:"lastModifiedBy,omitempty"` + LastModifiedDateTime *string `json:"lastModifiedDateTime,omitempty"` + PolicyProperties *PolicyProperties `json:"policyProperties,omitempty"` + Rules *[]RoleManagementPolicyRule `json:"rules,omitempty"` + Scope *string `json:"scope,omitempty"` +} + +func (o *RoleManagementPolicyProperties) GetLastModifiedDateTimeAsTime() (*time.Time, error) { + if o.LastModifiedDateTime == nil { + return nil, nil + } + return dates.ParseAsFormat(o.LastModifiedDateTime, "2006-01-02T15:04:05Z07:00") +} + +func (o *RoleManagementPolicyProperties) SetLastModifiedDateTimeAsTime(input time.Time) { + formatted := input.Format("2006-01-02T15:04:05Z07:00") + o.LastModifiedDateTime = &formatted +} + +var _ json.Unmarshaler = &RoleManagementPolicyProperties{} + +func (s *RoleManagementPolicyProperties) UnmarshalJSON(bytes []byte) error { + type alias RoleManagementPolicyProperties + var decoded alias + if err := json.Unmarshal(bytes, &decoded); err != nil { + return fmt.Errorf("unmarshaling into RoleManagementPolicyProperties: %+v", err) + } + + s.Description = decoded.Description + s.DisplayName = decoded.DisplayName + s.IsOrganizationDefault = decoded.IsOrganizationDefault + s.LastModifiedBy = decoded.LastModifiedBy + s.LastModifiedDateTime = decoded.LastModifiedDateTime + s.PolicyProperties = decoded.PolicyProperties + s.Scope = decoded.Scope + + var temp map[string]json.RawMessage + if err := json.Unmarshal(bytes, &temp); err != nil { + return fmt.Errorf("unmarshaling RoleManagementPolicyProperties into map[string]json.RawMessage: %+v", err) + } + + if v, ok := temp["effectiveRules"]; ok { + var listTemp []json.RawMessage + if err := json.Unmarshal(v, &listTemp); err != nil { + return fmt.Errorf("unmarshaling EffectiveRules into list []json.RawMessage: %+v", err) + } + + output := make([]RoleManagementPolicyRule, 0) + for i, val := range listTemp { + impl, err := unmarshalRoleManagementPolicyRuleImplementation(val) + if err != nil { + return fmt.Errorf("unmarshaling index %d field 'EffectiveRules' for 'RoleManagementPolicyProperties': %+v", i, err) + } + output = append(output, impl) + } + s.EffectiveRules = &output + } + + if v, ok := temp["rules"]; ok { + var listTemp []json.RawMessage + if err := json.Unmarshal(v, &listTemp); err != nil { + return fmt.Errorf("unmarshaling Rules into list []json.RawMessage: %+v", err) + } + + output := make([]RoleManagementPolicyRule, 0) + for i, val := range listTemp { + impl, err := unmarshalRoleManagementPolicyRuleImplementation(val) + if err != nil { + return fmt.Errorf("unmarshaling index %d field 'Rules' for 'RoleManagementPolicyProperties': %+v", i, err) + } + output = append(output, impl) + } + s.Rules = &output + } + return nil +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/model_rolemanagementpolicyrule.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/model_rolemanagementpolicyrule.go new file mode 100644 index 0000000000000..a71c8dcb3160c --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/model_rolemanagementpolicyrule.go @@ -0,0 +1,45 @@ +package rolemanagementpolicies + +import ( + "encoding/json" + "fmt" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type RoleManagementPolicyRule interface { +} + +// Josh moved to access internals +type RawRoleManagementPolicyRuleImpl struct { + Type string `json:"-"` + Values map[string]interface{} `json:"-"` +} + +func unmarshalRoleManagementPolicyRuleImplementation(input []byte) (RoleManagementPolicyRule, error) { + if input == nil { + return nil, nil + } + + var temp map[string]interface{} + if err := json.Unmarshal(input, &temp); err != nil { + return nil, fmt.Errorf("unmarshaling RoleManagementPolicyRule into map[string]interface: %+v", err) + } + + value, ok := temp["ruleType"].(string) + if !ok { + return nil, nil + } + + // type RawRoleManagementPolicyRuleImpl struct { + // Type string `json:"-"` + // Values map[string]interface{} `json:"-"` + // } + out := RawRoleManagementPolicyRuleImpl{ + Type: value, + Values: temp, + } + return out, nil + +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/model_rolemanagementpolicyruletarget.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/model_rolemanagementpolicyruletarget.go new file mode 100644 index 0000000000000..b93dd22a7fe38 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/model_rolemanagementpolicyruletarget.go @@ -0,0 +1,13 @@ +package rolemanagementpolicies + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type RoleManagementPolicyRuleTarget struct { + Caller *string `json:"caller,omitempty"` + EnforcedSettings *[]string `json:"enforcedSettings,omitempty"` + InheritableSettings *[]string `json:"inheritableSettings,omitempty"` + Level *string `json:"level,omitempty"` + Operations *[]string `json:"operations,omitempty"` + TargetObjects *[]string `json:"targetObjects,omitempty"` +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/predicates.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/predicates.go new file mode 100644 index 0000000000000..94b78c08b1288 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/predicates.go @@ -0,0 +1,24 @@ +package rolemanagementpolicies + +type RoleManagementPolicyOperationPredicate struct { + Id *string + Name *string + Type *string +} + +func (p RoleManagementPolicyOperationPredicate) Matches(input RoleManagementPolicy) bool { + + if p.Id != nil && (input.Id == nil && *p.Id != *input.Id) { + return false + } + + if p.Name != nil && (input.Name == nil && *p.Name != *input.Name) { + return false + } + + if p.Type != nil && (input.Type == nil && *p.Type != *input.Type) { + return false + } + + return true +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/version.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/version.go new file mode 100644 index 0000000000000..cbd840f2fceda --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies/version.go @@ -0,0 +1,12 @@ +package rolemanagementpolicies + +import "fmt" + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +const defaultApiVersion = "2020-10-01" + +func userAgent() string { + return fmt.Sprintf("hashicorp/go-azure-sdk/rolemanagementpolicies/%s", defaultApiVersion) +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 04377e7348c1e..d44f9c4da4ef9 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -176,6 +176,7 @@ github.com/hashicorp/go-azure-sdk/resource-manager/applicationinsights/2020-11-2 github.com/hashicorp/go-azure-sdk/resource-manager/applicationinsights/2022-04-01/workbooksapis github.com/hashicorp/go-azure-sdk/resource-manager/applicationinsights/2022-06-15/webtestsapis github.com/hashicorp/go-azure-sdk/resource-manager/attestation/2020-10-01/attestationproviders +github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/rolemanagementpolicies github.com/hashicorp/go-azure-sdk/resource-manager/automation/2019-06-01/runbook github.com/hashicorp/go-azure-sdk/resource-manager/automation/2021-06-22/automationaccount github.com/hashicorp/go-azure-sdk/resource-manager/automation/2021-06-22/hybridrunbookworker diff --git a/website/docs/r/role_management_policy.html.markdown b/website/docs/r/role_management_policy.html.markdown new file mode 100644 index 0000000000000..f2fdf593df362 --- /dev/null +++ b/website/docs/r/role_management_policy.html.markdown @@ -0,0 +1,211 @@ +--- +subcategory: "Authorization" +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_role_management_policy" +description: |- + Manages a Role Management Policy. +--- + +# azurerm_role_management_policy + +Manages a Role Management Policy. + +## Example Usage + +```hcl +data "azurerm_subscription" "primary" {} + +data "azurerm_role_definition" "test" { + name = "Monitoring Reader" +} + +resource "azurerm_role_management_policy" "test" { + scope = data.azurerm_subscription.primary.id + role_definition_id = "${data.azurerm_subscription.primary.id}${data.azurerm_role_definition.test.id}" + + activation { + maximum_duration_hours = 12 + } +} +``` + +## Arguments Reference + +The following arguments are supported: + +* `role_definition_id` - (Required) The ID of the role definition id. + +* `scope` - (Required) The scope. + +--- + +* `activation` - (Optional) A `activation` block as defined below. + +* `assignment` - (Optional) A `assignment` block as defined below. + +* `notifications` - (Optional) A `notifications` block as defined below. + +--- + +A `activation` block supports the following: + +* `approvers` - (Optional) A `approvers` block as defined below. + +* `maximum_duration_hours` - (Optional) The maximum duration in hours for an activation.. + +* `require_justification` - (Optional) Is Justification required for an activation?. + +* `require_multi_factor_authentication` - (Optional) Is Multi Factor Authentication required for an activation? + +* `require_ticket_information` - (Optional) Is Ticket Information required for an activation?. + +--- + +A `active` block supports the following: + +* `allow_permanent` - (Optional) Allow permanent active assignment. Conflicts with `assignment.0.active.0.expire_after_days`,`assignment.0.active.0.expire_after_hours` + +* `expire_after_days` - (Optional) The number of days after an active assignments is expired. Conflicts with `assignment.0.active.0.allow_permanent`,`assignment.0.active.0.expire_after_hours` + +* `expire_after_hours` - (Optional) The number of hours after an active assignments is expired. Conflicts with `assignment.0.active.0.allow_permanent`,`assignment.0.active.0.expire_after_days` + +* `require_justification` - (Optional) Is Justification required for an active assignment? + +* `require_multi_factor_authentication` - (Optional) Is Multi Factor Authentication required for an active assignment? + +--- + +A `approvers` block supports the following: + +* `group` - (Optional) One or more `group` blocks as defined below. + +* `user` - (Optional) One or more `user` blocks as defined below. + +--- + +A `assigned_user` block supports the following: + +* `additional_recipients` - (Optional) List of additional recipients to email notifications. + +* `critical_emails_only` - (Optional) Will critical emails only be sent? + +* `default_recipients` - (Optional) Will notifications be sent to the default recipients? + +--- + +A `assignment` block supports the following: + +* `active` - (Optional) A `active` block as defined above. + +* `eligible` - (Optional) A `eligible` block as defined below. + +--- + +A `eligible` block supports the following: + +* `allow_permanent` - (Optional) Allow permanent eligible assignment. Conflicts with `assignment.0.eligible.0.expire_after_hours`,`assignment.0.eligible.0.expire_after_days` + +* `expire_after_days` - (Optional) The number of days after an eligible assignments is expired. Conflicts with `assignment.0.eligible.0.allow_permanent`,`assignment.0.eligible.0.expire_after_hours` + +* `expire_after_hours` - (Optional) The number of hours after an eligible assignments is expired. Conflicts with `assignment.0.eligible.0.allow_permanent`,`assignment.0.eligible.0.expire_after_days` + +--- + +A `eligible_member_activate` block supports the following: + +* `assigned_user` - (Optional) A `assigned_user` block as defined above. + +* `request_for_extension_or_approval` - (Optional) A `request_for_extension_or_approval` block as defined below. + +* `role_assignment_alert` - (Optional) A `role_assignment_alert` block as defined below. + +--- + +A `group` block supports the following: + +* `id` - (Required) The object id of a group. + +* `name` - (Required) The name of the group. + +--- + +A `member_assigned_active` block supports the following: + +* `assigned_user` - (Optional) A `assigned_user` block as defined above. + +* `request_for_extension_or_approval` - (Optional) A `request_for_extension_or_approval` block as defined below. + +* `role_assignment_alert` - (Optional) A `role_assignment_alert` block as defined below. + +--- + +A `member_assigned_eligible` block supports the following: + +* `assigned_user` - (Optional) A `assigned_user` block as defined above. + +* `request_for_extension_or_approval` - (Optional) A `request_for_extension_or_approval` block as defined below. + +* `role_assignment_alert` - (Optional) A `role_assignment_alert` block as defined below. + +--- + +A `notifications` block supports the following: + +* `eligible_member_activate` - (Optional) A `eligible_member_activate` block as defined above. + +* `member_assigned_active` - (Optional) A `member_assigned_active` block as defined above. + +* `member_assigned_eligible` - (Optional) A `member_assigned_eligible` block as defined above. + +--- + +A `request_for_extension_or_approval` block supports the following: + +* `additional_recipients` - (Optional) List of additional recipients to email notifications. + +* `critical_emails_only` - (Optional) Will critical emails only be sent? + +* `default_recipients` - (Optional) Will notifications be sent to the default recipients? + +--- + +A `role_assignment_alert` block supports the following: + +* `additional_recipients` - (Optional) List of additional recipients to email notifications. + +* `critical_emails_only` - (Optional) Will critical emails only be sent? + +* `default_recipients` - (Optional) Will notifications be sent to the default recipients? + +--- + +A `user` block supports the following: + +* `id` - (Required) The object id of a user. + +* `name` - (Required) The name of the user. + +## Attributes Reference + +In addition to the Arguments listed above - the following Attributes are exported: + +* `id` - The ID of the Role Management Policy. + +## Timeouts + +The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/language/resources/syntax#operation-timeouts) for certain actions: + +* `create` - (Defaults to 30 minutes) Used when creating the Role Management Policy. +* `read` - (Defaults to 5 minutes) Used when retrieving the Role Management Policy. +* `update` - (Defaults to 30 minutes) Used when updating the Role Management Policy. +* `delete` - (Defaults to 30 minutes) Used when deleting the Role Management Policy. + +## Import + +Role Management Policies can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_role_management_policy.example /subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/roleManagementPolicies/00000000-0000-0000-0000-000000000000|/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/roleDefinitions/00000000-0000-0000-0000-000000000000 +``` + +-> **NOTE:** This ID is specific to Terraform - and is of the format `{roleManagementPolicyId}|{roleDefinitionId}`.