diff --git a/internal/services/authorization/client/client.go b/internal/services/authorization/client/client.go index 0c7bf9d11201..6d4de793afe1 100644 --- a/internal/services/authorization/client/client.go +++ b/internal/services/authorization/client/client.go @@ -11,8 +11,10 @@ import ( // To swap sdk for `azurerm_role_definition` without changing API version "github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentscheduleinstances" "github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedulerequests" + "github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules" "github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityscheduleinstances" "github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedulerequests" + "github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules" "github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2022-04-01/roleassignments" "github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2022-05-01-preview/roledefinitions" "github.com/hashicorp/terraform-provider-azurerm/internal/common" @@ -22,8 +24,10 @@ type Client struct { RoleAssignmentsClient *authorization.RoleAssignmentsClient RoleAssignmentScheduleRequestClient *roleassignmentschedulerequests.RoleAssignmentScheduleRequestsClient RoleAssignmentScheduleInstancesClient *roleassignmentscheduleinstances.RoleAssignmentScheduleInstancesClient + RoleAssignmentSchedulesClient *roleassignmentschedules.RoleAssignmentSchedulesClient RoleEligibilityScheduleRequestClient *roleeligibilityschedulerequests.RoleEligibilityScheduleRequestsClient RoleEligibilityScheduleInstancesClient *roleeligibilityscheduleinstances.RoleEligibilityScheduleInstancesClient + RoleEligibilitySchedulesClient *roleeligibilityschedules.RoleEligibilitySchedulesClient ScopedRoleAssignmentsClient *roleassignments.RoleAssignmentsClient ScopedRoleDefinitionsClient *roledefinitions.RoleDefinitionsClient } @@ -45,6 +49,12 @@ func NewClient(o *common.ClientOptions) (*Client, error) { } o.Configure(roleAssignmentScheduleInstancesClient.Client, o.Authorizers.ResourceManager) + roleAssignmentSchedulesClient, err := roleassignmentschedules.NewRoleAssignmentSchedulesClientWithBaseURI(o.Environment.ResourceManager) + if err != nil { + return nil, fmt.Errorf("creating roleAssignmentSchedulesClient: %+v", err) + } + o.Configure(roleAssignmentSchedulesClient.Client, o.Authorizers.ResourceManager) + roleEligibilityScheduleRequestClient, err := roleeligibilityschedulerequests.NewRoleEligibilityScheduleRequestsClientWithBaseURI(o.Environment.ResourceManager) if err != nil { return nil, fmt.Errorf("creating roleEligibilityScheduleRequestClient: %+v", err) @@ -57,6 +67,12 @@ func NewClient(o *common.ClientOptions) (*Client, error) { } o.Configure(roleEligibilityScheduleInstancesClient.Client, o.Authorizers.ResourceManager) + roleEligibilitySchedulesClient, err := roleeligibilityschedules.NewRoleEligibilitySchedulesClientWithBaseURI(o.Environment.ResourceManager) + if err != nil { + return nil, fmt.Errorf("creating roleEligibilitySchedulesClient: %+v", err) + } + o.Configure(roleEligibilitySchedulesClient.Client, o.Authorizers.ResourceManager) + scopedRoleAssignmentsClient, err := roleassignments.NewRoleAssignmentsClientWithBaseURI(o.Environment.ResourceManager) if err != nil { return nil, fmt.Errorf("building Role Assignment Client: %+v", err) @@ -73,8 +89,10 @@ func NewClient(o *common.ClientOptions) (*Client, error) { RoleAssignmentsClient: &roleAssignmentsClient, RoleAssignmentScheduleRequestClient: roleAssignmentScheduleRequestsClient, RoleAssignmentScheduleInstancesClient: roleAssignmentScheduleInstancesClient, + RoleAssignmentSchedulesClient: roleAssignmentSchedulesClient, RoleEligibilityScheduleRequestClient: roleEligibilityScheduleRequestClient, RoleEligibilityScheduleInstancesClient: roleEligibilityScheduleInstancesClient, + RoleEligibilitySchedulesClient: roleEligibilitySchedulesClient, ScopedRoleAssignmentsClient: scopedRoleAssignmentsClient, ScopedRoleDefinitionsClient: scopedRoleDefinitionsClient, }, nil diff --git a/internal/services/authorization/parse/pim_role_assignment.go b/internal/services/authorization/parse/pim_role_assignment.go index 804807b0a919..0bfd5ea37b83 100644 --- a/internal/services/authorization/parse/pim_role_assignment.go +++ b/internal/services/authorization/parse/pim_role_assignment.go @@ -9,8 +9,8 @@ import ( "strings" "github.com/hashicorp/go-azure-helpers/resourcemanager/commonids" - "github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentscheduleinstances" - "github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityscheduleinstances" + "github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules" + "github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules" ) type PimRoleAssignmentId struct { @@ -70,20 +70,20 @@ func RoleAssignmentScheduleID(input string) (*string, error) { return &matches[1], nil } -func RoleAssignmentScheduleIdFromInstance(r *roleassignmentscheduleinstances.RoleAssignmentScheduleInstance) (*string, error) { - re := regexp.MustCompile(`^.+/providers/Microsoft.Authorization/roleAssignmentSchedules/(.+)`) - matches := re.FindStringSubmatch(*r.Properties.RoleAssignmentScheduleId) +func RoleAssignmentScheduleRequestIdFromSchedule(r *roleassignmentschedules.RoleAssignmentSchedule) (*string, error) { + re := regexp.MustCompile(`^.+/providers/Microsoft.Authorization/roleAssignmentScheduleRequests/(.+)`) + matches := re.FindStringSubmatch(*r.Properties.RoleAssignmentScheduleRequestId) if len(matches) != 2 { - return nil, fmt.Errorf("parsing %s", *r.Properties.RoleAssignmentScheduleId) + return nil, fmt.Errorf("parsing %s", *r.Properties.RoleAssignmentScheduleRequestId) } return &matches[1], nil } -func RoleEligibilityScheduleIdFromInstance(r *roleeligibilityscheduleinstances.RoleEligibilityScheduleInstance) (*string, error) { - re := regexp.MustCompile(`^.+/providers/Microsoft.Authorization/roleEligibilitySchedules/(.+)`) - matches := re.FindStringSubmatch(*r.Properties.RoleEligibilityScheduleId) +func RoleEligibilityScheduleRequestIdFromSchedule(r *roleeligibilityschedules.RoleEligibilitySchedule) (*string, error) { + re := regexp.MustCompile(`^.+/providers/Microsoft.Authorization/roleEligibilityScheduleRequests/(.+)`) + matches := re.FindStringSubmatch(*r.Properties.RoleEligibilityScheduleRequestId) if len(matches) != 2 { - return nil, fmt.Errorf("parsing %s", *r.Properties.RoleEligibilityScheduleId) + return nil, fmt.Errorf("parsing %s", *r.Properties.RoleEligibilityScheduleRequestId) } return &matches[1], nil } diff --git a/internal/services/authorization/pim_active_role_assignment_resource.go b/internal/services/authorization/pim_active_role_assignment_resource.go index 692eb877e5a4..28d34e9c29d7 100644 --- a/internal/services/authorization/pim_active_role_assignment_resource.go +++ b/internal/services/authorization/pim_active_role_assignment_resource.go @@ -16,8 +16,8 @@ import ( "github.com/hashicorp/go-azure-helpers/lang/pointer" "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/roleassignmentscheduleinstances" "github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedulerequests" + "github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules" "github.com/hashicorp/go-uuid" "github.com/hashicorp/terraform-provider-azurerm/internal/sdk" "github.com/hashicorp/terraform-provider-azurerm/internal/services/authorization/parse" @@ -166,7 +166,7 @@ func (r PimActiveRoleAssignmentResource) Create() sdk.ResourceFunc { return sdk.ResourceFunc{ Timeout: 30 * time.Minute, Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { - clientInstances := metadata.Client.Authorization.RoleAssignmentScheduleInstancesClient + clientSchedules := metadata.Client.Authorization.RoleAssignmentSchedulesClient clientRequest := metadata.Client.Authorization.RoleAssignmentScheduleRequestClient scope := metadata.ResourceData.Get("scope").(string) @@ -175,23 +175,24 @@ func (r PimActiveRoleAssignmentResource) Create() sdk.ResourceFunc { id := parse.NewPimRoleAssignmentID(scope, roleDefinitionId, principalId) - filter := &roleassignmentscheduleinstances.ListForScopeOperationOptions{ - Filter: pointer.To(fmt.Sprintf("(principalId eq '%s' and roleDefinitionId eq '%s')", id.PrincipalId, id.RoleDefinitionId)), + filter := &roleassignmentschedules.ListForScopeOperationOptions{ + Filter: pointer.To(fmt.Sprintf("(principalId eq '%s')", id.PrincipalId)), } - items, err := clientInstances.ListForScopeComplete(ctx, id.ScopeID(), *filter) + items, err := clientSchedules.ListForScopeComplete(ctx, id.ScopeID(), *filter) if err != nil { return fmt.Errorf("listing role assignments on scope %s: %+v", id, err) } for _, item := range items.Items { - if *item.Properties.MemberType == roleassignmentscheduleinstances.MemberTypeDirect && + if *item.Properties.MemberType == roleassignmentschedules.MemberTypeDirect && + strings.EqualFold(*item.Properties.RoleDefinitionId, id.RoleDefinitionId) && strings.EqualFold(*item.Properties.Scope, id.Scope) { return metadata.ResourceRequiresImport(r.ResourceType(), id) } } var config PimActiveRoleAssignmentResourceSchema - if err := metadata.Decode(&config); err != nil { + if err = metadata.Decode(&config); err != nil { return fmt.Errorf("decoding: %+v", err) } @@ -201,7 +202,7 @@ func (r PimActiveRoleAssignmentResource) Create() sdk.ResourceFunc { payload.Properties.RequestType = roleassignmentschedulerequests.RequestTypeAdminAssign - uuid, err := uuid.GenerateUUID() + roleAssignmentScheduleRequestId, err := uuid.GenerateUUID() if err != nil { return fmt.Errorf("generating uuid: %+v", err) } @@ -211,7 +212,7 @@ func (r PimActiveRoleAssignmentResource) Create() sdk.ResourceFunc { return fmt.Errorf("internal error: context has no deadline") } - requestId := roleassignmentschedulerequests.NewScopedRoleAssignmentScheduleRequestID(config.Scope, uuid) + requestId := roleassignmentschedulerequests.NewScopedRoleAssignmentScheduleRequestID(config.Scope, roleAssignmentScheduleRequestId) stateConf := &pluginsdk.StateChangeConf{ Pending: []string{"Missing"}, Target: []string{"Created"}, @@ -223,11 +224,11 @@ func (r PimActiveRoleAssignmentResource) Create() sdk.ResourceFunc { return fmt.Errorf("waiting for %s to be created: %+v", id, err) } - // wait for resource to exist + // Wait for resource to exist stateConf = &pluginsdk.StateChangeConf{ Pending: []string{"Missing"}, Target: []string{"Found"}, - Refresh: waitForActiveRoleAssignment(ctx, clientInstances, config.Scope, config.PrincipalId, config.RoleDefinitionId, "Found"), + Refresh: waitForActiveRoleAssignment(ctx, clientSchedules, config.Scope, config.PrincipalId, config.RoleDefinitionId, "Found"), MinTimeout: 30 * time.Second, Timeout: time.Until(deadline), } @@ -247,7 +248,7 @@ func (r PimActiveRoleAssignmentResource) Read() sdk.ResourceFunc { Timeout: 5 * time.Minute, Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { - clientInstances := metadata.Client.Authorization.RoleAssignmentScheduleInstancesClient + clientSchedules := metadata.Client.Authorization.RoleAssignmentSchedulesClient clientRequest := metadata.Client.Authorization.RoleAssignmentScheduleRequestClient schema := PimActiveRoleAssignmentResourceSchema{} @@ -257,33 +258,34 @@ func (r PimActiveRoleAssignmentResource) Read() sdk.ResourceFunc { return err } - filter := &roleassignmentscheduleinstances.ListForScopeOperationOptions{ - Filter: pointer.To(fmt.Sprintf("(principalId eq '%s' and roleDefinitionId eq '%s')", id.PrincipalId, id.RoleDefinitionId)), + filter := &roleassignmentschedules.ListForScopeOperationOptions{ + Filter: pointer.To(fmt.Sprintf("(principalId eq '%s')", id.PrincipalId)), } - items, err := clientInstances.ListForScopeComplete(ctx, id.ScopeID(), *filter) + items, err := clientSchedules.ListForScopeComplete(ctx, id.ScopeID(), *filter) if err != nil { return fmt.Errorf("listing role assignments on scope %s: %+v", id, err) } - var instance *roleassignmentscheduleinstances.RoleAssignmentScheduleInstance + var schedule *roleassignmentschedules.RoleAssignmentSchedule for _, item := range items.Items { - if *item.Properties.MemberType == roleassignmentscheduleinstances.MemberTypeDirect && + if *item.Properties.MemberType == roleassignmentschedules.MemberTypeDirect && + strings.EqualFold(*item.Properties.RoleDefinitionId, id.RoleDefinitionId) && strings.EqualFold(*item.Properties.Scope, id.Scope) { - instance = &item + schedule = &item break } } - if instance == nil { - return fmt.Errorf("retrieving %s: %+v", *id, err) + if schedule == nil { + return metadata.MarkAsGone(*id) } schema.Scope = id.Scope - guid, err := parse.RoleAssignmentScheduleIdFromInstance(instance) + roleAssignmentScheduleRequestId, err := parse.RoleAssignmentScheduleRequestIdFromSchedule(schedule) if err != nil { return err } - scheduleRequestId := roleassignmentschedulerequests.NewScopedRoleAssignmentScheduleRequestID(id.Scope, *guid) + scheduleRequestId := roleassignmentschedulerequests.NewScopedRoleAssignmentScheduleRequestID(id.Scope, *roleAssignmentScheduleRequestId) resp, err := clientRequest.Get(ctx, scheduleRequestId) if err != nil { @@ -296,7 +298,7 @@ func (r PimActiveRoleAssignmentResource) Read() sdk.ResourceFunc { if model := resp.Model; model != nil { schema.Scope = id.Scope - if err := r.mapRoleAssignmentScheduleRequestToPimActiveRoleAssignmentResourceSchema(*model, &schema); err != nil { + if err = r.mapRoleAssignmentScheduleRequestToPimActiveRoleAssignmentResourceSchema(*model, &schema); err != nil { return fmt.Errorf("flattening model: %+v", err) } } @@ -320,7 +322,7 @@ func (PimActiveRoleAssignmentResource) Delete() sdk.ResourceFunc { Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { clientRequest := metadata.Client.Authorization.RoleAssignmentScheduleRequestClient - clientInstances := metadata.Client.Authorization.RoleAssignmentScheduleInstancesClient + clientSchedules := metadata.Client.Authorization.RoleAssignmentSchedulesClient id, err := parse.PimRoleAssignmentID(metadata.ResourceData.Id()) if err != nil { @@ -328,53 +330,94 @@ func (PimActiveRoleAssignmentResource) Delete() sdk.ResourceFunc { } var config PimActiveRoleAssignmentResourceSchema - if err := metadata.Decode(&config); err != nil { + if err = metadata.Decode(&config); err != nil { return fmt.Errorf("decoding: %+v", err) } - payload := roleassignmentschedulerequests.RoleAssignmentScheduleRequest{} - payload.Properties = &roleassignmentschedulerequests.RoleAssignmentScheduleRequestProperties{} - payload.Properties.PrincipalId = id.PrincipalId - payload.Properties.RoleDefinitionId = id.RoleDefinitionId - payload.Properties.RequestType = roleassignmentschedulerequests.RequestTypeAdminRemove - payload.Properties.ScheduleInfo = &roleassignmentschedulerequests.RoleAssignmentScheduleRequestPropertiesScheduleInfo{} - if config.Justification != "" { - payload.Properties.Justification = &config.Justification + deadline, ok := ctx.Deadline() + if !ok { + return fmt.Errorf("internal error: context has no deadline") } - if len(config.TicketInfo) == 1 { - payload.Properties.TicketInfo = &roleassignmentschedulerequests.RoleAssignmentScheduleRequestPropertiesTicketInfo{} - payload.Properties.TicketInfo.TicketNumber = &config.TicketInfo[0].TicketNumber - payload.Properties.TicketInfo.TicketSystem = &config.TicketInfo[0].TicketSystem + + filter := roleassignmentschedules.ListForScopeOperationOptions{ + Filter: pointer.To(fmt.Sprintf("(principalId eq '%s')", id.PrincipalId)), } - uuid, err := uuid.GenerateUUID() + items, err := clientSchedules.ListForScopeComplete(ctx, id.ScopeID(), filter) if err != nil { - return fmt.Errorf("generating uuid: %+v", err) + return fmt.Errorf("listing role assignments on scope %s: %+v", id, err) } - deleteId := roleassignmentschedulerequests.NewScopedRoleAssignmentScheduleRequestID(id.Scope, uuid) - deadline, ok := ctx.Deadline() - if !ok { - return fmt.Errorf("internal error: context has no deadline") + var schedule *roleassignmentschedules.RoleAssignmentSchedule + for _, item := range items.Items { + if *item.Properties.MemberType == roleassignmentschedules.MemberTypeDirect && + strings.EqualFold(*item.Properties.RoleDefinitionId, id.RoleDefinitionId) && + strings.EqualFold(*item.Properties.Scope, id.Scope) { + schedule = &item + break + } } - // wait for resource to deleted - stateConf := &pluginsdk.StateChangeConf{ - Pending: []string{"Exist"}, - Target: []string{"Deleted"}, - Refresh: deleteActiveRoleAssignment(ctx, clientRequest, deleteId, &payload), - MinTimeout: 1 * time.Minute, - Timeout: time.Until(deadline), + if schedule == nil { + log.Printf("[DEBUG] Role Eligibility request has been canceled.") + return nil } - if _, err = stateConf.WaitForStateContext(ctx); err != nil { - return fmt.Errorf("waiting for %s to become deleted: %+v", id, err) + switch *schedule.Properties.Status { + case roleassignmentschedules.StatusPendingApproval, roleassignmentschedules.StatusPendingApprovalProvisioning, + roleassignmentschedules.StatusPendingEvaluation, roleassignmentschedules.StatusGranted, + roleassignmentschedules.StatusPendingProvisioning, roleassignmentschedules.StatusPendingAdminDecision: + // Pending role assignments should be removed by Cancel operation + roleAssignmentScheduleRequestId, err := parse.RoleAssignmentScheduleRequestIdFromSchedule(schedule) + if err != nil { + return err + } + scheduleRequestId := roleassignmentschedulerequests.NewScopedRoleAssignmentScheduleRequestID(id.Scope, *roleAssignmentScheduleRequestId) + if _, err = clientRequest.Cancel(ctx, scheduleRequestId); err != nil { + return err + } + default: + // Remove active role assignment by sending an AdminRemove request + payload := roleassignmentschedulerequests.RoleAssignmentScheduleRequest{} + payload.Properties = &roleassignmentschedulerequests.RoleAssignmentScheduleRequestProperties{} + payload.Properties.PrincipalId = id.PrincipalId + payload.Properties.RoleDefinitionId = id.RoleDefinitionId + payload.Properties.RequestType = roleassignmentschedulerequests.RequestTypeAdminRemove + payload.Properties.ScheduleInfo = &roleassignmentschedulerequests.RoleAssignmentScheduleRequestPropertiesScheduleInfo{} + + if config.Justification != "" { + payload.Properties.Justification = &config.Justification + } + if len(config.TicketInfo) == 1 { + payload.Properties.TicketInfo = &roleassignmentschedulerequests.RoleAssignmentScheduleRequestPropertiesTicketInfo{} + payload.Properties.TicketInfo.TicketNumber = &config.TicketInfo[0].TicketNumber + payload.Properties.TicketInfo.TicketSystem = &config.TicketInfo[0].TicketSystem + } + + roleAssignmentScheduleRequestId, err := uuid.GenerateUUID() + if err != nil { + return fmt.Errorf("generating uuid: %+v", err) + } + deleteId := roleassignmentschedulerequests.NewScopedRoleAssignmentScheduleRequestID(id.Scope, roleAssignmentScheduleRequestId) + + // Wait for resource to deleted + stateConf := &pluginsdk.StateChangeConf{ + Pending: []string{"Exist"}, + Target: []string{"Deleted"}, + Refresh: deleteActiveRoleAssignment(ctx, clientRequest, deleteId, &payload), + MinTimeout: 1 * time.Minute, + Timeout: time.Until(deadline), + } + + if _, err = stateConf.WaitForStateContext(ctx); err != nil { + return fmt.Errorf("waiting for %s to become deleted: %+v", id, err) + } } - // wait for role assignment to be missing - stateConf = &pluginsdk.StateChangeConf{ + // Wait for role assignment to be missing + stateConf := &pluginsdk.StateChangeConf{ Pending: []string{"Found"}, Target: []string{"Missing"}, - Refresh: waitForActiveRoleAssignment(ctx, clientInstances, id.Scope, id.PrincipalId, id.RoleDefinitionId, "Missing"), + Refresh: waitForActiveRoleAssignment(ctx, clientSchedules, id.Scope, id.PrincipalId, id.RoleDefinitionId, "Missing"), MinTimeout: 30 * time.Second, Timeout: time.Until(deadline), } @@ -602,7 +645,6 @@ func (r PimActiveRoleAssignmentResource) mapRoleAssignmentScheduleRequestPropert func createActiveRoleAssignment(ctx context.Context, client *roleassignmentschedulerequests.RoleAssignmentScheduleRequestsClient, id roleassignmentschedulerequests.ScopedRoleAssignmentScheduleRequestId, payload *roleassignmentschedulerequests.RoleAssignmentScheduleRequest) pluginsdk.StateRefreshFunc { return func() (interface{}, string, error) { - // Azure can error when the subject doesn't exist yet due to AAD replication // Retry deletes while that error exists. result, err := client.Create(ctx, id, *payload) @@ -618,25 +660,25 @@ func createActiveRoleAssignment(ctx context.Context, client *roleassignmentsched } } -func waitForActiveRoleAssignment(ctx context.Context, client *roleassignmentscheduleinstances.RoleAssignmentScheduleInstancesClient, scope string, principalId string, roleDefinitionId string, target string) pluginsdk.StateRefreshFunc { +func waitForActiveRoleAssignment(ctx context.Context, client *roleassignmentschedules.RoleAssignmentSchedulesClient, scope string, principalId string, roleDefinitionId string, target string) pluginsdk.StateRefreshFunc { return func() (interface{}, string, error) { log.Printf("[DEBUG] Checking to see if Role Assignment is %s on %q with role %q for %q.", target, scope, roleDefinitionId, principalId) - instanceId := commonids.NewScopeID(scope) - filter := &roleassignmentscheduleinstances.ListForScopeOperationOptions{ + scopeId := commonids.NewScopeID(scope) + filter := &roleassignmentschedules.ListForScopeOperationOptions{ Filter: pointer.To(fmt.Sprintf("assignedTo('%s')", principalId)), } - items, err := client.ListForScopeComplete(ctx, instanceId, *filter) + items, err := client.ListForScopeComplete(ctx, scopeId, *filter) if err != nil { - return nil, "", fmt.Errorf("listing role assignments on scope %s: %+v", instanceId, err) + return nil, "", fmt.Errorf("listing role assignments on scope %s: %+v", scopeId, err) } state := "Missing" var result interface{} for _, item := range items.Items { if *item.Properties.RoleDefinitionId == roleDefinitionId && - *item.Properties.MemberType == roleassignmentscheduleinstances.MemberTypeDirect && + *item.Properties.MemberType == roleassignmentschedules.MemberTypeDirect && strings.EqualFold(*item.Properties.Scope, scope) { state = "Found" result = item @@ -645,7 +687,7 @@ func waitForActiveRoleAssignment(ctx context.Context, client *roleassignmentsche } if target == "Missing" && state == "Missing" { - result = &roleassignmentscheduleinstances.RoleAssignmentScheduleInstance{} + result = &roleassignmentschedules.RoleAssignmentSchedule{} } return result, state, nil @@ -654,7 +696,6 @@ func waitForActiveRoleAssignment(ctx context.Context, client *roleassignmentsche func deleteActiveRoleAssignment(ctx context.Context, client *roleassignmentschedulerequests.RoleAssignmentScheduleRequestsClient, id roleassignmentschedulerequests.ScopedRoleAssignmentScheduleRequestId, payload *roleassignmentschedulerequests.RoleAssignmentScheduleRequest) pluginsdk.StateRefreshFunc { return func() (interface{}, string, error) { - // Azure can error when the role hasn't existed for less than 5 minutes. // Retry deletes while that error exists. result, err := client.Create(ctx, id, *payload) diff --git a/internal/services/authorization/pim_active_role_assignment_test.go b/internal/services/authorization/pim_active_role_assignment_resource_test.go similarity index 86% rename from internal/services/authorization/pim_active_role_assignment_test.go rename to internal/services/authorization/pim_active_role_assignment_resource_test.go index 43edceecd6ad..75bc91ab039b 100644 --- a/internal/services/authorization/pim_active_role_assignment_test.go +++ b/internal/services/authorization/pim_active_role_assignment_resource_test.go @@ -6,10 +6,11 @@ package authorization_test import ( "context" "fmt" + "strings" "testing" "github.com/hashicorp/go-azure-helpers/lang/pointer" - "github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentscheduleinstances" + "github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules" "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" @@ -95,6 +96,22 @@ func TestAccPimActiveRoleAssignment_update(t *testing.T) { }) } +func TestAccPimActiveRoleAssignment_pending(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_pim_active_role_assignment", "test") + r := PimActiveRoleAssignmentResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.pending(), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("scope").Exists(), + ), + }, + data.ImportStep("schedule.0.start_date_time"), + }) +} + func TestAccPimActiveRoleAssignment_requiresImport(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_pim_active_role_assignment", "test") @@ -136,11 +153,11 @@ func (r PimActiveRoleAssignmentResource) Exists(ctx context.Context, client *cli return utils.Bool(false), err } - filter := &roleassignmentscheduleinstances.ListForScopeOperationOptions{ - Filter: pointer.To(fmt.Sprintf("(principalId eq '%s' and roleDefinitionId eq '%s')", id.PrincipalId, id.RoleDefinitionId)), + filter := &roleassignmentschedules.ListForScopeOperationOptions{ + Filter: pointer.To(fmt.Sprintf("(principalId eq '%s')", id.PrincipalId)), } - items, err := client.Authorization.RoleAssignmentScheduleInstancesClient.ListForScopeComplete(ctx, id.ScopeID(), *filter) + items, err := client.Authorization.RoleAssignmentSchedulesClient.ListForScopeComplete(ctx, id.ScopeID(), *filter) if err != nil { return nil, fmt.Errorf("listing role assignments on scope %s: %+v", id, err) } @@ -148,7 +165,8 @@ func (r PimActiveRoleAssignmentResource) Exists(ctx context.Context, client *cli foundDirectAssignment := false for _, i := range items.Items { - if *i.Properties.MemberType == roleassignmentscheduleinstances.MemberTypeDirect { + if *i.Properties.MemberType == roleassignmentschedules.MemberTypeDirect && + strings.EqualFold(*i.Properties.RoleDefinitionId, id.RoleDefinitionId) { foundDirectAssignment = true break } @@ -319,7 +337,7 @@ data "azurerm_subscription" "primary" {} data "azurerm_client_config" "test" {} data "azurerm_role_definition" "test" { - name = "Workbook Reader" + name = "Workbook Contributor" } resource "time_static" "test" {} @@ -416,3 +434,39 @@ resource "azurerm_pim_active_role_assignment" "test" { } ` } + +func (PimActiveRoleAssignmentResource) pending() string { + return ` +data "azurerm_subscription" "primary" {} + +data "azurerm_client_config" "test" {} + +data "azurerm_role_definition" "test" { + name = "Key Vault Reader" +} + +resource "time_offset" "test" { + offset_days = 1 +} + +resource "azurerm_pim_active_role_assignment" "test" { + scope = data.azurerm_subscription.primary.id + role_definition_id = "${data.azurerm_subscription.primary.id}${data.azurerm_role_definition.test.id}" + principal_id = data.azurerm_client_config.test.object_id + + schedule { + start_date_time = time_offset.test.rfc3339 + expiration { + duration_hours = 8 + } + } + + justification = "Expiration Duration Set" + + ticket { + number = "1" + system = "example ticket system" + } +} +` +} diff --git a/internal/services/authorization/pim_eligible_role_assignment_resource.go b/internal/services/authorization/pim_eligible_role_assignment_resource.go index a6bdee067420..61dfc6e8cbb4 100644 --- a/internal/services/authorization/pim_eligible_role_assignment_resource.go +++ b/internal/services/authorization/pim_eligible_role_assignment_resource.go @@ -16,8 +16,8 @@ import ( "github.com/hashicorp/go-azure-helpers/lang/pointer" "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/roleeligibilityscheduleinstances" "github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedulerequests" + "github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules" "github.com/hashicorp/go-uuid" "github.com/hashicorp/terraform-provider-azurerm/internal/sdk" "github.com/hashicorp/terraform-provider-azurerm/internal/services/authorization/parse" @@ -166,7 +166,7 @@ func (r PimEligibleRoleAssignmentResource) Create() sdk.ResourceFunc { return sdk.ResourceFunc{ Timeout: 30 * time.Minute, Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { - clientInstances := metadata.Client.Authorization.RoleEligibilityScheduleInstancesClient + clientSchedules := metadata.Client.Authorization.RoleEligibilitySchedulesClient clientRequest := metadata.Client.Authorization.RoleEligibilityScheduleRequestClient scope := metadata.ResourceData.Get("scope").(string) @@ -175,23 +175,24 @@ func (r PimEligibleRoleAssignmentResource) Create() sdk.ResourceFunc { id := parse.NewPimRoleAssignmentID(scope, roleDefinitionId, principalId) - filter := &roleeligibilityscheduleinstances.ListForScopeOperationOptions{ - Filter: pointer.To(fmt.Sprintf("(principalId eq '%s' and roleDefinitionId eq '%s')", id.PrincipalId, id.RoleDefinitionId)), + filter := &roleeligibilityschedules.ListForScopeOperationOptions{ + Filter: pointer.To(fmt.Sprintf("(principalId eq '%s')", id.PrincipalId)), } - items, err := clientInstances.ListForScopeComplete(ctx, id.ScopeID(), *filter) + items, err := clientSchedules.ListForScopeComplete(ctx, id.ScopeID(), *filter) if err != nil { return fmt.Errorf("listing role assignments on scope %s: %+v", id, err) } for _, item := range items.Items { - if *item.Properties.MemberType == roleeligibilityscheduleinstances.MemberTypeDirect && + if *item.Properties.MemberType == roleeligibilityschedules.MemberTypeDirect && + strings.EqualFold(*item.Properties.RoleDefinitionId, roleDefinitionId) && strings.EqualFold(*item.Properties.Scope, id.Scope) { return metadata.ResourceRequiresImport(r.ResourceType(), id) } } var config PimEligibleRoleAssignmentResourceSchema - if err := metadata.Decode(&config); err != nil { + if err = metadata.Decode(&config); err != nil { return fmt.Errorf("decoding: %+v", err) } @@ -201,12 +202,12 @@ func (r PimEligibleRoleAssignmentResource) Create() sdk.ResourceFunc { payload.Properties.RequestType = roleeligibilityschedulerequests.RequestTypeAdminAssign - uuid, err := uuid.GenerateUUID() + roleEligibilityScheduleRequestId, err := uuid.GenerateUUID() if err != nil { return fmt.Errorf("generating uuid: %+v", err) } - requestId := roleeligibilityschedulerequests.NewScopedRoleEligibilityScheduleRequestID(config.Scope, uuid) + requestId := roleeligibilityschedulerequests.NewScopedRoleEligibilityScheduleRequestID(config.Scope, roleEligibilityScheduleRequestId) deadline, ok := ctx.Deadline() if !ok { @@ -228,7 +229,7 @@ func (r PimEligibleRoleAssignmentResource) Create() sdk.ResourceFunc { stateConf = &pluginsdk.StateChangeConf{ Pending: []string{"Missing"}, Target: []string{"Found"}, - Refresh: waitForEligibleRoleAssignmentSchedule(ctx, clientInstances, config.Scope, config.PrincipalId, config.RoleDefinitionId, "Found"), + Refresh: waitForEligibleRoleAssignmentSchedule(ctx, clientSchedules, config.Scope, config.PrincipalId, config.RoleDefinitionId, "Found"), MinTimeout: 30 * time.Second, Timeout: time.Until(deadline), } @@ -247,8 +248,8 @@ func (r PimEligibleRoleAssignmentResource) Read() sdk.ResourceFunc { return sdk.ResourceFunc{ Timeout: 5 * time.Minute, Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { - clientInstances := metadata.Client.Authorization.RoleEligibilityScheduleInstancesClient clientRequest := metadata.Client.Authorization.RoleEligibilityScheduleRequestClient + clientSchedules := metadata.Client.Authorization.RoleEligibilitySchedulesClient schema := PimEligibleRoleAssignmentResourceSchema{} @@ -257,33 +258,34 @@ func (r PimEligibleRoleAssignmentResource) Read() sdk.ResourceFunc { return err } - filter := &roleeligibilityscheduleinstances.ListForScopeOperationOptions{ - Filter: pointer.To(fmt.Sprintf("(principalId eq '%s' and roleDefinitionId eq '%s')", id.PrincipalId, id.RoleDefinitionId)), + filter := &roleeligibilityschedules.ListForScopeOperationOptions{ + Filter: pointer.To(fmt.Sprintf("(principalId eq '%s')", id.PrincipalId)), } - items, err := clientInstances.ListForScopeComplete(ctx, id.ScopeID(), *filter) + items, err := clientSchedules.ListForScopeComplete(ctx, id.ScopeID(), *filter) if err != nil { return fmt.Errorf("listing role assignments on scope %s: %+v", id, err) } - var instance *roleeligibilityscheduleinstances.RoleEligibilityScheduleInstance + var schedule *roleeligibilityschedules.RoleEligibilitySchedule for _, item := range items.Items { - if *item.Properties.MemberType == roleeligibilityscheduleinstances.MemberTypeDirect && + if *item.Properties.MemberType == roleeligibilityschedules.MemberTypeDirect && + strings.EqualFold(*item.Properties.RoleDefinitionId, id.RoleDefinitionId) && strings.EqualFold(*item.Properties.Scope, id.Scope) { - instance = &item + schedule = &item break } } - if instance == nil { - return fmt.Errorf("retrieving %s: %+v", *id, err) + if schedule == nil { + return metadata.MarkAsGone(*id) } schema.Scope = id.Scope - guid, err := parse.RoleEligibilityScheduleIdFromInstance(instance) + roleEligibilityScheduleRequestId, err := parse.RoleEligibilityScheduleRequestIdFromSchedule(schedule) if err != nil { return err } - scheduleRequestId := roleeligibilityschedulerequests.NewScopedRoleEligibilityScheduleRequestID(id.Scope, *guid) + scheduleRequestId := roleeligibilityschedulerequests.NewScopedRoleEligibilityScheduleRequestID(id.Scope, *roleEligibilityScheduleRequestId) resp, err := clientRequest.Get(ctx, scheduleRequestId) if err != nil { @@ -296,7 +298,7 @@ func (r PimEligibleRoleAssignmentResource) Read() sdk.ResourceFunc { if model := resp.Model; model != nil { schema.Scope = id.Scope - if err := r.mapRoleAssignmentScheduleRequestToPimEligibleRoleAssignmentResourceSchema(*model, &schema); err != nil { + if err = r.mapRoleAssignmentScheduleRequestToPimEligibleRoleAssignmentResourceSchema(*model, &schema); err != nil { return fmt.Errorf("flattening model: %+v", err) } } @@ -317,7 +319,7 @@ func (PimEligibleRoleAssignmentResource) Delete() sdk.ResourceFunc { return sdk.ResourceFunc{ Timeout: 30 * time.Minute, Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { - clientInstances := metadata.Client.Authorization.RoleEligibilityScheduleInstancesClient + clientSchedules := metadata.Client.Authorization.RoleEligibilitySchedulesClient clientRequest := metadata.Client.Authorization.RoleEligibilityScheduleRequestClient id, err := parse.PimRoleAssignmentID(metadata.ResourceData.Id()) @@ -329,51 +331,91 @@ func (PimEligibleRoleAssignmentResource) Delete() sdk.ResourceFunc { if err := metadata.Decode(&config); err != nil { return fmt.Errorf("decoding: %+v", err) } - payload := roleeligibilityschedulerequests.RoleEligibilityScheduleRequest{} - payload.Properties = &roleeligibilityschedulerequests.RoleEligibilityScheduleRequestProperties{} - payload.Properties.PrincipalId = id.PrincipalId - payload.Properties.RoleDefinitionId = id.RoleDefinitionId - payload.Properties.RequestType = roleeligibilityschedulerequests.RequestTypeAdminRemove - payload.Properties.ScheduleInfo = &roleeligibilityschedulerequests.RoleEligibilityScheduleRequestPropertiesScheduleInfo{} - if config.Justification != "" { - payload.Properties.Justification = &config.Justification + deadline, ok := ctx.Deadline() + if !ok { + return fmt.Errorf("internal error: context has no deadline") } - if len(config.TicketInfo) == 1 { - payload.Properties.TicketInfo = &roleeligibilityschedulerequests.RoleEligibilityScheduleRequestPropertiesTicketInfo{} - payload.Properties.TicketInfo.TicketNumber = &config.TicketInfo[0].TicketNumber - payload.Properties.TicketInfo.TicketSystem = &config.TicketInfo[0].TicketSystem + + filter := roleeligibilityschedules.ListForScopeOperationOptions{ + Filter: pointer.To(fmt.Sprintf("(principalId eq '%s')", id.PrincipalId)), } - uuid, err := uuid.GenerateUUID() + items, err := clientSchedules.ListForScopeComplete(ctx, id.ScopeID(), filter) if err != nil { - return fmt.Errorf("generating uuid: %+v", err) + return fmt.Errorf("listing role assignments on scope %s: %+v", id, err) } - deleteId := roleeligibilityschedulerequests.NewScopedRoleEligibilityScheduleRequestID(id.Scope, uuid) - deadline, ok := ctx.Deadline() - if !ok { - return fmt.Errorf("internal error: context has no deadline") + var schedule *roleeligibilityschedules.RoleEligibilitySchedule + for _, item := range items.Items { + if *item.Properties.MemberType == roleeligibilityschedules.MemberTypeDirect && + strings.EqualFold(*item.Properties.RoleDefinitionId, id.RoleDefinitionId) && + strings.EqualFold(*item.Properties.Scope, id.Scope) { + schedule = &item + break + } } - - // wait for resource to deleted - stateConf := &pluginsdk.StateChangeConf{ - Pending: []string{"Exist"}, - Target: []string{"Deleted"}, - Refresh: deleteEligibilityRoleAssignmentSchedule(ctx, clientRequest, deleteId, &payload), - MinTimeout: 1 * time.Minute, - Timeout: time.Until(deadline), + if schedule == nil { + log.Printf("[DEBUG] Role Eligibility request has been canceled.") + return nil } - if _, err = stateConf.WaitForStateContext(ctx); err != nil { - return fmt.Errorf("waiting for %s to become deleted: %+v", id, err) + switch *schedule.Properties.Status { + case roleeligibilityschedules.StatusPendingApproval, roleeligibilityschedules.StatusPendingApprovalProvisioning, + roleeligibilityschedules.StatusPendingEvaluation, roleeligibilityschedules.StatusGranted, + roleeligibilityschedules.StatusPendingProvisioning, roleeligibilityschedules.StatusPendingAdminDecision: + // Pending role assignments should be removed by Cancel operation + roleEligibilityScheduleRequestId, err := parse.RoleEligibilityScheduleRequestIdFromSchedule(schedule) + if err != nil { + return err + } + scheduleRequestId := roleeligibilityschedulerequests.NewScopedRoleEligibilityScheduleRequestID(id.Scope, *roleEligibilityScheduleRequestId) + if _, err = clientRequest.Cancel(ctx, scheduleRequestId); err != nil { + return err + } + default: + // remove active role assignment + payload := roleeligibilityschedulerequests.RoleEligibilityScheduleRequest{} + payload.Properties = &roleeligibilityschedulerequests.RoleEligibilityScheduleRequestProperties{} + payload.Properties.PrincipalId = id.PrincipalId + payload.Properties.RoleDefinitionId = id.RoleDefinitionId + payload.Properties.RequestType = roleeligibilityschedulerequests.RequestTypeAdminRemove + payload.Properties.ScheduleInfo = &roleeligibilityschedulerequests.RoleEligibilityScheduleRequestPropertiesScheduleInfo{} + + if config.Justification != "" { + payload.Properties.Justification = &config.Justification + } + if len(config.TicketInfo) == 1 { + payload.Properties.TicketInfo = &roleeligibilityschedulerequests.RoleEligibilityScheduleRequestPropertiesTicketInfo{} + payload.Properties.TicketInfo.TicketNumber = &config.TicketInfo[0].TicketNumber + payload.Properties.TicketInfo.TicketSystem = &config.TicketInfo[0].TicketSystem + } + + roleEligibilityScheduleRequestId, err := uuid.GenerateUUID() + if err != nil { + return fmt.Errorf("generating uuid: %+v", err) + } + deleteId := roleeligibilityschedulerequests.NewScopedRoleEligibilityScheduleRequestID(id.Scope, roleEligibilityScheduleRequestId) + + // Wait for resource to deleted + stateConf := &pluginsdk.StateChangeConf{ + Pending: []string{"Exist"}, + Target: []string{"Deleted"}, + Refresh: deleteEligibilityRoleAssignmentSchedule(ctx, clientRequest, deleteId, &payload), + MinTimeout: 1 * time.Minute, + Timeout: time.Until(deadline), + } + + if _, err = stateConf.WaitForStateContext(ctx); err != nil { + return fmt.Errorf("waiting for %s to become deleted: %+v", id, err) + } } - // wait for role assignment to be missing - stateConf = &pluginsdk.StateChangeConf{ + // Wait for role assignment to be missing + stateConf := &pluginsdk.StateChangeConf{ Pending: []string{"Found"}, Target: []string{"Missing"}, - Refresh: waitForEligibleRoleAssignmentSchedule(ctx, clientInstances, id.Scope, id.PrincipalId, id.RoleDefinitionId, "Missing"), + Refresh: waitForEligibleRoleAssignmentSchedule(ctx, clientSchedules, id.Scope, id.PrincipalId, id.RoleDefinitionId, "Missing"), MinTimeout: 30 * time.Second, Timeout: time.Until(deadline), } @@ -602,7 +644,6 @@ func (r PimEligibleRoleAssignmentResource) mapRoleEligibilityScheduleRequestProp func createEligibilityRoleAssignment(ctx context.Context, client *roleeligibilityschedulerequests.RoleEligibilityScheduleRequestsClient, id roleeligibilityschedulerequests.ScopedRoleEligibilityScheduleRequestId, payload *roleeligibilityschedulerequests.RoleEligibilityScheduleRequest) pluginsdk.StateRefreshFunc { return func() (interface{}, string, error) { - // Azure can error when the subject doesn't exist yet due to AAD replication // Retry deletes while that error exists. result, err := client.Create(ctx, id, *payload) @@ -618,25 +659,25 @@ func createEligibilityRoleAssignment(ctx context.Context, client *roleeligibilit } } -func waitForEligibleRoleAssignmentSchedule(ctx context.Context, client *roleeligibilityscheduleinstances.RoleEligibilityScheduleInstancesClient, scope string, principalId string, roleDefinitionId string, target string) pluginsdk.StateRefreshFunc { +func waitForEligibleRoleAssignmentSchedule(ctx context.Context, client *roleeligibilityschedules.RoleEligibilitySchedulesClient, scope string, principalId string, roleDefinitionId string, target string) pluginsdk.StateRefreshFunc { return func() (interface{}, string, error) { log.Printf("[DEBUG] Checking to see if Role Assignment is %s on %q with role %q for %q.", target, scope, roleDefinitionId, principalId) - instanceId := commonids.NewScopeID(scope) - filter := &roleeligibilityscheduleinstances.ListForScopeOperationOptions{ + scopeId := commonids.NewScopeID(scope) + filter := &roleeligibilityschedules.ListForScopeOperationOptions{ Filter: pointer.To(fmt.Sprintf("assignedTo('%s')", principalId)), } - items, err := client.ListForScopeComplete(ctx, instanceId, *filter) + items, err := client.ListForScopeComplete(ctx, scopeId, *filter) if err != nil { - return nil, "", fmt.Errorf("listing role assignments on scope %s: %+v", instanceId, err) + return nil, "", fmt.Errorf("listing role assignments on scope %s: %+v", scopeId, err) } state := "Missing" var result interface{} for _, item := range items.Items { if *item.Properties.RoleDefinitionId == roleDefinitionId && - *item.Properties.MemberType == roleeligibilityscheduleinstances.MemberTypeDirect && + *item.Properties.MemberType == roleeligibilityschedules.MemberTypeDirect && strings.EqualFold(*item.Properties.Scope, scope) { state = "Found" result = item @@ -645,7 +686,7 @@ func waitForEligibleRoleAssignmentSchedule(ctx context.Context, client *roleelig } if target == "Missing" && state == "Missing" { - result = &roleeligibilityscheduleinstances.RoleEligibilityScheduleInstance{} + result = &roleeligibilityschedules.RoleEligibilitySchedule{} } return result, state, nil @@ -654,7 +695,6 @@ func waitForEligibleRoleAssignmentSchedule(ctx context.Context, client *roleelig func deleteEligibilityRoleAssignmentSchedule(ctx context.Context, client *roleeligibilityschedulerequests.RoleEligibilityScheduleRequestsClient, id roleeligibilityschedulerequests.ScopedRoleEligibilityScheduleRequestId, payload *roleeligibilityschedulerequests.RoleEligibilityScheduleRequest) pluginsdk.StateRefreshFunc { return func() (interface{}, string, error) { - // Azure can error when the role hasn't existed for less than 5 minutes. // Retry deletes while that error exists. result, err := client.Create(ctx, id, *payload) diff --git a/internal/services/authorization/pim_eligible_role_assignment_test.go b/internal/services/authorization/pim_eligible_role_assignment_resource_test.go similarity index 87% rename from internal/services/authorization/pim_eligible_role_assignment_test.go rename to internal/services/authorization/pim_eligible_role_assignment_resource_test.go index 848f46354d15..25405771d4ce 100644 --- a/internal/services/authorization/pim_eligible_role_assignment_test.go +++ b/internal/services/authorization/pim_eligible_role_assignment_resource_test.go @@ -6,10 +6,11 @@ package authorization_test import ( "context" "fmt" + "strings" "testing" "github.com/hashicorp/go-azure-helpers/lang/pointer" - "github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityscheduleinstances" + "github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules" "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" @@ -96,6 +97,22 @@ func TestAccPimEligibleRoleAssignment_update(t *testing.T) { }) } +func TestAccPimEligibleRoleAssignment_pending(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_pim_eligible_role_assignment", "test") + r := PimEligibleRoleAssignmentResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.pending(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("scope").Exists(), + ), + }, + data.ImportStep("schedule.0.start_date_time"), + }) +} + func TestAccPimEligibleRoleAssignment_requiresImport(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_pim_eligible_role_assignment", "test") @@ -135,18 +152,19 @@ func (r PimEligibleRoleAssignmentResource) Exists(ctx context.Context, client *c return utils.Bool(false), err } - filter := &roleeligibilityscheduleinstances.ListForScopeOperationOptions{ - Filter: pointer.To(fmt.Sprintf("(principalId eq '%s' and roleDefinitionId eq '%s')", id.PrincipalId, id.RoleDefinitionId)), + filter := &roleeligibilityschedules.ListForScopeOperationOptions{ + Filter: pointer.To(fmt.Sprintf("(principalId eq '%s')", id.PrincipalId)), } - items, err := client.Authorization.RoleEligibilityScheduleInstancesClient.ListForScopeComplete(ctx, id.ScopeID(), *filter) + items, err := client.Authorization.RoleEligibilitySchedulesClient.ListForScopeComplete(ctx, id.ScopeID(), *filter) if err != nil { return nil, fmt.Errorf("listing role eligibility on scope %s: %+v", id, err) } foundDirectAssignment := false for _, i := range items.Items { - if *i.Properties.MemberType == roleeligibilityscheduleinstances.MemberTypeDirect { + if *i.Properties.MemberType == roleeligibilityschedules.MemberTypeDirect && + strings.EqualFold(*i.Properties.RoleDefinitionId, id.RoleDefinitionId) { foundDirectAssignment = true break } @@ -469,3 +487,41 @@ resource "azurerm_pim_eligible_role_assignment" "test" { } `, aadGroup(data)) } + +func (PimEligibleRoleAssignmentResource) pending(data acceptance.TestData) string { + return fmt.Sprintf(` +data "azurerm_subscription" "primary" {} + +data "azurerm_client_config" "test" {} + +data "azurerm_role_definition" "test" { + name = "Key Vault Contributor" +} + +%s + +resource "time_offset" "test" { + offset_days = 1 +} + +resource "azurerm_pim_eligible_role_assignment" "test" { + scope = data.azurerm_subscription.primary.id + role_definition_id = "${data.azurerm_subscription.primary.id}${data.azurerm_role_definition.test.id}" + principal_id = azuread_user.test.object_id + + schedule { + start_date_time = time_offset.test.rfc3339 + expiration { + duration_hours = 8 + } + } + + justification = "Expiration Duration Set" + + ticket { + number = "1" + system = "example ticket system" + } +} +`, aadGroup(data)) +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/README.md b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/README.md new file mode 100644 index 000000000000..5b1cf9040288 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/README.md @@ -0,0 +1,54 @@ + +## `github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules` Documentation + +The `roleassignmentschedules` 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-helpers/resourcemanager/commonids" +import "github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules" +``` + + +### Client Initialization + +```go +client := roleassignmentschedules.NewRoleAssignmentSchedulesClientWithBaseURI("https://management.azure.com") +client.Client.Authorizer = authorizer +``` + + +### Example Usage: `RoleAssignmentSchedulesClient.Get` + +```go +ctx := context.TODO() +id := roleassignmentschedules.NewScopedRoleAssignmentScheduleID("/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/some-resource-group", "roleAssignmentScheduleValue") + +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: `RoleAssignmentSchedulesClient.ListForScope` + +```go +ctx := context.TODO() +id := commonids.NewScopeID("/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/some-resource-group") + +// alternatively `client.ListForScope(ctx, id, roleassignmentschedules.DefaultListForScopeOperationOptions())` can be used to do batched pagination +items, err := client.ListForScopeComplete(ctx, id, roleassignmentschedules.DefaultListForScopeOperationOptions()) +if err != nil { + // handle the error +} +for _, item := range items { + // do something +} +``` diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/client.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/client.go new file mode 100644 index 000000000000..d341ea01477e --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/client.go @@ -0,0 +1,26 @@ +package roleassignmentschedules + +import ( + "fmt" + + "github.com/hashicorp/go-azure-sdk/sdk/client/resourcemanager" + sdkEnv "github.com/hashicorp/go-azure-sdk/sdk/environments" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type RoleAssignmentSchedulesClient struct { + Client *resourcemanager.Client +} + +func NewRoleAssignmentSchedulesClientWithBaseURI(sdkApi sdkEnv.Api) (*RoleAssignmentSchedulesClient, error) { + client, err := resourcemanager.NewResourceManagerClient(sdkApi, "roleassignmentschedules", defaultApiVersion) + if err != nil { + return nil, fmt.Errorf("instantiating RoleAssignmentSchedulesClient: %+v", err) + } + + return &RoleAssignmentSchedulesClient{ + Client: client, + }, nil +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/constants.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/constants.go new file mode 100644 index 000000000000..0f99d81d55f5 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/constants.go @@ -0,0 +1,246 @@ +package roleassignmentschedules + +import ( + "encoding/json" + "fmt" + "strings" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type AssignmentType string + +const ( + AssignmentTypeActivated AssignmentType = "Activated" + AssignmentTypeAssigned AssignmentType = "Assigned" +) + +func PossibleValuesForAssignmentType() []string { + return []string{ + string(AssignmentTypeActivated), + string(AssignmentTypeAssigned), + } +} + +func (s *AssignmentType) UnmarshalJSON(bytes []byte) error { + var decoded string + if err := json.Unmarshal(bytes, &decoded); err != nil { + return fmt.Errorf("unmarshaling: %+v", err) + } + out, err := parseAssignmentType(decoded) + if err != nil { + return fmt.Errorf("parsing %q: %+v", decoded, err) + } + *s = *out + return nil +} + +func parseAssignmentType(input string) (*AssignmentType, error) { + vals := map[string]AssignmentType{ + "activated": AssignmentTypeActivated, + "assigned": AssignmentTypeAssigned, + } + if v, ok := vals[strings.ToLower(input)]; ok { + return &v, nil + } + + // otherwise presume it's an undefined value and best-effort it + out := AssignmentType(input) + return &out, nil +} + +type MemberType string + +const ( + MemberTypeDirect MemberType = "Direct" + MemberTypeGroup MemberType = "Group" + MemberTypeInherited MemberType = "Inherited" +) + +func PossibleValuesForMemberType() []string { + return []string{ + string(MemberTypeDirect), + string(MemberTypeGroup), + string(MemberTypeInherited), + } +} + +func (s *MemberType) UnmarshalJSON(bytes []byte) error { + var decoded string + if err := json.Unmarshal(bytes, &decoded); err != nil { + return fmt.Errorf("unmarshaling: %+v", err) + } + out, err := parseMemberType(decoded) + if err != nil { + return fmt.Errorf("parsing %q: %+v", decoded, err) + } + *s = *out + return nil +} + +func parseMemberType(input string) (*MemberType, error) { + vals := map[string]MemberType{ + "direct": MemberTypeDirect, + "group": MemberTypeGroup, + "inherited": MemberTypeInherited, + } + if v, ok := vals[strings.ToLower(input)]; ok { + return &v, nil + } + + // otherwise presume it's an undefined value and best-effort it + out := MemberType(input) + return &out, nil +} + +type PrincipalType string + +const ( + PrincipalTypeDevice PrincipalType = "Device" + PrincipalTypeForeignGroup PrincipalType = "ForeignGroup" + PrincipalTypeGroup PrincipalType = "Group" + PrincipalTypeServicePrincipal PrincipalType = "ServicePrincipal" + PrincipalTypeUser PrincipalType = "User" +) + +func PossibleValuesForPrincipalType() []string { + return []string{ + string(PrincipalTypeDevice), + string(PrincipalTypeForeignGroup), + string(PrincipalTypeGroup), + string(PrincipalTypeServicePrincipal), + string(PrincipalTypeUser), + } +} + +func (s *PrincipalType) UnmarshalJSON(bytes []byte) error { + var decoded string + if err := json.Unmarshal(bytes, &decoded); err != nil { + return fmt.Errorf("unmarshaling: %+v", err) + } + out, err := parsePrincipalType(decoded) + if err != nil { + return fmt.Errorf("parsing %q: %+v", decoded, err) + } + *s = *out + return nil +} + +func parsePrincipalType(input string) (*PrincipalType, error) { + vals := map[string]PrincipalType{ + "device": PrincipalTypeDevice, + "foreigngroup": PrincipalTypeForeignGroup, + "group": PrincipalTypeGroup, + "serviceprincipal": PrincipalTypeServicePrincipal, + "user": PrincipalTypeUser, + } + if v, ok := vals[strings.ToLower(input)]; ok { + return &v, nil + } + + // otherwise presume it's an undefined value and best-effort it + out := PrincipalType(input) + return &out, nil +} + +type Status string + +const ( + StatusAccepted Status = "Accepted" + StatusAdminApproved Status = "AdminApproved" + StatusAdminDenied Status = "AdminDenied" + StatusCanceled Status = "Canceled" + StatusDenied Status = "Denied" + StatusFailed Status = "Failed" + StatusFailedAsResourceIsLocked Status = "FailedAsResourceIsLocked" + StatusGranted Status = "Granted" + StatusInvalid Status = "Invalid" + StatusPendingAdminDecision Status = "PendingAdminDecision" + StatusPendingApproval Status = "PendingApproval" + StatusPendingApprovalProvisioning Status = "PendingApprovalProvisioning" + StatusPendingEvaluation Status = "PendingEvaluation" + StatusPendingExternalProvisioning Status = "PendingExternalProvisioning" + StatusPendingProvisioning Status = "PendingProvisioning" + StatusPendingRevocation Status = "PendingRevocation" + StatusPendingScheduleCreation Status = "PendingScheduleCreation" + StatusProvisioned Status = "Provisioned" + StatusProvisioningStarted Status = "ProvisioningStarted" + StatusRevoked Status = "Revoked" + StatusScheduleCreated Status = "ScheduleCreated" + StatusTimedOut Status = "TimedOut" +) + +func PossibleValuesForStatus() []string { + return []string{ + string(StatusAccepted), + string(StatusAdminApproved), + string(StatusAdminDenied), + string(StatusCanceled), + string(StatusDenied), + string(StatusFailed), + string(StatusFailedAsResourceIsLocked), + string(StatusGranted), + string(StatusInvalid), + string(StatusPendingAdminDecision), + string(StatusPendingApproval), + string(StatusPendingApprovalProvisioning), + string(StatusPendingEvaluation), + string(StatusPendingExternalProvisioning), + string(StatusPendingProvisioning), + string(StatusPendingRevocation), + string(StatusPendingScheduleCreation), + string(StatusProvisioned), + string(StatusProvisioningStarted), + string(StatusRevoked), + string(StatusScheduleCreated), + string(StatusTimedOut), + } +} + +func (s *Status) UnmarshalJSON(bytes []byte) error { + var decoded string + if err := json.Unmarshal(bytes, &decoded); err != nil { + return fmt.Errorf("unmarshaling: %+v", err) + } + out, err := parseStatus(decoded) + if err != nil { + return fmt.Errorf("parsing %q: %+v", decoded, err) + } + *s = *out + return nil +} + +func parseStatus(input string) (*Status, error) { + vals := map[string]Status{ + "accepted": StatusAccepted, + "adminapproved": StatusAdminApproved, + "admindenied": StatusAdminDenied, + "canceled": StatusCanceled, + "denied": StatusDenied, + "failed": StatusFailed, + "failedasresourceislocked": StatusFailedAsResourceIsLocked, + "granted": StatusGranted, + "invalid": StatusInvalid, + "pendingadmindecision": StatusPendingAdminDecision, + "pendingapproval": StatusPendingApproval, + "pendingapprovalprovisioning": StatusPendingApprovalProvisioning, + "pendingevaluation": StatusPendingEvaluation, + "pendingexternalprovisioning": StatusPendingExternalProvisioning, + "pendingprovisioning": StatusPendingProvisioning, + "pendingrevocation": StatusPendingRevocation, + "pendingschedulecreation": StatusPendingScheduleCreation, + "provisioned": StatusProvisioned, + "provisioningstarted": StatusProvisioningStarted, + "revoked": StatusRevoked, + "schedulecreated": StatusScheduleCreated, + "timedout": StatusTimedOut, + } + if v, ok := vals[strings.ToLower(input)]; ok { + return &v, nil + } + + // otherwise presume it's an undefined value and best-effort it + out := Status(input) + return &out, nil +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/id_scopedroleassignmentschedule.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/id_scopedroleassignmentschedule.go new file mode 100644 index 000000000000..64f372c3185d --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/id_scopedroleassignmentschedule.go @@ -0,0 +1,115 @@ +package roleassignmentschedules + +import ( + "fmt" + "strings" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +var _ resourceids.ResourceId = &ScopedRoleAssignmentScheduleId{} + +// ScopedRoleAssignmentScheduleId is a struct representing the Resource ID for a Scoped Role Assignment Schedule +type ScopedRoleAssignmentScheduleId struct { + Scope string + RoleAssignmentScheduleName string +} + +// NewScopedRoleAssignmentScheduleID returns a new ScopedRoleAssignmentScheduleId struct +func NewScopedRoleAssignmentScheduleID(scope string, roleAssignmentScheduleName string) ScopedRoleAssignmentScheduleId { + return ScopedRoleAssignmentScheduleId{ + Scope: scope, + RoleAssignmentScheduleName: roleAssignmentScheduleName, + } +} + +// ParseScopedRoleAssignmentScheduleID parses 'input' into a ScopedRoleAssignmentScheduleId +func ParseScopedRoleAssignmentScheduleID(input string) (*ScopedRoleAssignmentScheduleId, error) { + parser := resourceids.NewParserFromResourceIdType(&ScopedRoleAssignmentScheduleId{}) + parsed, err := parser.Parse(input, false) + if err != nil { + return nil, fmt.Errorf("parsing %q: %+v", input, err) + } + + id := ScopedRoleAssignmentScheduleId{} + if err := id.FromParseResult(*parsed); err != nil { + return nil, err + } + + return &id, nil +} + +// ParseScopedRoleAssignmentScheduleIDInsensitively parses 'input' case-insensitively into a ScopedRoleAssignmentScheduleId +// note: this method should only be used for API response data and not user input +func ParseScopedRoleAssignmentScheduleIDInsensitively(input string) (*ScopedRoleAssignmentScheduleId, error) { + parser := resourceids.NewParserFromResourceIdType(&ScopedRoleAssignmentScheduleId{}) + parsed, err := parser.Parse(input, true) + if err != nil { + return nil, fmt.Errorf("parsing %q: %+v", input, err) + } + + id := ScopedRoleAssignmentScheduleId{} + if err := id.FromParseResult(*parsed); err != nil { + return nil, err + } + + return &id, nil +} + +func (id *ScopedRoleAssignmentScheduleId) FromParseResult(input resourceids.ParseResult) error { + var ok bool + + if id.Scope, ok = input.Parsed["scope"]; !ok { + return resourceids.NewSegmentNotSpecifiedError(id, "scope", input) + } + + if id.RoleAssignmentScheduleName, ok = input.Parsed["roleAssignmentScheduleName"]; !ok { + return resourceids.NewSegmentNotSpecifiedError(id, "roleAssignmentScheduleName", input) + } + + return nil +} + +// ValidateScopedRoleAssignmentScheduleID checks that 'input' can be parsed as a Scoped Role Assignment Schedule ID +func ValidateScopedRoleAssignmentScheduleID(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 := ParseScopedRoleAssignmentScheduleID(v); err != nil { + errors = append(errors, err) + } + + return +} + +// ID returns the formatted Scoped Role Assignment Schedule ID +func (id ScopedRoleAssignmentScheduleId) ID() string { + fmtString := "/%s/providers/Microsoft.Authorization/roleAssignmentSchedules/%s" + return fmt.Sprintf(fmtString, strings.TrimPrefix(id.Scope, "/"), id.RoleAssignmentScheduleName) +} + +// Segments returns a slice of Resource ID Segments which comprise this Scoped Role Assignment Schedule ID +func (id ScopedRoleAssignmentScheduleId) 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("staticRoleAssignmentSchedules", "roleAssignmentSchedules", "roleAssignmentSchedules"), + resourceids.UserSpecifiedSegment("roleAssignmentScheduleName", "roleAssignmentScheduleValue"), + } +} + +// String returns a human-readable description of this Scoped Role Assignment Schedule ID +func (id ScopedRoleAssignmentScheduleId) String() string { + components := []string{ + fmt.Sprintf("Scope: %q", id.Scope), + fmt.Sprintf("Role Assignment Schedule Name: %q", id.RoleAssignmentScheduleName), + } + return fmt.Sprintf("Scoped Role Assignment Schedule (%s)", strings.Join(components, "\n")) +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/method_get.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/method_get.go new file mode 100644 index 000000000000..db27d7b3048c --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/method_get.go @@ -0,0 +1,54 @@ +package roleassignmentschedules + +import ( + "context" + "net/http" + + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" +) + +// 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 + OData *odata.OData + Model *RoleAssignmentSchedule +} + +// Get ... +func (c RoleAssignmentSchedulesClient) Get(ctx context.Context, id ScopedRoleAssignmentScheduleId) (result GetOperationResponse, err error) { + opts := client.RequestOptions{ + ContentType: "application/json; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodGet, + Path: id.ID(), + } + + req, err := c.Client.NewRequest(ctx, opts) + if err != nil { + return + } + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.OData = resp.OData + result.HttpResponse = resp.Response + } + if err != nil { + return + } + + var model RoleAssignmentSchedule + result.Model = &model + + if err = resp.Unmarshal(result.Model); err != nil { + return + } + + return +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/method_listforscope.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/method_listforscope.go new file mode 100644 index 000000000000..baaf127aebf0 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/method_listforscope.go @@ -0,0 +1,120 @@ +package roleassignmentschedules + +import ( + "context" + "fmt" + "net/http" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/commonids" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" +) + +// 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 + OData *odata.OData + Model *[]RoleAssignmentSchedule +} + +type ListForScopeCompleteResult struct { + LatestHttpResponse *http.Response + Items []RoleAssignmentSchedule +} + +type ListForScopeOperationOptions struct { + Filter *string +} + +func DefaultListForScopeOperationOptions() ListForScopeOperationOptions { + return ListForScopeOperationOptions{} +} + +func (o ListForScopeOperationOptions) ToHeaders() *client.Headers { + out := client.Headers{} + + return &out +} + +func (o ListForScopeOperationOptions) ToOData() *odata.Query { + out := odata.Query{} + return &out +} + +func (o ListForScopeOperationOptions) ToQuery() *client.QueryParams { + out := client.QueryParams{} + if o.Filter != nil { + out.Append("$filter", fmt.Sprintf("%v", *o.Filter)) + } + return &out +} + +// ListForScope ... +func (c RoleAssignmentSchedulesClient) ListForScope(ctx context.Context, id commonids.ScopeId, options ListForScopeOperationOptions) (result ListForScopeOperationResponse, err error) { + opts := client.RequestOptions{ + ContentType: "application/json; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodGet, + Path: fmt.Sprintf("%s/providers/Microsoft.Authorization/roleAssignmentSchedules", id.ID()), + OptionsObject: options, + } + + req, err := c.Client.NewRequest(ctx, opts) + if err != nil { + return + } + + var resp *client.Response + resp, err = req.ExecutePaged(ctx) + if resp != nil { + result.OData = resp.OData + result.HttpResponse = resp.Response + } + if err != nil { + return + } + + var values struct { + Values *[]RoleAssignmentSchedule `json:"value"` + } + if err = resp.Unmarshal(&values); err != nil { + return + } + + result.Model = values.Values + + return +} + +// ListForScopeComplete retrieves all the results into a single object +func (c RoleAssignmentSchedulesClient) ListForScopeComplete(ctx context.Context, id commonids.ScopeId, options ListForScopeOperationOptions) (ListForScopeCompleteResult, error) { + return c.ListForScopeCompleteMatchingPredicate(ctx, id, options, RoleAssignmentScheduleOperationPredicate{}) +} + +// ListForScopeCompleteMatchingPredicate retrieves all the results and then applies the predicate +func (c RoleAssignmentSchedulesClient) ListForScopeCompleteMatchingPredicate(ctx context.Context, id commonids.ScopeId, options ListForScopeOperationOptions, predicate RoleAssignmentScheduleOperationPredicate) (result ListForScopeCompleteResult, err error) { + items := make([]RoleAssignmentSchedule, 0) + + resp, err := c.ListForScope(ctx, id, options) + if err != nil { + err = fmt.Errorf("loading results: %+v", err) + return + } + if resp.Model != nil { + for _, v := range *resp.Model { + if predicate.Matches(v) { + items = append(items, v) + } + } + } + + result = ListForScopeCompleteResult{ + LatestHttpResponse: resp.HttpResponse, + Items: items, + } + return +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/model_expandedproperties.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/model_expandedproperties.go new file mode 100644 index 000000000000..df650fa03cf9 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/model_expandedproperties.go @@ -0,0 +1,10 @@ +package roleassignmentschedules + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ExpandedProperties struct { + Principal *ExpandedPropertiesPrincipal `json:"principal,omitempty"` + RoleDefinition *ExpandedPropertiesRoleDefinition `json:"roleDefinition,omitempty"` + Scope *ExpandedPropertiesScope `json:"scope,omitempty"` +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/model_expandedpropertiesprincipal.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/model_expandedpropertiesprincipal.go new file mode 100644 index 000000000000..6ab44039f61e --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/model_expandedpropertiesprincipal.go @@ -0,0 +1,11 @@ +package roleassignmentschedules + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ExpandedPropertiesPrincipal 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/roleassignmentschedules/model_expandedpropertiesroledefinition.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/model_expandedpropertiesroledefinition.go new file mode 100644 index 000000000000..ef2298e23d7b --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/model_expandedpropertiesroledefinition.go @@ -0,0 +1,10 @@ +package roleassignmentschedules + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ExpandedPropertiesRoleDefinition 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/roleassignmentschedules/model_expandedpropertiesscope.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/model_expandedpropertiesscope.go new file mode 100644 index 000000000000..3246c2885eb4 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/model_expandedpropertiesscope.go @@ -0,0 +1,10 @@ +package roleassignmentschedules + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ExpandedPropertiesScope 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/roleassignmentschedules/model_roleassignmentschedule.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/model_roleassignmentschedule.go new file mode 100644 index 000000000000..9e916466dbab --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/model_roleassignmentschedule.go @@ -0,0 +1,11 @@ +package roleassignmentschedules + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type RoleAssignmentSchedule struct { + Id *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Properties *RoleAssignmentScheduleProperties `json:"properties,omitempty"` + Type *string `json:"type,omitempty"` +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/model_roleassignmentscheduleproperties.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/model_roleassignmentscheduleproperties.go new file mode 100644 index 000000000000..bf0074b4dd04 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/model_roleassignmentscheduleproperties.go @@ -0,0 +1,77 @@ +package roleassignmentschedules + +import ( + "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 RoleAssignmentScheduleProperties struct { + AssignmentType *AssignmentType `json:"assignmentType,omitempty"` + Condition *string `json:"condition,omitempty"` + ConditionVersion *string `json:"conditionVersion,omitempty"` + CreatedOn *string `json:"createdOn,omitempty"` + EndDateTime *string `json:"endDateTime,omitempty"` + ExpandedProperties *ExpandedProperties `json:"expandedProperties,omitempty"` + LinkedRoleEligibilityScheduleId *string `json:"linkedRoleEligibilityScheduleId,omitempty"` + MemberType *MemberType `json:"memberType,omitempty"` + PrincipalId *string `json:"principalId,omitempty"` + PrincipalType *PrincipalType `json:"principalType,omitempty"` + RoleAssignmentScheduleRequestId *string `json:"roleAssignmentScheduleRequestId,omitempty"` + RoleDefinitionId *string `json:"roleDefinitionId,omitempty"` + Scope *string `json:"scope,omitempty"` + StartDateTime *string `json:"startDateTime,omitempty"` + Status *Status `json:"status,omitempty"` + UpdatedOn *string `json:"updatedOn,omitempty"` +} + +func (o *RoleAssignmentScheduleProperties) GetCreatedOnAsTime() (*time.Time, error) { + if o.CreatedOn == nil { + return nil, nil + } + return dates.ParseAsFormat(o.CreatedOn, "2006-01-02T15:04:05Z07:00") +} + +func (o *RoleAssignmentScheduleProperties) SetCreatedOnAsTime(input time.Time) { + formatted := input.Format("2006-01-02T15:04:05Z07:00") + o.CreatedOn = &formatted +} + +func (o *RoleAssignmentScheduleProperties) GetEndDateTimeAsTime() (*time.Time, error) { + if o.EndDateTime == nil { + return nil, nil + } + return dates.ParseAsFormat(o.EndDateTime, "2006-01-02T15:04:05Z07:00") +} + +func (o *RoleAssignmentScheduleProperties) SetEndDateTimeAsTime(input time.Time) { + formatted := input.Format("2006-01-02T15:04:05Z07:00") + o.EndDateTime = &formatted +} + +func (o *RoleAssignmentScheduleProperties) GetStartDateTimeAsTime() (*time.Time, error) { + if o.StartDateTime == nil { + return nil, nil + } + return dates.ParseAsFormat(o.StartDateTime, "2006-01-02T15:04:05Z07:00") +} + +func (o *RoleAssignmentScheduleProperties) SetStartDateTimeAsTime(input time.Time) { + formatted := input.Format("2006-01-02T15:04:05Z07:00") + o.StartDateTime = &formatted +} + +func (o *RoleAssignmentScheduleProperties) GetUpdatedOnAsTime() (*time.Time, error) { + if o.UpdatedOn == nil { + return nil, nil + } + return dates.ParseAsFormat(o.UpdatedOn, "2006-01-02T15:04:05Z07:00") +} + +func (o *RoleAssignmentScheduleProperties) SetUpdatedOnAsTime(input time.Time) { + formatted := input.Format("2006-01-02T15:04:05Z07:00") + o.UpdatedOn = &formatted +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/predicates.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/predicates.go new file mode 100644 index 000000000000..ac48499025f1 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/predicates.go @@ -0,0 +1,27 @@ +package roleassignmentschedules + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type RoleAssignmentScheduleOperationPredicate struct { + Id *string + Name *string + Type *string +} + +func (p RoleAssignmentScheduleOperationPredicate) Matches(input RoleAssignmentSchedule) 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/roleassignmentschedules/version.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/version.go new file mode 100644 index 000000000000..701d5043b86c --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules/version.go @@ -0,0 +1,12 @@ +package roleassignmentschedules + +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/roleassignmentschedules/%s", defaultApiVersion) +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/README.md b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/README.md new file mode 100644 index 000000000000..cfa586977d82 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/README.md @@ -0,0 +1,54 @@ + +## `github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules` Documentation + +The `roleeligibilityschedules` 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-helpers/resourcemanager/commonids" +import "github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules" +``` + + +### Client Initialization + +```go +client := roleeligibilityschedules.NewRoleEligibilitySchedulesClientWithBaseURI("https://management.azure.com") +client.Client.Authorizer = authorizer +``` + + +### Example Usage: `RoleEligibilitySchedulesClient.Get` + +```go +ctx := context.TODO() +id := roleeligibilityschedules.NewScopedRoleEligibilityScheduleID("/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/some-resource-group", "roleEligibilityScheduleValue") + +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: `RoleEligibilitySchedulesClient.ListForScope` + +```go +ctx := context.TODO() +id := commonids.NewScopeID("/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/some-resource-group") + +// alternatively `client.ListForScope(ctx, id, roleeligibilityschedules.DefaultListForScopeOperationOptions())` can be used to do batched pagination +items, err := client.ListForScopeComplete(ctx, id, roleeligibilityschedules.DefaultListForScopeOperationOptions()) +if err != nil { + // handle the error +} +for _, item := range items { + // do something +} +``` diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/client.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/client.go new file mode 100644 index 000000000000..435d81c050db --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/client.go @@ -0,0 +1,26 @@ +package roleeligibilityschedules + +import ( + "fmt" + + "github.com/hashicorp/go-azure-sdk/sdk/client/resourcemanager" + sdkEnv "github.com/hashicorp/go-azure-sdk/sdk/environments" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type RoleEligibilitySchedulesClient struct { + Client *resourcemanager.Client +} + +func NewRoleEligibilitySchedulesClientWithBaseURI(sdkApi sdkEnv.Api) (*RoleEligibilitySchedulesClient, error) { + client, err := resourcemanager.NewResourceManagerClient(sdkApi, "roleeligibilityschedules", defaultApiVersion) + if err != nil { + return nil, fmt.Errorf("instantiating RoleEligibilitySchedulesClient: %+v", err) + } + + return &RoleEligibilitySchedulesClient{ + Client: client, + }, nil +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/constants.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/constants.go new file mode 100644 index 000000000000..606123b4be50 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/constants.go @@ -0,0 +1,205 @@ +package roleeligibilityschedules + +import ( + "encoding/json" + "fmt" + "strings" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type MemberType string + +const ( + MemberTypeDirect MemberType = "Direct" + MemberTypeGroup MemberType = "Group" + MemberTypeInherited MemberType = "Inherited" +) + +func PossibleValuesForMemberType() []string { + return []string{ + string(MemberTypeDirect), + string(MemberTypeGroup), + string(MemberTypeInherited), + } +} + +func (s *MemberType) UnmarshalJSON(bytes []byte) error { + var decoded string + if err := json.Unmarshal(bytes, &decoded); err != nil { + return fmt.Errorf("unmarshaling: %+v", err) + } + out, err := parseMemberType(decoded) + if err != nil { + return fmt.Errorf("parsing %q: %+v", decoded, err) + } + *s = *out + return nil +} + +func parseMemberType(input string) (*MemberType, error) { + vals := map[string]MemberType{ + "direct": MemberTypeDirect, + "group": MemberTypeGroup, + "inherited": MemberTypeInherited, + } + if v, ok := vals[strings.ToLower(input)]; ok { + return &v, nil + } + + // otherwise presume it's an undefined value and best-effort it + out := MemberType(input) + return &out, nil +} + +type PrincipalType string + +const ( + PrincipalTypeDevice PrincipalType = "Device" + PrincipalTypeForeignGroup PrincipalType = "ForeignGroup" + PrincipalTypeGroup PrincipalType = "Group" + PrincipalTypeServicePrincipal PrincipalType = "ServicePrincipal" + PrincipalTypeUser PrincipalType = "User" +) + +func PossibleValuesForPrincipalType() []string { + return []string{ + string(PrincipalTypeDevice), + string(PrincipalTypeForeignGroup), + string(PrincipalTypeGroup), + string(PrincipalTypeServicePrincipal), + string(PrincipalTypeUser), + } +} + +func (s *PrincipalType) UnmarshalJSON(bytes []byte) error { + var decoded string + if err := json.Unmarshal(bytes, &decoded); err != nil { + return fmt.Errorf("unmarshaling: %+v", err) + } + out, err := parsePrincipalType(decoded) + if err != nil { + return fmt.Errorf("parsing %q: %+v", decoded, err) + } + *s = *out + return nil +} + +func parsePrincipalType(input string) (*PrincipalType, error) { + vals := map[string]PrincipalType{ + "device": PrincipalTypeDevice, + "foreigngroup": PrincipalTypeForeignGroup, + "group": PrincipalTypeGroup, + "serviceprincipal": PrincipalTypeServicePrincipal, + "user": PrincipalTypeUser, + } + if v, ok := vals[strings.ToLower(input)]; ok { + return &v, nil + } + + // otherwise presume it's an undefined value and best-effort it + out := PrincipalType(input) + return &out, nil +} + +type Status string + +const ( + StatusAccepted Status = "Accepted" + StatusAdminApproved Status = "AdminApproved" + StatusAdminDenied Status = "AdminDenied" + StatusCanceled Status = "Canceled" + StatusDenied Status = "Denied" + StatusFailed Status = "Failed" + StatusFailedAsResourceIsLocked Status = "FailedAsResourceIsLocked" + StatusGranted Status = "Granted" + StatusInvalid Status = "Invalid" + StatusPendingAdminDecision Status = "PendingAdminDecision" + StatusPendingApproval Status = "PendingApproval" + StatusPendingApprovalProvisioning Status = "PendingApprovalProvisioning" + StatusPendingEvaluation Status = "PendingEvaluation" + StatusPendingExternalProvisioning Status = "PendingExternalProvisioning" + StatusPendingProvisioning Status = "PendingProvisioning" + StatusPendingRevocation Status = "PendingRevocation" + StatusPendingScheduleCreation Status = "PendingScheduleCreation" + StatusProvisioned Status = "Provisioned" + StatusProvisioningStarted Status = "ProvisioningStarted" + StatusRevoked Status = "Revoked" + StatusScheduleCreated Status = "ScheduleCreated" + StatusTimedOut Status = "TimedOut" +) + +func PossibleValuesForStatus() []string { + return []string{ + string(StatusAccepted), + string(StatusAdminApproved), + string(StatusAdminDenied), + string(StatusCanceled), + string(StatusDenied), + string(StatusFailed), + string(StatusFailedAsResourceIsLocked), + string(StatusGranted), + string(StatusInvalid), + string(StatusPendingAdminDecision), + string(StatusPendingApproval), + string(StatusPendingApprovalProvisioning), + string(StatusPendingEvaluation), + string(StatusPendingExternalProvisioning), + string(StatusPendingProvisioning), + string(StatusPendingRevocation), + string(StatusPendingScheduleCreation), + string(StatusProvisioned), + string(StatusProvisioningStarted), + string(StatusRevoked), + string(StatusScheduleCreated), + string(StatusTimedOut), + } +} + +func (s *Status) UnmarshalJSON(bytes []byte) error { + var decoded string + if err := json.Unmarshal(bytes, &decoded); err != nil { + return fmt.Errorf("unmarshaling: %+v", err) + } + out, err := parseStatus(decoded) + if err != nil { + return fmt.Errorf("parsing %q: %+v", decoded, err) + } + *s = *out + return nil +} + +func parseStatus(input string) (*Status, error) { + vals := map[string]Status{ + "accepted": StatusAccepted, + "adminapproved": StatusAdminApproved, + "admindenied": StatusAdminDenied, + "canceled": StatusCanceled, + "denied": StatusDenied, + "failed": StatusFailed, + "failedasresourceislocked": StatusFailedAsResourceIsLocked, + "granted": StatusGranted, + "invalid": StatusInvalid, + "pendingadmindecision": StatusPendingAdminDecision, + "pendingapproval": StatusPendingApproval, + "pendingapprovalprovisioning": StatusPendingApprovalProvisioning, + "pendingevaluation": StatusPendingEvaluation, + "pendingexternalprovisioning": StatusPendingExternalProvisioning, + "pendingprovisioning": StatusPendingProvisioning, + "pendingrevocation": StatusPendingRevocation, + "pendingschedulecreation": StatusPendingScheduleCreation, + "provisioned": StatusProvisioned, + "provisioningstarted": StatusProvisioningStarted, + "revoked": StatusRevoked, + "schedulecreated": StatusScheduleCreated, + "timedout": StatusTimedOut, + } + if v, ok := vals[strings.ToLower(input)]; ok { + return &v, nil + } + + // otherwise presume it's an undefined value and best-effort it + out := Status(input) + return &out, nil +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/id_scopedroleeligibilityschedule.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/id_scopedroleeligibilityschedule.go new file mode 100644 index 000000000000..354e34a24de6 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/id_scopedroleeligibilityschedule.go @@ -0,0 +1,115 @@ +package roleeligibilityschedules + +import ( + "fmt" + "strings" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +var _ resourceids.ResourceId = &ScopedRoleEligibilityScheduleId{} + +// ScopedRoleEligibilityScheduleId is a struct representing the Resource ID for a Scoped Role Eligibility Schedule +type ScopedRoleEligibilityScheduleId struct { + Scope string + RoleEligibilityScheduleName string +} + +// NewScopedRoleEligibilityScheduleID returns a new ScopedRoleEligibilityScheduleId struct +func NewScopedRoleEligibilityScheduleID(scope string, roleEligibilityScheduleName string) ScopedRoleEligibilityScheduleId { + return ScopedRoleEligibilityScheduleId{ + Scope: scope, + RoleEligibilityScheduleName: roleEligibilityScheduleName, + } +} + +// ParseScopedRoleEligibilityScheduleID parses 'input' into a ScopedRoleEligibilityScheduleId +func ParseScopedRoleEligibilityScheduleID(input string) (*ScopedRoleEligibilityScheduleId, error) { + parser := resourceids.NewParserFromResourceIdType(&ScopedRoleEligibilityScheduleId{}) + parsed, err := parser.Parse(input, false) + if err != nil { + return nil, fmt.Errorf("parsing %q: %+v", input, err) + } + + id := ScopedRoleEligibilityScheduleId{} + if err := id.FromParseResult(*parsed); err != nil { + return nil, err + } + + return &id, nil +} + +// ParseScopedRoleEligibilityScheduleIDInsensitively parses 'input' case-insensitively into a ScopedRoleEligibilityScheduleId +// note: this method should only be used for API response data and not user input +func ParseScopedRoleEligibilityScheduleIDInsensitively(input string) (*ScopedRoleEligibilityScheduleId, error) { + parser := resourceids.NewParserFromResourceIdType(&ScopedRoleEligibilityScheduleId{}) + parsed, err := parser.Parse(input, true) + if err != nil { + return nil, fmt.Errorf("parsing %q: %+v", input, err) + } + + id := ScopedRoleEligibilityScheduleId{} + if err := id.FromParseResult(*parsed); err != nil { + return nil, err + } + + return &id, nil +} + +func (id *ScopedRoleEligibilityScheduleId) FromParseResult(input resourceids.ParseResult) error { + var ok bool + + if id.Scope, ok = input.Parsed["scope"]; !ok { + return resourceids.NewSegmentNotSpecifiedError(id, "scope", input) + } + + if id.RoleEligibilityScheduleName, ok = input.Parsed["roleEligibilityScheduleName"]; !ok { + return resourceids.NewSegmentNotSpecifiedError(id, "roleEligibilityScheduleName", input) + } + + return nil +} + +// ValidateScopedRoleEligibilityScheduleID checks that 'input' can be parsed as a Scoped Role Eligibility Schedule ID +func ValidateScopedRoleEligibilityScheduleID(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 := ParseScopedRoleEligibilityScheduleID(v); err != nil { + errors = append(errors, err) + } + + return +} + +// ID returns the formatted Scoped Role Eligibility Schedule ID +func (id ScopedRoleEligibilityScheduleId) ID() string { + fmtString := "/%s/providers/Microsoft.Authorization/roleEligibilitySchedules/%s" + return fmt.Sprintf(fmtString, strings.TrimPrefix(id.Scope, "/"), id.RoleEligibilityScheduleName) +} + +// Segments returns a slice of Resource ID Segments which comprise this Scoped Role Eligibility Schedule ID +func (id ScopedRoleEligibilityScheduleId) 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("staticRoleEligibilitySchedules", "roleEligibilitySchedules", "roleEligibilitySchedules"), + resourceids.UserSpecifiedSegment("roleEligibilityScheduleName", "roleEligibilityScheduleValue"), + } +} + +// String returns a human-readable description of this Scoped Role Eligibility Schedule ID +func (id ScopedRoleEligibilityScheduleId) String() string { + components := []string{ + fmt.Sprintf("Scope: %q", id.Scope), + fmt.Sprintf("Role Eligibility Schedule Name: %q", id.RoleEligibilityScheduleName), + } + return fmt.Sprintf("Scoped Role Eligibility Schedule (%s)", strings.Join(components, "\n")) +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/method_get.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/method_get.go new file mode 100644 index 000000000000..2a5632f66911 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/method_get.go @@ -0,0 +1,54 @@ +package roleeligibilityschedules + +import ( + "context" + "net/http" + + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" +) + +// 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 + OData *odata.OData + Model *RoleEligibilitySchedule +} + +// Get ... +func (c RoleEligibilitySchedulesClient) Get(ctx context.Context, id ScopedRoleEligibilityScheduleId) (result GetOperationResponse, err error) { + opts := client.RequestOptions{ + ContentType: "application/json; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodGet, + Path: id.ID(), + } + + req, err := c.Client.NewRequest(ctx, opts) + if err != nil { + return + } + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.OData = resp.OData + result.HttpResponse = resp.Response + } + if err != nil { + return + } + + var model RoleEligibilitySchedule + result.Model = &model + + if err = resp.Unmarshal(result.Model); err != nil { + return + } + + return +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/method_listforscope.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/method_listforscope.go new file mode 100644 index 000000000000..cb3087c5e33f --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/method_listforscope.go @@ -0,0 +1,120 @@ +package roleeligibilityschedules + +import ( + "context" + "fmt" + "net/http" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/commonids" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" +) + +// 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 + OData *odata.OData + Model *[]RoleEligibilitySchedule +} + +type ListForScopeCompleteResult struct { + LatestHttpResponse *http.Response + Items []RoleEligibilitySchedule +} + +type ListForScopeOperationOptions struct { + Filter *string +} + +func DefaultListForScopeOperationOptions() ListForScopeOperationOptions { + return ListForScopeOperationOptions{} +} + +func (o ListForScopeOperationOptions) ToHeaders() *client.Headers { + out := client.Headers{} + + return &out +} + +func (o ListForScopeOperationOptions) ToOData() *odata.Query { + out := odata.Query{} + return &out +} + +func (o ListForScopeOperationOptions) ToQuery() *client.QueryParams { + out := client.QueryParams{} + if o.Filter != nil { + out.Append("$filter", fmt.Sprintf("%v", *o.Filter)) + } + return &out +} + +// ListForScope ... +func (c RoleEligibilitySchedulesClient) ListForScope(ctx context.Context, id commonids.ScopeId, options ListForScopeOperationOptions) (result ListForScopeOperationResponse, err error) { + opts := client.RequestOptions{ + ContentType: "application/json; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodGet, + Path: fmt.Sprintf("%s/providers/Microsoft.Authorization/roleEligibilitySchedules", id.ID()), + OptionsObject: options, + } + + req, err := c.Client.NewRequest(ctx, opts) + if err != nil { + return + } + + var resp *client.Response + resp, err = req.ExecutePaged(ctx) + if resp != nil { + result.OData = resp.OData + result.HttpResponse = resp.Response + } + if err != nil { + return + } + + var values struct { + Values *[]RoleEligibilitySchedule `json:"value"` + } + if err = resp.Unmarshal(&values); err != nil { + return + } + + result.Model = values.Values + + return +} + +// ListForScopeComplete retrieves all the results into a single object +func (c RoleEligibilitySchedulesClient) ListForScopeComplete(ctx context.Context, id commonids.ScopeId, options ListForScopeOperationOptions) (ListForScopeCompleteResult, error) { + return c.ListForScopeCompleteMatchingPredicate(ctx, id, options, RoleEligibilityScheduleOperationPredicate{}) +} + +// ListForScopeCompleteMatchingPredicate retrieves all the results and then applies the predicate +func (c RoleEligibilitySchedulesClient) ListForScopeCompleteMatchingPredicate(ctx context.Context, id commonids.ScopeId, options ListForScopeOperationOptions, predicate RoleEligibilityScheduleOperationPredicate) (result ListForScopeCompleteResult, err error) { + items := make([]RoleEligibilitySchedule, 0) + + resp, err := c.ListForScope(ctx, id, options) + if err != nil { + err = fmt.Errorf("loading results: %+v", err) + return + } + if resp.Model != nil { + for _, v := range *resp.Model { + if predicate.Matches(v) { + items = append(items, v) + } + } + } + + result = ListForScopeCompleteResult{ + LatestHttpResponse: resp.HttpResponse, + Items: items, + } + return +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/model_expandedproperties.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/model_expandedproperties.go new file mode 100644 index 000000000000..eff7f8b432a2 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/model_expandedproperties.go @@ -0,0 +1,10 @@ +package roleeligibilityschedules + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ExpandedProperties struct { + Principal *ExpandedPropertiesPrincipal `json:"principal,omitempty"` + RoleDefinition *ExpandedPropertiesRoleDefinition `json:"roleDefinition,omitempty"` + Scope *ExpandedPropertiesScope `json:"scope,omitempty"` +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/model_expandedpropertiesprincipal.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/model_expandedpropertiesprincipal.go new file mode 100644 index 000000000000..cf9ad4e6b3d3 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/model_expandedpropertiesprincipal.go @@ -0,0 +1,11 @@ +package roleeligibilityschedules + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ExpandedPropertiesPrincipal 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/roleeligibilityschedules/model_expandedpropertiesroledefinition.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/model_expandedpropertiesroledefinition.go new file mode 100644 index 000000000000..2064c23a85dd --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/model_expandedpropertiesroledefinition.go @@ -0,0 +1,10 @@ +package roleeligibilityschedules + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ExpandedPropertiesRoleDefinition 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/roleeligibilityschedules/model_expandedpropertiesscope.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/model_expandedpropertiesscope.go new file mode 100644 index 000000000000..1a5499bead6d --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/model_expandedpropertiesscope.go @@ -0,0 +1,10 @@ +package roleeligibilityschedules + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ExpandedPropertiesScope 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/roleeligibilityschedules/model_roleeligibilityschedule.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/model_roleeligibilityschedule.go new file mode 100644 index 000000000000..0e513fd89e14 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/model_roleeligibilityschedule.go @@ -0,0 +1,11 @@ +package roleeligibilityschedules + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type RoleEligibilitySchedule struct { + Id *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Properties *RoleEligibilityScheduleProperties `json:"properties,omitempty"` + Type *string `json:"type,omitempty"` +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/model_roleeligibilityscheduleproperties.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/model_roleeligibilityscheduleproperties.go new file mode 100644 index 000000000000..05f98d2e7989 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/model_roleeligibilityscheduleproperties.go @@ -0,0 +1,75 @@ +package roleeligibilityschedules + +import ( + "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 RoleEligibilityScheduleProperties struct { + Condition *string `json:"condition,omitempty"` + ConditionVersion *string `json:"conditionVersion,omitempty"` + CreatedOn *string `json:"createdOn,omitempty"` + EndDateTime *string `json:"endDateTime,omitempty"` + ExpandedProperties *ExpandedProperties `json:"expandedProperties,omitempty"` + MemberType *MemberType `json:"memberType,omitempty"` + PrincipalId *string `json:"principalId,omitempty"` + PrincipalType *PrincipalType `json:"principalType,omitempty"` + RoleDefinitionId *string `json:"roleDefinitionId,omitempty"` + RoleEligibilityScheduleRequestId *string `json:"roleEligibilityScheduleRequestId,omitempty"` + Scope *string `json:"scope,omitempty"` + StartDateTime *string `json:"startDateTime,omitempty"` + Status *Status `json:"status,omitempty"` + UpdatedOn *string `json:"updatedOn,omitempty"` +} + +func (o *RoleEligibilityScheduleProperties) GetCreatedOnAsTime() (*time.Time, error) { + if o.CreatedOn == nil { + return nil, nil + } + return dates.ParseAsFormat(o.CreatedOn, "2006-01-02T15:04:05Z07:00") +} + +func (o *RoleEligibilityScheduleProperties) SetCreatedOnAsTime(input time.Time) { + formatted := input.Format("2006-01-02T15:04:05Z07:00") + o.CreatedOn = &formatted +} + +func (o *RoleEligibilityScheduleProperties) GetEndDateTimeAsTime() (*time.Time, error) { + if o.EndDateTime == nil { + return nil, nil + } + return dates.ParseAsFormat(o.EndDateTime, "2006-01-02T15:04:05Z07:00") +} + +func (o *RoleEligibilityScheduleProperties) SetEndDateTimeAsTime(input time.Time) { + formatted := input.Format("2006-01-02T15:04:05Z07:00") + o.EndDateTime = &formatted +} + +func (o *RoleEligibilityScheduleProperties) GetStartDateTimeAsTime() (*time.Time, error) { + if o.StartDateTime == nil { + return nil, nil + } + return dates.ParseAsFormat(o.StartDateTime, "2006-01-02T15:04:05Z07:00") +} + +func (o *RoleEligibilityScheduleProperties) SetStartDateTimeAsTime(input time.Time) { + formatted := input.Format("2006-01-02T15:04:05Z07:00") + o.StartDateTime = &formatted +} + +func (o *RoleEligibilityScheduleProperties) GetUpdatedOnAsTime() (*time.Time, error) { + if o.UpdatedOn == nil { + return nil, nil + } + return dates.ParseAsFormat(o.UpdatedOn, "2006-01-02T15:04:05Z07:00") +} + +func (o *RoleEligibilityScheduleProperties) SetUpdatedOnAsTime(input time.Time) { + formatted := input.Format("2006-01-02T15:04:05Z07:00") + o.UpdatedOn = &formatted +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/predicates.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/predicates.go new file mode 100644 index 000000000000..50b39a7215b1 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/predicates.go @@ -0,0 +1,27 @@ +package roleeligibilityschedules + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type RoleEligibilityScheduleOperationPredicate struct { + Id *string + Name *string + Type *string +} + +func (p RoleEligibilityScheduleOperationPredicate) Matches(input RoleEligibilitySchedule) 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/roleeligibilityschedules/version.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/version.go new file mode 100644 index 000000000000..6c2bb9ce3616 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules/version.go @@ -0,0 +1,12 @@ +package roleeligibilityschedules + +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/roleeligibilityschedules/%s", defaultApiVersion) +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 63648a8b1cb0..44a266596926 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -221,8 +221,10 @@ github.com/hashicorp/go-azure-sdk/resource-manager/appplatform/2024-01-01-previe 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/roleassignmentscheduleinstances github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedulerequests +github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleassignmentschedules github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityscheduleinstances github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedulerequests +github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2020-10-01/roleeligibilityschedules github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2022-04-01/roleassignments github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2022-04-01/roledefinitions github.com/hashicorp/go-azure-sdk/resource-manager/authorization/2022-05-01-preview/roledefinitions