Skip to content

Commit

Permalink
add zoom_phone_user_calling_plans resource
Browse files Browse the repository at this point in the history
Signed-off-by: Tadayuki Onishi <tonishi@folio-sec.com>
  • Loading branch information
Tadayuki Onishi committed Aug 24, 2024
1 parent 8df3baa commit bbada5e
Show file tree
Hide file tree
Showing 8 changed files with 676 additions and 0 deletions.
146 changes: 146 additions & 0 deletions docs/resources/phone_user_calling_plans.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "zoom_phone_user_calling_plans Resource - zoom"
subcategory: ""
description: |-
Assigns calling plans to a Zoom Phone user.
API Permissions
The following API permissions are required in order to use this resource.
This resource requires the phone:read:user:admin, phone:write:calling_plan:admin, phone:delete:users_calling_plan:admin.
---

# zoom_phone_user_calling_plans (Resource)

Assigns calling plans to a Zoom Phone user.

## API Permissions

The following API permissions are required in order to use this resource.
This resource requires the `phone:read:user:admin`, `phone:write:calling_plan:admin`, `phone:delete:users_calling_plan:admin`.

## Example Usage

```terraform
resource "zoom_phone_user" "example" {
user_id = "AAggbuS-Q6aXXcsv2wnug"
extension_number = 101
}
resource "zoom_phone_user_calling_plans" "example" {
user_id = zoom_phone_user.example.user_id
calling_plans = [
{
type = 207
},
]
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `calling_plans` (Attributes Set) Use this attribute to configure settings for the calling plan of the user. (see [below for nested schema](#nestedatt--calling_plans))
- `user_id` (String) The ID of the Zoom user.

<a id="nestedatt--calling_plans"></a>
### Nested Schema for `calling_plans`

Required:

- `type` (Number) The [type](https://marketplace.zoom.us/docs/api-reference/other-references/plans#zoom-phone-calling-plans) of calling plan. Allowed: `61000`, `101`, `304`, `41000`, `50202`, `60202`, `203`, `107`, `31001`, `31005`, `50201`, `60201`, `1`, `1001`, `31007`, `51000`, `303`, `103`, `402`, `2000`, `31000`, `43000`, `50207`, `4`, `207`, `302`, `600`, `3000`, `31004`, `100`, `3010`, `31003`, `204`, `201`, `400`, `30007`, `40200`, `70207`, `6`, `404`, `40202`, `102`, `307`, `200`, `3099`, `4000`, `4010`, `30001`, `71000`, `202`, `31002`, `31006`, `40201`, `63000`, `70202`, `30003`, `30000`, `53000`, `70200`, `300`, `5`, `3098`, `3`, `5000`, `30002`, `30004`, `40207`, `50200`, `60200`, `60207`, `3040`, `70201`, `301`, `401`, `403`, `1000`, `104`
- `70200`: MEETINGS_US_CA_NUMBER_INCLUDED
- `300`: US_CA_NUMBER
- `30000`: METERED_US_CA_NUMBER_INCLUDED
- `53000`: MEETINGS_BUS_PN_PRO
- `3`: INTERNATIONAL_TOLL_NUMBER
- `5`: BYOC_NUMBER
- `3098`: RESERVED_PLAN
- `30004`: METERED_EURB_NUMBER_INCLUDED
- `40207`: MEETINGS_PRO_UNLIMITED_JP
- `50200`: MEETINGS_BUS_UNLIMITED_US_CA
- `60200`: MEETINGS_ENT_UNLIMITED_US_CA
- `60207`: MEETINGS_ENT_UNLIMITED_JP
- `3040`: ZP_COMMON_AREA
- `5000`: PREMIUM_NUMBER
- `30002`: METERED_GB_IE_NUMBER_INCLUDED
- `70201`: MEETINGS_AU_NZ_NUMBER_INCLUDED
- `403`: NZ_TOLLFREE_NUMBER
- `1000`: UNLIMITED_DOMESTIC_SELECT
- `104`: METERED_EURB
- `301`: AU_NZ_NUMBER
- `401`: AU_TOLLFREE_NUMBER
- `101`: METERED_PLAN_AU_NZ
- `61000`: MEETINGS_ENT_GLOBAL_SELECT
- `50202`: MEETINGS_BUS_UNLIMITED_GB_IE
- `60202`: MEETINGS_ENT_UNLIMITED_GB_IE
- `203`: UNLIMITED_EURA
- `304`: EURB_NUMBER
- `41000`: MEETINGS_PRO_GLOBAL_SELECT
- `31005`: UNLIMITED_DOMESTIC_SELECT_NUMBER_INCLUDED
- `50201`: MEETINGS_BUS_UNLIMITED_AU_NZ
- `60201`: MEETINGS_ENT_UNLIMITED_AU_NZ
- `1`: NO_FEATURE_PACKAGE
- `107`: METERED_JP
- `31001`: UNLIMITED_AU_NZ_NUMBER_INCLUDED
- `51000`: MEETINGS_BUS_GLOBAL_SELECT
- `303`: EURA_NUMBER
- `1001`: METERED_GLOBAL_SELECT
- `31007`: UNLIMITED_JP_NUMBER_INCLUDED
- `2000`: UNLIMITED_DOMESTIC_SELECT_NUMBER
- `31000`: UNLIMITED_US_CA_NUMBER_INCLUDED
- `43000`: MEETINGS_PRO_PN_PRO
- `50207`: MEETINGS_BUS_UNLIMITED_JP
- `4`: INTERNATIONAL_TOLL_FREE_NUMBER
- `103`: METERED_EURA
- `402`: GB_IE_TOLLFREE_NUMBER
- `600`: BETA
- `3000`: ZP_PRO
- `31004`: UNLIMITED_EURB_NUMBER_INCLUDED
- `100`: METERED_PLAN_US_CA
- `207`: UNLIMITED_JP
- `302`: GB_IE_NUMBER
- `204`: UNLIMITED_EURB
- `3010`: BASIC
- `31003`: UNLIMITED_EURA_NUMBER_INCLUDED
- `30007`: METERED_JP_NUMBER_INCLUDED
- `40200`: MEETINGS_PRO_UNLIMITED_US_CA
- `70207`: MEETINGS_JP_NUMBER_INCLUDED
- `6`: BETA_NUMBER
- `201`: UNLIMITED_PLAN_AU_NZ
- `400`: US_CA_TOLLFREE_NUMBER
- `102`: METERED_PLAN_GB_IE
- `404`: GLOBAL_TOLLFREE_NUMBER
- `40202`: MEETINGS_PRO_UNLIMITED_GB_IE
- `200`: UNLIMITED_PLAN_US_CA
- `307`: JP_NUMBER
- `4010`: ZP_PREMIUM_ADDON
- `30001`: METERED_AU_NZ_NUMBER_INCLUDED
- `71000`: MEETINGS_GLOBAL_SELECT_NUMBER_INCLUDED
- `202`: UNLIMITED_PLAN_GB_IE
- `3099`: BASIC_MIGRATED
- `4000`: INTERNATIONAL_SELECT_ADDON
- `40201`: MEETINGS_PRO_UNLIMITED_AU_NZ
- `63000`: MEETINGS_ENT_PN_PRO
- `70202`: MEETINGS_GB_IE_NUMBER_INCLUDED
- `30003`: METERED_EURA_NUMBER_INCLUDED
- `31002`: UNLIMITED_GB_IE_NUMBER_INCLUDED
- `31006`: METERED_GLOBAL_SELECT_NUMBER_INCLUDED

Optional:

- `billing_account_id` (String) The billing account ID. If the user is located in India, the field is required.

Read-Only:

- `name` (String) The name of the calling plan.

## Import

Import is supported using the following syntax:

```shell
# ${user_id}
terraform import zoom_phone_user_calling_plans.example AAggbuS-Q6aXXcsv2wnug
```
2 changes: 2 additions & 0 deletions examples/resources/zoom_phone_user_calling_plans/import.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# ${user_id}
terraform import zoom_phone_user_calling_plans.example AAggbuS-Q6aXXcsv2wnug
21 changes: 21 additions & 0 deletions examples/resources/zoom_phone_user_calling_plans/provider.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
terraform {
required_providers {
zoom = {
source = "registry.terraform.io/folio-sec/zoom"
}
}
}

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
}
13 changes: 13 additions & 0 deletions examples/resources/zoom_phone_user_calling_plans/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
resource "zoom_phone_user" "example" {
user_id = "AAggbuS-Q6aXXcsv2wnug"
extension_number = 101
}

resource "zoom_phone_user_calling_plans" "example" {
user_id = zoom_phone_user.example.user_id
calling_plans = [
{
type = 207
},
]
}
2 changes: 2 additions & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
sharedlinegroupgroupmembers "github.com/folio-sec/terraform-provider-zoom/internal/services/phone/sharedlinegroupmember"
sharedlinegroupgroupphonenumbers "github.com/folio-sec/terraform-provider-zoom/internal/services/phone/sharedlinegroupphonenumber"
phoneuser "github.com/folio-sec/terraform-provider-zoom/internal/services/phone/user"
"github.com/folio-sec/terraform-provider-zoom/internal/services/phone/usercallingplans"
"github.com/folio-sec/terraform-provider-zoom/internal/services/phone/userphonenumber"
"github.com/folio-sec/terraform-provider-zoom/internal/services/user/user"
"github.com/folio-sec/terraform-provider-zoom/internal/zoomoauth"
Expand Down Expand Up @@ -215,6 +216,7 @@ func (p *zoomProvider) Resources(_ context.Context) []func() resource.Resource {
sharedlinegroupgroupmembers.NewPhoneSharedLineGroupMembersResource,
sharedlinegroupgroupphonenumbers.NewPhoneSharedLineGroupPhoneNumbersResource,
phoneuser.NewPhoneUserResource,
usercallingplans.NewPhoneUserCallingPlansResource,
userphonenumber.NewPhoneUserPhoneNumbersResource,
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package usercallingplans

import (
"context"
"errors"
"fmt"
"strconv"

"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"
lop "github.com/samber/lo/parallel"
)

func newCrud(client *zoomphone.Client) *crud {
return &crud{
client: client,
}
}

type crud struct {
client *zoomphone.Client
}

func (c *crud) read(ctx context.Context, userID types.String) (*readDto, error) {
ret, err := c.client.PhoneUser(ctx, zoomphone.PhoneUserParams{
UserId: userID.ValueString(),
})
if err != nil {
return nil, fmt.Errorf("unable to read phone user: %v", err)
}

return &readDto{
callingPlans: lo.Map(ret.CallingPlans, func(v zoomphone.PhoneUserOKCallingPlansItem, _ int) readDtoCallingPlan {
return readDtoCallingPlan{
callingPlanType: util.FromOptInt(v.Type),
callingPlanName: util.FromOptString(v.Name),
billingAccountID: util.FromOptString(v.BillingAccountID),
}
}),
}, nil
}

func (c *crud) create(ctx context.Context, dto createDto) (*createdDto, error) {
_, err := c.client.AssignCallingPlan(ctx, zoomphone.NewOptAssignCallingPlanReq(zoomphone.AssignCallingPlanReq{
CallingPlans: lo.Map(dto.callingPlans, func(v createDtoCallingPlan, _ int) zoomphone.AssignCallingPlanReqCallingPlansItem {
return zoomphone.AssignCallingPlanReqCallingPlansItem{
Type: util.ToPhoneOptInt(v.callingPlanType),
BillingAccountID: util.ToPhoneOptString(v.billingAccountID),
}
}),
}), zoomphone.AssignCallingPlanParams{
UserId: dto.userID.ValueString(),
})
if err != nil {
var status *zoomphone.ErrorResponseStatusCode
if errors.As(err, &status) {
if status.StatusCode == 400 && status.Response.Code.Value == 300 {
_ = 1
}
}
return nil, fmt.Errorf("unable to create phone user calling plan: %v", err)
}
return &createdDto{}, nil
}

func (c *crud) delete(ctx context.Context, dto deleteDto) error {
errs := lo.Compact(lop.Map(dto.callingPlans, func(v deleteDtoCallingPlan, _ int) error {
err := c.client.UnassignCallingPlan(ctx, zoomphone.UnassignCallingPlanParams{
UserId: dto.userID.ValueString(),
PlanType: strconv.Itoa(int(v.callingPlanType.ValueInt32())),
BillingAccountID: util.ToPhoneOptString(v.billingAccountID),
})

if err != nil {
var status *zoomphone.ErrorResponseStatusCode
if errors.As(err, &status) {
if status.StatusCode == 404 {
return nil // already deleted
}
}
return fmt.Errorf("unable to delete phone user calling plan: %v", err)
}

return nil
}))

if len(errs) > 0 {
return errors.Join(errs...)
}

return nil
}
37 changes: 37 additions & 0 deletions internal/services/phone/usercallingplans/user_calling_plans_dto.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package usercallingplans

import (
"github.com/hashicorp/terraform-plugin-framework/types"
)

type readDto struct {
callingPlans []readDtoCallingPlan
}

type readDtoCallingPlan struct {
callingPlanType types.Int32
callingPlanName types.String
billingAccountID types.String
}

type createDto struct {
userID types.String
callingPlans []createDtoCallingPlan
}

type createDtoCallingPlan struct {
callingPlanType types.Int32
billingAccountID types.String
}

type createdDto struct{}

type deleteDto struct {
userID types.String
callingPlans []deleteDtoCallingPlan
}

type deleteDtoCallingPlan struct {
callingPlanType types.Int32
billingAccountID types.String
}
Loading

0 comments on commit bbada5e

Please sign in to comment.