diff --git a/.gitignore b/.gitignore index 9bc3dac..8ef08dc 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,8 @@ dist/ terraform.tfstate terraform.tfstate.backup terraform.tfstate.*.backup +.terraform.lock.hcl +.terraform/ tmp/ __debug_bin* diff --git a/docs/resources/phone_call_queue_policy_voice_mail.md b/docs/resources/phone_call_queue_policy_voice_mail.md new file mode 100644 index 0000000..92b2393 --- /dev/null +++ b/docs/resources/phone_call_queue_policy_voice_mail.md @@ -0,0 +1,71 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "zoom_phone_call_queue_policy_voice_mail Resource - zoom" +subcategory: "" +description: |- + The policy sub-setting for a specific call queue according to the voice_mail. + API Permissions + The following API permissions are required in order to use this resource. + This resource requires the phone:read:call_queue:admin, phone:write:call_queue_policy:admin, phone:update:call_queue_policy:admin, phone:delete:call_queue_policy:admin. +--- + +# zoom_phone_call_queue_policy_voice_mail (Resource) + +The policy sub-setting for a specific call queue according to the voice_mail. + +## API Permissions +The following API permissions are required in order to use this resource. +This resource requires the `phone:read:call_queue:admin`, `phone:write:call_queue_policy:admin`, `phone:update:call_queue_policy:admin`, `phone:delete:call_queue_policy:admin`. + +## Example Usage + +```terraform +resource "zoom_phone_call_queue" "example" { + name = "terraform-example" + extension_number = "1234" +} + +resource "zoom_phone_call_queue_policy_voice_mail" "example" { + call_queue_id = zoom_phone_call_queue.example.id + + access_members = [ + { + access_user_id = "LLgNJuS-Q6aYBcsv2wJnug", # Zoom User Id (not phone user id) + allow_download = true + allow_delete = false + allow_sharing = true + }, + ] +} +``` + + +## Schema + +### Required + +- `access_members` (Attributes Set) The shared voicemail access member list. (see [below for nested schema](#nestedatt--access_members)) +- `call_queue_id` (String) Unique identifier of the Call Queue. + + +### Nested Schema for `access_members` + +Required: + +- `access_user_id` (String) The Zoom user ID or email to share or update the access permissions with. +- `allow_delete` (Boolean) Specifies whether the member has delete permissions. The default is **false**. +- `allow_download` (Boolean) Specifies whether the member has download permissions. The default is **false**. +- `allow_sharing` (Boolean) Specifies whether the member has the permission to share. The default is **false**. + +Read-Only: + +- `shared_id` (String) The number is limited to the minimum value of 10 or the number of allowed access members account setting. + +## Import + +Import is supported using the following syntax: + +```shell +# ${call_queue_id} +terraform import zoom_phone_call_queue_policy_voice_mail.example wGJDBcnJQC6tV86BbtlXXX +``` diff --git a/examples/resources/zoom_phone_call_queue_policy_voice_mail/import.sh b/examples/resources/zoom_phone_call_queue_policy_voice_mail/import.sh new file mode 100644 index 0000000..f59ee68 --- /dev/null +++ b/examples/resources/zoom_phone_call_queue_policy_voice_mail/import.sh @@ -0,0 +1,2 @@ +# ${call_queue_id} +terraform import zoom_phone_call_queue_policy_voice_mail.example wGJDBcnJQC6tV86BbtlXXX diff --git a/examples/resources/zoom_phone_call_queue_policy_voice_mail/provider.tf b/examples/resources/zoom_phone_call_queue_policy_voice_mail/provider.tf new file mode 100644 index 0000000..23b61ca --- /dev/null +++ b/examples/resources/zoom_phone_call_queue_policy_voice_mail/provider.tf @@ -0,0 +1,22 @@ +terraform { + required_providers { + zoom = { + source = "folio-sec/zoom" + version = "~> 0.0.0" + } + } +} + +provider "zoom" { + account_id = var.zoom_account_id + client_id = var.zoom_client_id + client_secret = var.zoom_client_secret +} + +variable "zoom_account_id" {} + +variable "zoom_client_id" {} + +variable "zoom_client_secret" { + sensitive = true +} diff --git a/examples/resources/zoom_phone_call_queue_policy_voice_mail/resource.tf b/examples/resources/zoom_phone_call_queue_policy_voice_mail/resource.tf new file mode 100644 index 0000000..3d73c50 --- /dev/null +++ b/examples/resources/zoom_phone_call_queue_policy_voice_mail/resource.tf @@ -0,0 +1,17 @@ +resource "zoom_phone_call_queue" "example" { + name = "terraform-example" + extension_number = "1234" +} + +resource "zoom_phone_call_queue_policy_voice_mail" "example" { + call_queue_id = zoom_phone_call_queue.example.id + + access_members = [ + { + access_user_id = "LLgNJuS-Q6aYBcsv2wJnug", # Zoom User Id (not phone user id) + allow_download = true + allow_delete = false + allow_sharing = true + }, + ] +} diff --git a/internal/provider/provider.go b/internal/provider/provider.go index bff5042..b380c7a 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -18,6 +18,7 @@ import ( "github.com/folio-sec/terraform-provider-zoom/internal/services/phone/callqueue" "github.com/folio-sec/terraform-provider-zoom/internal/services/phone/callqueuemember" "github.com/folio-sec/terraform-provider-zoom/internal/services/phone/callqueuephonenumber" + "github.com/folio-sec/terraform-provider-zoom/internal/services/phone/callqueuepolicy" "github.com/folio-sec/terraform-provider-zoom/internal/services/phone/externalcontact" "github.com/folio-sec/terraform-provider-zoom/internal/services/phone/phonenumbers" "github.com/folio-sec/terraform-provider-zoom/internal/services/phone/sharedlinegroup" @@ -217,6 +218,7 @@ func (p *zoomProvider) Resources(_ context.Context) []func() resource.Resource { callqueue.NewPhoneCallQueueResource, callqueuemember.NewPhoneCallQueueMembersResource, callqueuephonenumber.NewPhoneCallQueuePhoneNumbersResource, + callqueuepolicy.NewPhoneCallQueuePolicyVoiceMailResource, externalcontact.NewPhoneExternalContactResource, sharedlinegroupgroup.NewPhoneSharedLineGroupResource, sharedlinegroupgroupmembers.NewPhoneSharedLineGroupMembersResource, diff --git a/internal/services/phone/callqueuepolicy/call_queue_policy_crud.go b/internal/services/phone/callqueuepolicy/call_queue_policy_crud.go new file mode 100644 index 0000000..5997d72 --- /dev/null +++ b/internal/services/phone/callqueuepolicy/call_queue_policy_crud.go @@ -0,0 +1,131 @@ +package callqueuepolicy + +import ( + "context" + "errors" + "fmt" + "github.com/folio-sec/terraform-provider-zoom/generated/api/zoomphone" + "github.com/folio-sec/terraform-provider-zoom/internal/util" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/samber/lo" +) + +func newCrud(client *zoomphone.Client) *crud { + return &crud{ + client: client, + } +} + +type crud struct { + client *zoomphone.Client +} + +func (c *crud) read(ctx context.Context, callQueueID types.String) (*readDto, error) { + detail, err := c.client.GetACallQueue(ctx, zoomphone.GetACallQueueParams{ + CallQueueId: callQueueID.ValueString(), + }) + if err != nil { + var status *zoomphone.ErrorResponseStatusCode + if errors.As(err, &status) { + if status.StatusCode == 400 { + return nil, nil // already deleted + } + } + return nil, fmt.Errorf("unable to read phone call queue policy: %w", err) + } + + var policyVoiceMailMembers []*readDtoPolicyVoiceMailMember + if detail.Policy.IsSet() { + policyVoiceMailMembers = lo.Map(detail.Policy.Value.GetVoicemailAccessMembers(), func(item zoomphone.GetACallQueueOKPolicyVoicemailAccessMembersItem, index int) *readDtoPolicyVoiceMailMember { + return &readDtoPolicyVoiceMailMember{ + accessUserID: util.FromOptString(item.AccessUserID), + allowDownload: util.FromOptBool(item.AllowDownload), + allowDelete: util.FromOptBool(item.AllowDelete), + allowSharing: util.FromOptBool(item.AllowSharing), + sharedID: util.FromOptString(item.SharedID), + } + }) + } + return &readDto{ + callQueueID: callQueueID, + policyVoiceMailMembers: policyVoiceMailMembers, + }, nil +} + +func (c *crud) add(ctx context.Context, dto *addDto) error { + var voicemailAccessMembers []zoomphone.AddCQPolicySubSettingReqVoicemailAccessMembersItem + if dto.voicemailAccessMembers != nil { + voicemailAccessMembers = lo.Map(dto.voicemailAccessMembers, func(item *addDtoVoicemailAccessMember, index int) zoomphone.AddCQPolicySubSettingReqVoicemailAccessMembersItem { + return zoomphone.AddCQPolicySubSettingReqVoicemailAccessMembersItem{ + AccessUserID: util.ToPhoneOptString(item.accessUserID), + AllowDownload: util.ToPhoneOptBool(item.allowDownload), + AllowDelete: util.ToPhoneOptBool(item.allowDelete), + AllowSharing: util.ToPhoneOptBool(item.allowSharing), + } + }) + } + _, err := c.client.AddCQPolicySubSetting(ctx, zoomphone.OptAddCQPolicySubSettingReq{ + Value: zoomphone.AddCQPolicySubSettingReq{ + VoicemailAccessMembers: voicemailAccessMembers, + }, + Set: true, + }, zoomphone.AddCQPolicySubSettingParams{ + CallQueueId: dto.callQueueID.ValueString(), + PolicyType: dto.policyType.String(), + }) + if err != nil { + return fmt.Errorf("error creating phone call queue policy: %v", err) + } + return nil +} + +func (c *crud) update(ctx context.Context, dto *updateDto) error { + var voicemailAccessMembers []zoomphone.UpdateCQPolicySubSettingReqVoicemailAccessMembersItem + if dto.voicemailAccessMembers != nil { + voicemailAccessMembers = lo.Map(dto.voicemailAccessMembers, func(item *updateDtoVoicemailAccessMember, index int) zoomphone.UpdateCQPolicySubSettingReqVoicemailAccessMembersItem { + return zoomphone.UpdateCQPolicySubSettingReqVoicemailAccessMembersItem{ + AccessUserID: util.ToPhoneOptString(item.accessUserID), + AllowDownload: util.ToPhoneOptBool(item.allowDownload), + AllowDelete: util.ToPhoneOptBool(item.allowDelete), + AllowSharing: util.ToPhoneOptBool(item.allowSharing), + SharedID: util.ToPhoneOptString(item.sharedID), + } + }) + } + err := c.client.UpdateCQPolicySubSetting(ctx, zoomphone.OptUpdateCQPolicySubSettingReq{ + Value: zoomphone.UpdateCQPolicySubSettingReq{ + VoicemailAccessMembers: voicemailAccessMembers, + }, + Set: true, + }, zoomphone.UpdateCQPolicySubSettingParams{ + CallQueueId: dto.callQueueID.ValueString(), + PolicyType: dto.policyType.String(), + }) + if err != nil { + return fmt.Errorf("error updating phone call queue policy: %v", err) + } + return nil +} + +func (c *crud) remove(ctx context.Context, dto *removeDto) error { + // maxItems: 20 + for _, chunk := range lo.Chunk(dto.sharedIDs, 20) { + err := c.client.RemoveCQPolicySubSetting(ctx, zoomphone.RemoveCQPolicySubSettingParams{ + CallQueueId: dto.callQueueID.ValueString(), + PolicyType: dto.policyType.String(), + SharedIds: lo.Map(chunk, func(item types.String, index int) string { + return item.ValueString() + }), + }) + if err != nil { + var status *zoomphone.ErrorResponseStatusCode + if errors.As(err, &status) { + if status.StatusCode == 400 && status.Response.Code.Value == 404 { + return nil + } + } + return fmt.Errorf("error removing phone call queue policy: %v", err) + } + } + return nil +} diff --git a/internal/services/phone/callqueuepolicy/call_queue_policy_dto.go b/internal/services/phone/callqueuepolicy/call_queue_policy_dto.go new file mode 100644 index 0000000..c4859b9 --- /dev/null +++ b/internal/services/phone/callqueuepolicy/call_queue_policy_dto.go @@ -0,0 +1,66 @@ +package callqueuepolicy + +import ( + "github.com/hashicorp/terraform-plugin-framework/types" +) + +type PolicyType int + +const ( + VoiceMail PolicyType = iota +) + +func (pt PolicyType) String() string { + switch pt { + case VoiceMail: + return "voice_mail" + default: + return "" + } +} + +type readDto struct { + callQueueID types.String + policyVoiceMailMembers []*readDtoPolicyVoiceMailMember +} + +type readDtoPolicyVoiceMailMember struct { + accessUserID types.String + allowDownload types.Bool + allowDelete types.Bool + allowSharing types.Bool + sharedID types.String +} + +type addDto struct { + callQueueID types.String + policyType PolicyType + voicemailAccessMembers []*addDtoVoicemailAccessMember +} + +type addDtoVoicemailAccessMember struct { + accessUserID types.String + allowDownload types.Bool + allowDelete types.Bool + allowSharing types.Bool +} + +type updateDto struct { + callQueueID types.String + policyType PolicyType + voicemailAccessMembers []*updateDtoVoicemailAccessMember +} + +type updateDtoVoicemailAccessMember struct { + accessUserID types.String + allowDownload types.Bool + allowDelete types.Bool + allowSharing types.Bool + sharedID types.String +} + +type removeDto struct { + callQueueID types.String + policyType PolicyType + sharedIDs []types.String +} diff --git a/internal/services/phone/callqueuepolicy/call_queue_policy_voice_mail_resource.go b/internal/services/phone/callqueuepolicy/call_queue_policy_voice_mail_resource.go new file mode 100644 index 0000000..85ef621 --- /dev/null +++ b/internal/services/phone/callqueuepolicy/call_queue_policy_voice_mail_resource.go @@ -0,0 +1,356 @@ +package callqueuepolicy + +import ( + "context" + "fmt" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" + "github.com/samber/lo" + "strings" + + "github.com/folio-sec/terraform-provider-zoom/internal/provider/shared" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-log/tflog" +) + +var ( + _ resource.Resource = &tfVoiceMailResource{} + _ resource.ResourceWithConfigure = &tfVoiceMailResource{} + _ resource.ResourceWithImportState = &tfVoiceMailResource{} +) + +func NewPhoneCallQueuePolicyVoiceMailResource() resource.Resource { + return &tfVoiceMailResource{} +} + +type tfVoiceMailResource struct { + crud *crud +} + +func (r *tfVoiceMailResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { + if req.ProviderData == nil { + return + } + data, ok := req.ProviderData.(*shared.ProviderData) + if !ok { + resp.Diagnostics.AddError( + "Unexpected ProviderData Source Configure Type", + fmt.Sprintf("Expected *provider.ProviderData, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + return + } + r.crud = newCrud(data.PhoneClient) +} + +func (r *tfVoiceMailResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_phone_call_queue_policy_voice_mail" +} + +func (r *tfVoiceMailResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) { + resp.Schema = schema.Schema{ + MarkdownDescription: `The policy sub-setting for a specific call queue according to the voice_mail. + +## API Permissions +The following API permissions are required in order to use this resource. +This resource requires the ` + strings.Join([]string{ + "`phone:read:call_queue:admin`", + "`phone:write:call_queue_policy:admin`", + "`phone:update:call_queue_policy:admin`", + "`phone:delete:call_queue_policy:admin`", + }, ", ") + ".", + Attributes: map[string]schema.Attribute{ + "call_queue_id": schema.StringAttribute{ + Required: true, + MarkdownDescription: "Unique identifier of the Call Queue.", + }, + "access_members": schema.SetNestedAttribute{ + Required: true, + MarkdownDescription: "The shared voicemail access member list.", + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "access_user_id": schema.StringAttribute{ + Required: true, + MarkdownDescription: "The Zoom user ID or email to share or update the access permissions with.", + }, + "allow_download": schema.BoolAttribute{ + Required: true, + MarkdownDescription: "Specifies whether the member has download permissions. The default is **false**.", + }, + "allow_delete": schema.BoolAttribute{ + Required: true, + MarkdownDescription: "Specifies whether the member has delete permissions. The default is **false**.", + }, + "allow_sharing": schema.BoolAttribute{ + Required: true, + MarkdownDescription: "Specifies whether the member has the permission to share. The default is **false**.", + }, + "shared_id": schema.StringAttribute{ + Computed: true, + MarkdownDescription: "The number is limited to the minimum value of 10 or the number of allowed access members account setting.", + PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}, + }, + }, + }, + }, + }, + } +} + +type resourceVoiceMailModel struct { + CallQueueID types.String `tfsdk:"call_queue_id"` + AccessMembers []resourceVoiceMailModelAccessMember `tfsdk:"access_members"` +} + +type resourceVoiceMailModelAccessMember struct { + AccessUserId types.String `tfsdk:"access_user_id"` + AllowDownload types.Bool `tfsdk:"allow_download"` + AllowDelete types.Bool `tfsdk:"allow_delete"` + AllowSharing types.Bool `tfsdk:"allow_sharing"` + SharedId types.String `tfsdk:"shared_id"` +} + +func (r *tfVoiceMailResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { + var state resourceVoiceMailModel + diags := req.State.Get(ctx, &state) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + output, err := r.read(ctx, state.CallQueueID) + if err != nil { + resp.Diagnostics.AddError("Error reading phone call queue policy voice mail", err.Error()) + return + } + + tflog.Error(ctx, fmt.Sprintf("read output %v", output)) + diags = resp.State.Set(ctx, &output) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } +} + +func (r *tfVoiceMailResource) read(ctx context.Context, callQueueID types.String) (*resourceVoiceMailModel, error) { + dto, err := r.crud.read(ctx, callQueueID) + if err != nil { + return nil, fmt.Errorf("error read: %v", err) + } + if dto == nil { + return nil, nil // already deleted + } + + return &resourceVoiceMailModel{ + CallQueueID: dto.callQueueID, + AccessMembers: lo.Map(dto.policyVoiceMailMembers, func(item *readDtoPolicyVoiceMailMember, index int) resourceVoiceMailModelAccessMember { + return resourceVoiceMailModelAccessMember{ + AccessUserId: item.accessUserID, + AllowDownload: item.allowDownload, + AllowDelete: item.allowDelete, + AllowSharing: item.allowSharing, + SharedId: item.sharedID, + } + }), + }, nil +} + +func (r *tfVoiceMailResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + var plan resourceVoiceMailModel + diags := req.Plan.Get(ctx, &plan) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + if err := r.sync(ctx, plan); err != nil { + resp.Diagnostics.AddError( + "Error creating phone call queue policy voice mail", + err.Error(), + ) + return + } + + output, err := r.read(ctx, plan.CallQueueID) + if err != nil { + resp.Diagnostics.AddError("Error creating phone call queue voice mail on reading", err.Error()) + return + } + diags = resp.State.Set(ctx, output) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } +} + +func (r *tfVoiceMailResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { + var plan resourceVoiceMailModel + diags := req.Plan.Get(ctx, &plan) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + resp.Diagnostics.AddError( + "Error updating phone call queue policy", + "Error updating phone call queue policy", + ) + return + } + + if err := r.sync(ctx, plan); err != nil { + resp.Diagnostics.AddError( + "Error updating phone call queue policy voice mail", + err.Error(), + ) + return + } + + output, err := r.read(ctx, plan.CallQueueID) + if err != nil { + resp.Diagnostics.AddError("Error updating phone call queue voice mail", err.Error()) + return + } + diags = resp.State.Set(ctx, output) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } +} + +func (r *tfVoiceMailResource) sync(ctx context.Context, plan resourceVoiceMailModel) error { + asis, err := r.read(ctx, plan.CallQueueID) + if err != nil { + return fmt.Errorf( + "could not sync phone call queue policy voice mail %s on read, unexpected error: %v", + plan.CallQueueID.ValueString(), + err, + ) + } + + // remove members + var removeSharedIDs []types.String + for _, asisMember := range asis.AccessMembers { + planExisted := lo.ContainsBy(plan.AccessMembers, func(planItem resourceVoiceMailModelAccessMember) bool { + return planItem.AccessUserId == asisMember.AccessUserId + }) + if !planExisted { + removeSharedIDs = append(removeSharedIDs, asisMember.SharedId) + } + } + if len(removeSharedIDs) > 0 { + if err = r.crud.remove(ctx, &removeDto{ + callQueueID: plan.CallQueueID, + policyType: VoiceMail, + sharedIDs: removeSharedIDs, + }); err != nil { + return fmt.Errorf( + "could not sync phone call queue policy voice mail %s on remove, unexpected error: %v", + plan.CallQueueID.ValueString(), + err, + ) + } + } + + // add members + addMembers := lo.Filter(plan.AccessMembers, func(planItem resourceVoiceMailModelAccessMember, index int) bool { + return planItem.SharedId.ValueString() == "" + }) + if len(addMembers) > 0 { + if err = r.crud.add(ctx, &addDto{ + callQueueID: plan.CallQueueID, + policyType: VoiceMail, + voicemailAccessMembers: lo.Map(addMembers, func(item resourceVoiceMailModelAccessMember, index int) *addDtoVoicemailAccessMember { + return &addDtoVoicemailAccessMember{ + accessUserID: item.AccessUserId, + allowDownload: item.AllowDownload, + allowDelete: item.AllowDelete, + allowSharing: item.AllowSharing, + } + }), + }); err != nil { + return fmt.Errorf( + "could not sync phone call queue policy voice mail %s on add, unexpected error: %v", + plan.CallQueueID.ValueString(), + err, + ) + } + } + + // update members + updateMembers := lo.Filter(plan.AccessMembers, func(planItem resourceVoiceMailModelAccessMember, index int) bool { + return planItem.SharedId.ValueString() != "" + }) + if err := r.crud.update(ctx, &updateDto{ + callQueueID: plan.CallQueueID, + policyType: VoiceMail, + voicemailAccessMembers: lo.Map(updateMembers, func(item resourceVoiceMailModelAccessMember, index int) *updateDtoVoicemailAccessMember { + return &updateDtoVoicemailAccessMember{ + accessUserID: item.AccessUserId, + allowDownload: item.AllowDownload, + allowDelete: item.AllowDelete, + allowSharing: item.AllowSharing, + sharedID: item.SharedId, + } + }), + }); err != nil { + return fmt.Errorf( + "could not update phone call queue policy voice mail %s on update, unexpected error: %v", + plan.CallQueueID.ValueString(), + err, + ) + } + return nil +} + +func (r *tfVoiceMailResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { + var state resourceVoiceMailModel + diags := req.State.Get(ctx, &state) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + asis, err := r.read(ctx, state.CallQueueID) + if err != nil { + resp.Diagnostics.AddError( + "Error deleting phone call queue policy voice mail on read", + fmt.Sprintf( + "Could not delete phone call queue policy %s, unexpected error: %s", + state.CallQueueID.ValueString(), + err, + ), + ) + return + } + if asis == nil || len(asis.AccessMembers) == 0 { + return + } + + var removeSharedIDs []types.String + for _, asisMember := range asis.AccessMembers { + removeSharedIDs = append(removeSharedIDs, asisMember.SharedId) + } + if err := r.crud.remove(ctx, &removeDto{ + callQueueID: state.CallQueueID, + policyType: VoiceMail, + sharedIDs: removeSharedIDs, + }); err != nil { + resp.Diagnostics.AddError( + "Error deleting phone call queue policy voice mail", + fmt.Sprintf( + "Could not delete phone call queue policy %s, unexpected error: %s", + state.CallQueueID.ValueString(), + err, + ), + ) + return + } + + tflog.Info(ctx, "deleted phone call queue policy voice mail", map[string]interface{}{ + "call_queue_id": state.CallQueueID.ValueString(), + }) +} + +func (r *tfVoiceMailResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { + resource.ImportStatePassthroughID(ctx, path.Root("call_queue_id"), req, resp) +}