Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/4215.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:new-resource
tencentcloud_cynosdb_cluster_read_only_instance_group_acces_operation
```
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,11 @@ require (
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.3.105
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cloudaudit v1.0.1033
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cls v1.3.112
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.113
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.115
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/config v1.3.80
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm v1.3.113
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cwp v1.3.30
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cynosdb v1.3.110
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cynosdb v1.3.115
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dayu v1.0.335
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dbbrain v1.3.26
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dc v1.0.633
Expand Down
7 changes: 4 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1003,8 +1003,9 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.107/go.mod
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.108/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.110/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.112/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.113 h1:kDwta48HDOTca5opVg66MUoSmD5gvDXKf0OFEWcnDqM=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.113/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.115 h1:qBIvZmmvegvIiAsSZYxQjcC/al86M3zVyNoC5RAxU6g=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.115/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/config v1.3.80 h1:chnsNBeJn3MieFLki4hpbzoml5NiTvLVzOTqYRVxQho=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/config v1.3.80/go.mod h1:B/ezGtlvDhZlleNM+2QdvZccrUi+J+fN6vMnDDsZnuM=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/controlcenter v1.1.51 h1:pGwrfCBBCt1u+EDHwfNj9NLQpvk5MVKVMcsE7SvwqM4=
Expand All @@ -1015,8 +1016,8 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm v1.3.113 h1:hXYW4sq
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm v1.3.113/go.mod h1:ZQwl20BTOl5GZdNC9E6G5d7bbDrdn22m7txsX2mO3kc=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cwp v1.3.30 h1:evU6/8eA7nay2ZZl/WcmRO/E1eEjPC5zAX5dNAMCoko=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cwp v1.3.30/go.mod h1:1zyxbBDx3OeAJa8Tmp0UJu4iJ0eTYQvhZzIYpXRuF/c=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cynosdb v1.3.110 h1:QOFGuGnbRjTPji1YkPrZd5ywYAdPClF7aoLldgDpd44=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cynosdb v1.3.110/go.mod h1:T+CEa+0ttowVLQwgqOOSlHW2ebse1QTq01ps3QoOgdk=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cynosdb v1.3.115 h1:WjC0ynjxqmLtMKOPxgQ4BrOVeiFLtmssZaJjTFsBXdk=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cynosdb v1.3.115/go.mod h1:HvWP1q755+PfkxY1DUZadn5cTrE/JBtJPdlzqFokDcQ=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dasb v1.0.970 h1:qVIRHgG1twsqF4aVN/x2T2yMRfPpsZBTNefDkqzM06M=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dasb v1.0.970/go.mod h1:NJuuQD4z6vcnsZnC7Tvz2U9hElNS1wroc34UQbZvP2U=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dayu v1.0.335 h1:D8qrelkK5udv8RzJJIABMzItGIyaZoYnxEVeIsYqiNw=
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-06-12
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
## Context

CynosDB (TDSQL-C) is a cloud-native database service. Clusters can have read-only instance groups, but access to these groups must be explicitly opened via the `OpenClusterReadOnlyInstanceGroupAccess` API. This API is asynchronous—it returns a `FlowId` that must be polled via `DescribeFlow` until the operation completes.

The existing codebase already has:
- A `CynosdbService.DescribeFlow()` helper in `tencentcloud/services/cynosdb/service_tencentcloud_cynosdb.go` that polls flow status.
- Multiple cynosdb resources that use this pattern (e.g., `cynosdb_cluster_password_complexity`, `cynosdb_proxy_end_point`).
- The `cynosdb/v20190107` SDK package is already vendored.

## Goals / Non-Goals

**Goals:**
- Provide a Terraform `RESOURCE_KIND_OPERATION` resource that opens read-only instance group access for a CynosDB cluster.
- Support async flow polling via `DescribeFlow` to wait for the operation to complete.
- Follow existing provider patterns for operation resources (Create-only, no Read/Update/Delete logic).
- Include unit tests using gomonkey mocks.

**Non-Goals:**
- No Read/Update/Delete lifecycle management (this is a one-shot operation).
- No import support (operation resources are not importable).
- No acceptance tests requiring real cloud credentials.

## Decisions

### 1. Resource structure: Create-only with empty Read/Delete

**Decision**: Implement Create with the API call + flow polling. Read returns nil (no state to read). Delete returns nil (nothing to destroy).

**Rationale**: This follows the established `RESOURCE_KIND_OPERATION` pattern used by `tencentcloud_cls_open_service_operation` and similar resources. The resource ID will be set to a generated token via `helper.BuildToken()` since there's no meaningful ID to track.

**Alternative considered**: Using `cluster_id` as the resource ID. Rejected because the operation is not idempotent and doesn't represent a persistent resource.

### 2. Async flow polling via existing CynosdbService.DescribeFlow

**Decision**: After calling `OpenClusterReadOnlyInstanceGroupAccess`, use `resource.Retry` with `tccommon.WriteRetryTimeout` to poll `CynosdbService.DescribeFlow(flowId)` until it returns success.

**Rationale**: This reuses the existing, well-tested flow polling infrastructure. The `DescribeFlow` helper already handles status codes (0 = success, 2 = failed).

### 3. Schema with Timeouts block

**Decision**: Include a `Timeouts` block with a `Create` timeout to support configurable wait times for the async operation.

**Rationale**: Required by provider conventions for async operations. Users may need longer timeouts for large clusters.

### 4. Unit tests with gomonkey mocks

**Decision**: Use gomonkey to mock the SDK client methods (`OpenClusterReadOnlyInstanceGroupAccessWithContext`, `DescribeFlow`) and test the Create function logic.

**Rationale**: Per project requirements, new terraform resources use gomonkey-based unit tests rather than acceptance tests.

## Risks / Trade-offs

- **[Risk] Flow polling timeout**: The async operation may take longer than the default timeout. → **Mitigation**: Expose configurable `Timeouts.Create` in the schema.
- **[Risk] API returns nil FlowId**: The API might succeed but return a nil FlowId. → **Mitigation**: Check for nil FlowId after the API call and return `NonRetryableError` if nil.
- **[Trade-off] No state tracking**: Since this is an operation resource, there's no way to detect if the operation was already performed. Re-applying will attempt to open access again. → **Accepted**: This is inherent to the RESOURCE_KIND_OPERATION pattern.
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
## Why

CynosDB (TDSQL-C) clusters support read-only instance groups, but currently there is no Terraform resource to enable (open) access to these groups. Users need a one-shot operation resource to programmatically open read-only instance group access for their CynosDB clusters via Terraform.

## What Changes

- Add a new `RESOURCE_KIND_OPERATION` resource `tencentcloud_cynosdb_cluster_read_only_instance_group_acces_operation` that calls the `OpenClusterReadOnlyInstanceGroupAccess` API to enable read-only instance group access.
- The resource is a one-shot operation: it only has a Create implementation (no Read/Update/Delete).
- The Create operation is asynchronous (returns a `FlowId`), so it must poll `DescribeFlow` until the operation completes.
- Input parameters: `cluster_id`, `port`, `security_group_ids`.
- Output (computed) parameter: `flow_id`.

## Capabilities

### New Capabilities
- `cynosdb-cluster-read-only-instance-group-access-operation`: One-shot operation resource to open read-only instance group access for a CynosDB cluster, wrapping the `OpenClusterReadOnlyInstanceGroupAccess` API with async flow polling.

### Modified Capabilities

(none)

## Impact

- New files:
- `tencentcloud/services/cynosdb/resource_tc_cynosdb_cluster_read_only_instance_group_acces_operation.go`
- `tencentcloud/services/cynosdb/resource_tc_cynosdb_cluster_read_only_instance_group_acces_operation_test.go`
- `tencentcloud/services/cynosdb/resource_tc_cynosdb_cluster_read_only_instance_group_acces_operation.md`
- Modified files:
- `tencentcloud/provider.go` (register the new resource)
- `tencentcloud/provider.md` (add resource to documentation list)
- Dependencies: Uses existing `github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cynosdb/v20190107` SDK package (already vendored).
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
## ADDED Requirements

### Requirement: Open read-only instance group access operation resource

The system SHALL provide a Terraform resource `tencentcloud_cynosdb_cluster_read_only_instance_group_acces_operation` that opens read-only instance group access for a CynosDB cluster by calling the `OpenClusterReadOnlyInstanceGroupAccess` API.

The resource SHALL accept the following input parameters:
- `cluster_id` (Required, ForceNew, String): The CynosDB cluster ID.
- `port` (Optional, ForceNew, String): The port for the read-only instance group access.
- `security_group_ids` (Optional, ForceNew, List of String): Security group IDs to associate.

The resource SHALL expose the following computed attributes:
- `flow_id` (Computed, Int): The flow ID returned by the async operation.

The resource SHALL be a one-shot operation (RESOURCE_KIND_OPERATION):
- Create: Calls `OpenClusterReadOnlyInstanceGroupAccess` API, then polls `DescribeFlow` until completion.
- Read: Returns nil (no state to read back).
- Delete: Returns nil (nothing to destroy).

#### Scenario: Successful open read-only instance group access

- **WHEN** user applies a Terraform configuration with `tencentcloud_cynosdb_cluster_read_only_instance_group_acces_operation` specifying a valid `cluster_id`
- **THEN** the resource SHALL call `OpenClusterReadOnlyInstanceGroupAccess` with the provided parameters, poll `DescribeFlow` until the flow completes successfully, store the `flow_id` in state, and set a generated token as the resource ID

#### Scenario: API returns nil response

- **WHEN** the `OpenClusterReadOnlyInstanceGroupAccess` API returns a nil response or nil FlowId
- **THEN** the resource SHALL return a `NonRetryableError` indicating the operation failed

#### Scenario: Async flow polling timeout

- **WHEN** the `DescribeFlow` polling exceeds the configured Create timeout
- **THEN** the resource SHALL return an error indicating the operation timed out

#### Scenario: Async flow reports failure

- **WHEN** `DescribeFlow` returns a failure status (status == 2)
- **THEN** the resource SHALL return an error indicating the flow execution failed

### Requirement: Resource registration in provider

The resource `tencentcloud_cynosdb_cluster_read_only_instance_group_acces_operation` SHALL be registered in `tencentcloud/provider.go` and documented in `tencentcloud/provider.md`.

#### Scenario: Resource is available in provider

- **WHEN** a user references `tencentcloud_cynosdb_cluster_read_only_instance_group_acces_operation` in their Terraform configuration
- **THEN** the provider SHALL recognize the resource type and route CRUD operations to the correct handler functions

### Requirement: Resource documentation

The resource SHALL have a documentation file at `tencentcloud/services/cynosdb/resource_tc_cynosdb_cluster_read_only_instance_group_acces_operation.md` with:
- A one-line description mentioning CynosDB
- An Example Usage section showing a basic configuration
- No Import section (operation resources are not importable)

#### Scenario: Documentation provides valid example

- **WHEN** a user reads the resource documentation
- **THEN** the example SHALL show a valid Terraform configuration using `cluster_id` as a required parameter
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
## 1. Resource Implementation

- [x] 1.1 Create resource file `tencentcloud/services/cynosdb/resource_tc_cynosdb_cluster_read_only_instance_group_acces_operation.go` with schema definition (cluster_id, port, security_group_ids, flow_id) and CRUD functions (Create calls OpenClusterReadOnlyInstanceGroupAccess + polls DescribeFlow; Read/Delete return nil)
- [x] 1.2 Register the resource `tencentcloud_cynosdb_cluster_read_only_instance_group_acces_operation` in `tencentcloud/provider.go`
- [x] 1.3 Add the resource entry to `tencentcloud/provider.md`

## 2. Documentation

- [x] 2.1 Create resource documentation file `tencentcloud/services/cynosdb/resource_tc_cynosdb_cluster_read_only_instance_group_acces_operation.md` with one-line description and Example Usage section

## 3. Unit Tests

- [x] 3.1 Create unit test file `tencentcloud/services/cynosdb/resource_tc_cynosdb_cluster_read_only_instance_group_acces_operation_test.go` using gomonkey to mock SDK client methods and verify Create logic with `go test -gcflags=all=-l`
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
## ADDED Requirements

### Requirement: Open read-only instance group access operation resource

The system SHALL provide a Terraform resource `tencentcloud_cynosdb_cluster_read_only_instance_group_acces_operation` that opens read-only instance group access for a CynosDB cluster by calling the `OpenClusterReadOnlyInstanceGroupAccess` API.

The resource SHALL accept the following input parameters:
- `cluster_id` (Required, ForceNew, String): The CynosDB cluster ID.
- `port` (Optional, ForceNew, String): The port for the read-only instance group access.
- `security_group_ids` (Optional, ForceNew, List of String): Security group IDs to associate.

The resource SHALL expose the following computed attributes:
- `flow_id` (Computed, Int): The flow ID returned by the async operation.

The resource SHALL be a one-shot operation (RESOURCE_KIND_OPERATION):
- Create: Calls `OpenClusterReadOnlyInstanceGroupAccess` API, then polls `DescribeFlow` until completion.
- Read: Returns nil (no state to read back).
- Delete: Returns nil (nothing to destroy).

#### Scenario: Successful open read-only instance group access

- **WHEN** user applies a Terraform configuration with `tencentcloud_cynosdb_cluster_read_only_instance_group_acces_operation` specifying a valid `cluster_id`
- **THEN** the resource SHALL call `OpenClusterReadOnlyInstanceGroupAccess` with the provided parameters, poll `DescribeFlow` until the flow completes successfully, store the `flow_id` in state, and set a generated token as the resource ID

#### Scenario: API returns nil response

- **WHEN** the `OpenClusterReadOnlyInstanceGroupAccess` API returns a nil response or nil FlowId
- **THEN** the resource SHALL return a `NonRetryableError` indicating the operation failed

#### Scenario: Async flow polling timeout

- **WHEN** the `DescribeFlow` polling exceeds the configured Create timeout
- **THEN** the resource SHALL return an error indicating the operation timed out

#### Scenario: Async flow reports failure

- **WHEN** `DescribeFlow` returns a failure status (status == 2)
- **THEN** the resource SHALL return an error indicating the flow execution failed

### Requirement: Resource registration in provider

The resource `tencentcloud_cynosdb_cluster_read_only_instance_group_acces_operation` SHALL be registered in `tencentcloud/provider.go` and documented in `tencentcloud/provider.md`.

#### Scenario: Resource is available in provider

- **WHEN** a user references `tencentcloud_cynosdb_cluster_read_only_instance_group_acces_operation` in their Terraform configuration
- **THEN** the provider SHALL recognize the resource type and route CRUD operations to the correct handler functions

### Requirement: Resource documentation

The resource SHALL have a documentation file at `tencentcloud/services/cynosdb/resource_tc_cynosdb_cluster_read_only_instance_group_acces_operation.md` with:
- A one-line description mentioning CynosDB
- An Example Usage section showing a basic configuration
- No Import section (operation resources are not importable)

#### Scenario: Documentation provides valid example

- **WHEN** a user reads the resource documentation
- **THEN** the example SHALL show a valid Terraform configuration using `cluster_id` as a required parameter
1 change: 1 addition & 0 deletions tencentcloud/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -1953,6 +1953,7 @@ func Provider() *schema.Provider {
"tencentcloud_cynosdb_audit_service": cynosdb.ResourceTencentCloudCynosdbAuditService(),
"tencentcloud_cynosdb_cls_delivery": cynosdb.ResourceTencentCloudCynosdbClsDelivery(),
"tencentcloud_cynosdb_libra_db_instance": cynosdb.ResourceTencentCloudCynosdbLibraDbInstance(),
"tencentcloud_cynosdb_cluster_read_only_instance_group_acces_operation": cynosdb.ResourceTencentCloudCynosdbClusterReadOnlyInstanceGroupAccesOperation(),
"tencentcloud_vod_adaptive_dynamic_streaming_template": vod.ResourceTencentCloudVodAdaptiveDynamicStreamingTemplate(),
"tencentcloud_vod_aigc_api_token": vod.ResourceTencentCloudVodAigcApiToken(),
"tencentcloud_vod_image_sprite_template": vod.ResourceTencentCloudVodImageSpriteTemplate(),
Expand Down
1 change: 1 addition & 0 deletions tencentcloud/provider.md
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,7 @@ tencentcloud_cynosdb_cluster_transparent_encrypt
tencentcloud_cynosdb_audit_service
tencentcloud_cynosdb_cls_delivery
tencentcloud_cynosdb_libra_db_instance
tencentcloud_cynosdb_cluster_read_only_instance_group_acces_operation

Direct Connect(DC)
Data Source
Expand Down
Loading
Loading