Skip to content

Commit

Permalink
feat(cph): support updating cph phone property
Browse files Browse the repository at this point in the history
  • Loading branch information
luoping-12345 committed Nov 22, 2024
1 parent ae6aa08 commit 6c9ca32
Show file tree
Hide file tree
Showing 4 changed files with 309 additions and 0 deletions.
64 changes: 64 additions & 0 deletions docs/resources/cph_phone_property.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
subcategory: "Cloud Phone (CPH)"
layout: "huaweicloud"
page_title: "HuaweiCloud: huaweicloud_cph_phone_property"
description: |-
Manages a CPH phone property resource within HuaweiCloud.
---

# huaweicloud_cph_phone_property

Manages a CPH phone property resource within HuaweiCloud.

## Example Usage

```hcl
variable "phone_id" {}
resource "huaweicloud_cph_phone_property" "test" {
phones {
phone_id = var.phone_id
property = jsonencode({
"com.cph.mainkeys":0,
"disable.status.bar":0,
"ro.permission.changed":0,
"ro.horizontal.screen":0,
"ro.install.auto":0,
"ro.com.cph.sfs_enable":0,
"ro.product.manufacturer":"Huawei",
"ro.product.name":"monbox",
"ro.com.cph.notification_disable":0
})
}
}
```

## Argument Reference

The following arguments are supported:

* `region` - (Optional, String, ForceNew) Specifies the region in which to create the resource.
If omitted, the provider-level region will be used.
Changing this creates a new resource.

* `phones` - (Required, List, NonUpdatable) Specifies the CPH phones.
The [phones](#cph_phones) structure is documented below.

<a name="cph_phones"></a>
The `phones` block supports:

* `phone_id` - (Required, String, NonUpdatable) Specifies the phone ID.

* `property` - (Required, String, NonUpdatable) Specifies the phone property, the format is json string.

## Attribute Reference

In addition to all arguments above, the following attributes are exported:

* `id` - The resource ID.

## Timeouts

This resource provides the following timeouts configuration options:

* `create` - Default is 30 minutes.
1 change: 1 addition & 0 deletions huaweicloud/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -1435,6 +1435,7 @@ func Provider() *schema.Provider {
"huaweicloud_cph_server_restart": cph.ResourceServerRestart(),
"huaweicloud_cph_phone_reset": cph.ResourcePhoneReset(),
"huaweicloud_cph_share_app": cph.ResourceShareApp(),
"huaweicloud_cph_phone_property": cph.ResourcePhoneProperty(),

"huaweicloud_cse_microservice": cse.ResourceMicroservice(),
"huaweicloud_cse_microservice_engine": cse.ResourceMicroserviceEngine(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package cph

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"

"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/acceptance"
)

func TestAccCphPhoneProperty_basic(t *testing.T) {
name := acceptance.RandomAccResourceName()

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
acceptance.TestAccPreCheck(t)
},
ProviderFactories: acceptance.TestAccProviderFactories,
CheckDestroy: nil,
Steps: []resource.TestStep{
{
Config: testCphPhoneProperty_basic(name),
},
},
})
}

func testCphPhoneProperty_basic(name string) string {
return fmt.Sprintf(`
%[1]s
data "huaweicloud_cph_phones" "test" {
server_id = huaweicloud_cph_server.test.id
}
resource "huaweicloud_cph_phone_property" "test" {
phones {
phone_id = data.huaweicloud_cph_phones.test.phones[0].phone_id
property = jsonencode({
"com.cph.mainkeys":0,
"disable.status.bar":0,
"ro.permission.changed":0,
"ro.horizontal.screen":0,
"ro.install.auto":0,
"ro.com.cph.sfs_enable":0,
"ro.product.manufacturer":"Huawei",
"ro.product.name":"monbox",
"ro.com.cph.notification_disable":0
})
}
}
`, testCphServer_build(name))
}

func testCphServer_build(name string) string {
return fmt.Sprintf(`
%s
resource "huaweicloud_cph_server" "test" {
name = "%s"
server_flavor = "physical.rx1.xlarge"
phone_flavor = "rx1.cp.c15.d46.e1v1"
image_id = data.huaweicloud_cph_phone_images.test.images[0].id
keypair_name = huaweicloud_kps_keypair.test.name
vpc_id = huaweicloud_vpc.test.id
subnet_id = huaweicloud_vpc_subnet.test.id
eip_type = "5_bgp"
bandwidth {
share_type = "0"
charge_mode = "1"
size = 300
}
period_unit = "month"
period = 1
auto_renew = "true"
lifecycle {
ignore_changes = [
image_id, auto_renew, period, period_unit,
]
}
}
`, testCphServerBase(name), name)
}
156 changes: 156 additions & 0 deletions huaweicloud/services/cph/resource_huaweicloud_cph_phone_property.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
package cph

import (
"context"
"strings"
"time"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"

"github.com/chnsz/golangsdk"

"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/config"
"github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/utils"
)

var PhonePropertyNonUpdatableParams = []string{"phones", "phones.*.phone_id", "phones.*.property"}

// @API CPH POST /v1/{project_id}/cloud-phone/phones/batch-update-property
// @API CPH GET /v1/{project_id}/cloud-phone/jobs/{job_id}
func ResourcePhoneProperty() *schema.Resource {
return &schema.Resource{
CreateContext: resourcePhonePropertyCreate,
UpdateContext: resourcePhonePropertyUpdate,
ReadContext: resourcePhonePropertyRead,
DeleteContext: resourcePhonePropertyDelete,

Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(30 * time.Minute),
},

CustomizeDiff: config.FlexibleForceNew(PhoneResetNonUpdatableParams),

Schema: map[string]*schema.Schema{
"region": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"phones": {
Type: schema.TypeList,
Required: true,
MaxItems: 1,
Description: `Specifies the CPH phones.`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"phone_id": {
Type: schema.TypeString,
Required: true,
Description: `Specifies the phone ID.`,
},
"property": {
Type: schema.TypeString,
Required: true,
Description: `Specifies the phone property, the format is json string.`,
},
},
},
},
"enable_force_new": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{"true", "false"}, false),
Description: utils.SchemaDesc("", utils.SchemaDescInput{Internal: true}),
},
},
}
}

func resourcePhonePropertyCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
cfg := meta.(*config.Config)
region := cfg.GetRegion(d)

client, err := cfg.NewServiceClient("cph", region)
if err != nil {
return diag.Errorf("error creating CPH client: %s", err)
}

// updatePhoneProperty: update CPH phone property
updatePhonePropertyHttpUrl := "v1/{project_id}/cloud-phone/phones/batch-update-property"
updatePhonePropertyPath := client.Endpoint + updatePhonePropertyHttpUrl
updatePhonePropertyPath = strings.ReplaceAll(updatePhonePropertyPath, "{project_id}", client.ProjectID)

updatePhonePropertyOpt := golangsdk.RequestOpts{
KeepResponseBody: true,
}

updatePhonePropertyOpt.JSONBody = utils.RemoveNil(map[string]interface{}{
"phones": d.Get("phones"),
})
updatePhonePropertyResp, err := client.Request("POST", updatePhonePropertyPath, &updatePhonePropertyOpt)
if err != nil {
return diag.Errorf("error updating CPH phone property: %s", err)
}

resp, err := utils.FlattenResponse(updatePhonePropertyResp)
if err != nil {
return diag.FromErr(err)
}
id := utils.PathSearch("jobs|[0].job_id", resp, "").(string)
if id == "" {
return diag.Errorf("unable to find the job ID from the API response")
}
d.SetId(id)

errorCode := utils.PathSearch("jobs|[0].error_code", resp, "").(string)
if errorCode != "" {
phoneId := utils.PathSearch("jobs|[0].phone_id", resp, "").(string)
errorMsg := utils.PathSearch("jobs|[0].error_msg", resp, "").(string)
return diag.Errorf("failed to updating CPH phone property (phone_id: %s), error_code: %s, error_msg: %s", phoneId, errorCode, errorMsg)
}

err = checkPhonePropertyJobStatus(ctx, client, d.Id(), d.Timeout(schema.TimeoutCreate))
if err != nil {
return diag.FromErr(err)
}

return nil
}

func resourcePhonePropertyRead(_ context.Context, _ *schema.ResourceData, _ interface{}) diag.Diagnostics {
return nil
}

func resourcePhonePropertyUpdate(_ context.Context, _ *schema.ResourceData, _ interface{}) diag.Diagnostics {
return nil
}

func resourcePhonePropertyDelete(_ context.Context, _ *schema.ResourceData, _ interface{}) diag.Diagnostics {
errorMsg := "Deleting CPH phone property resource is not supported. The resource is only removed from the state."
return diag.Diagnostics{
diag.Diagnostic{
Severity: diag.Warning,
Summary: errorMsg,
},
}
}

func checkPhonePropertyJobStatus(ctx context.Context, client *golangsdk.ServiceClient, id string, timeout time.Duration) error {
stateConf := &resource.StateChangeConf{
Pending: []string{"PENDING"},
Target: []string{"COMPLETED"},
Refresh: jobStatusRefreshFunc(client, id),
Timeout: timeout,
PollInterval: 10 * timeout,
Delay: 10 * time.Second,
}
_, err := stateConf.WaitForStateContext(ctx)
if err != nil {
return err
}
return nil
}

0 comments on commit 6c9ca32

Please sign in to comment.