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/4187.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:new-resource
tencentcloud_teo_edge_k_v_namespace
```
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ require (
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tdcpg v1.0.533
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tdmq v1.3.46
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tem v1.0.578
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.3.90
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.3.108
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tke v1.3.86
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/trocket v1.1.0
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tse v1.0.857
Expand Down
6 changes: 2 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -837,8 +837,6 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/apm v1.3.8 h1:v/G/D3bqU
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/apm v1.3.8/go.mod h1:DarTPk6LPu4LtKwDRbF2V2Af4KKXVXnzyteNhAifWm8=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/as v1.3.16 h1:0YPLYvTF/Jb2kzLQPTE9+SUHoOTinqxzLJpQNOg4Gcc=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/as v1.3.16/go.mod h1:1JNwb292Pt2CuxQOsgwdXFs2a79nLdwiFRXT0xKACkg=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/bh v1.3.68 h1:yyH8702x16BIh46K6vEeHoQiIHuKsYCye2Lj4lmtX98=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/bh v1.3.68/go.mod h1:ernIVPt8moCpVWvuoFsJ2OU29Gm6q0XCsY9gemtcR/0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/bh v1.3.93 h1:6tYneudwMIvczAIH+6UT4A6DUKF9VPm6er+TIVGMyKg=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/bh v1.3.93/go.mod h1:4VE2PmQ0iUVzFkamod4wE2eKjW95NkfqP/sWymsReR4=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/bi v1.0.824 h1:DVKvZ6h+qd7tadUrCjVAkCCmE3TsbK2ZmwGd3AJcpWc=
Expand Down Expand Up @@ -1075,8 +1073,8 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tdmq v1.3.46 h1:hnBTV4y
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tdmq v1.3.46/go.mod h1:brB63yRDKDgCzEBFU5G3OBV+wQ+lpnOnedxwdnLgjjk=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tem v1.0.578 h1:vBpQhUroO+FAslUmsDWGi8nvczsqZBWVgQwlnyT0Aj8=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tem v1.0.578/go.mod h1:UlojGQh/9wb7/uXPNi7PvMral1CNAskVDNgqJEV83l0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.3.90 h1:UAefUxiVLj639m5jplPyTyOkF5vT8W0d8TrWZ7cepj4=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.3.90/go.mod h1:YV/JlZueAHyf9eyLmowdbeX90MR5jJmy0Dn6gZwPT2M=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.3.108 h1:cAw2o4gMuAUZnjdo+WDZmUTHgH6FdysXeUDI1YcBjgI=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.3.108/go.mod h1:/+JtDwgVSkaDGMU42zTWtidw/p56hl2N46zkWJLAr9U=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/thpc v1.0.998 h1:f4/n0dVKQTD06xJ84B5asHViNJHrZmGojdAWEPIsITM=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/thpc v1.0.998/go.mod h1:fyi/HUwCwVe2NCCCjz8k/C5GwPu3QazCZO+OBJ3MhLk=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tke v1.3.86 h1:vTpLGPpzAbZHOv0F6hmy8C9IBwJIUfhTrXH0vi7eiGA=
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-06-03
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
## Context

TencentCloud TEO (EdgeOne) 提供 Edge KV 命名空间管理的云 API,包括 CreateEdgeKVNamespace、DescribeEdgeKVNamespaces、ModifyEdgeKVNamespace、DeleteEdgeKVNamespace 四个接口。这些接口已在 vendor 中可用(`github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo/v20220901`)。当前 provider 已有 TEO 服务目录(`tencentcloud/services/teo/`),需要在其中新增资源文件。

## Goals / Non-Goals

**Goals:**
- 实现 `tencentcloud_teo_edge_k_v_namespace` 资源的完整 CRUD 生命周期
- 使用 `zone_id#namespace` 联合 ID,支持 terraform import
- 遵循项目现有代码风格(参考 `tencentcloud_igtm_strategy` 资源)
- 提供单元测试(使用 gomonkey mock 云 API)
- 提供资源文档(.md 文件)

**Non-Goals:**
- 不实现 Edge KV 键值对的 CRUD(仅管理命名空间)
- 不实现 datasource 类型资源
- 不新增 service 层文件(直接在资源文件中调用 API)

## Decisions

### 1. 资源 ID 设计:使用 zone_id + namespace 联合 ID

**选择**: 使用 `tccommon.FILED_SP`(即 `#`)作为分隔符拼接 `zone_id` 和 `namespace` 作为资源 ID。

**理由**: CreateEdgeKVNamespace 接口不返回独立的资源 ID,命名空间通过 zone_id + namespace 唯一标识。这与项目中其他类似资源的做法一致。

**替代方案**: 仅使用 namespace 作为 ID → 不可行,因为 namespace 在不同 zone 下可能重复。

### 2. ForceNew 字段设计

**选择**: `zone_id` 和 `namespace` 设为 ForceNew。

**理由**: ModifyEdgeKVNamespace 接口仅支持修改 `remark` 字段,`zone_id` 和 `namespace` 是定位资源的标识符,不可变更。

### 3. Update 方法设计

**选择**: Update 方法仅处理 `remark` 字段的变更,通过 ModifyEdgeKVNamespace 接口实现。

**理由**: 云 API ModifyEdgeKVNamespace 仅支持修改 remark。zone_id 和 namespace 已设为 ForceNew,变更时会触发 destroy + create。

### 4. Read 方法设计:使用 Filters 过滤

**选择**: 在 DescribeEdgeKVNamespaces 请求中使用 `namespace` 过滤条件精确查询目标命名空间,Limit 设为 1000(接口最大值)。

**理由**: DescribeEdgeKVNamespaces 是列表查询接口,通过 Filters 按 namespace 名称过滤可精确定位目标资源。设置最大 Limit 确保不会因分页遗漏。

### 5. 测试方案:gomonkey mock

**选择**: 使用 gomonkey 对云 API 调用进行 mock,编写纯业务逻辑单元测试。

**理由**: 项目要求新增资源使用 mock 方式进行单元测试,不依赖真实云环境。

## Risks / Trade-offs

- [DescribeEdgeKVNamespaces 使用模糊匹配] → 在 Read 方法中遍历返回结果,精确匹配 namespace 名称,避免模糊查询返回多个结果时取错数据。
- [CreateEdgeKVNamespace 不返回资源 ID] → 创建成功后直接使用入参 zone_id + namespace 组合为 ID,无需从响应中提取。
- [并发创建同名 namespace] → 依赖云 API 侧的唯一性校验,Terraform 层面不做额外处理。
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
## Why

TencentCloud TEO (EdgeOne) 提供了 Edge KV 命名空间功能,允许用户在边缘节点创建和管理 KV 存储命名空间。当前 Terraform Provider 缺少对该资源的支持,用户无法通过 IaC 方式管理 TEO Edge KV 命名空间的生命周期(创建、查询、修改、删除)。新增此资源以补全 TEO 产品的 Terraform 覆盖度。

## What Changes

- 新增 Terraform 资源 `tencentcloud_teo_edge_k_v_namespace`,支持完整的 CRUD 生命周期管理
- 资源使用 `zone_id` + `namespace` 作为联合 ID,支持 import
- 支持创建时指定 `zone_id`、`namespace`、`remark` 参数
- 支持通过 `ModifyEdgeKVNamespace` 接口更新 `remark` 字段
- 支持通过 `DeleteEdgeKVNamespace` 接口删除命名空间
- Read 方法通过 `DescribeEdgeKVNamespaces` 接口查询命名空间详情
- 在 `provider.go` 和 `provider.md` 中注册新资源

## Capabilities

### New Capabilities

- `teo-edge-kv-namespace-resource`: 提供 TEO Edge KV 命名空间的 CRUD 资源管理能力,包括创建、读取、更新(remark)、删除命名空间,以及 import 支持

### Modified Capabilities

(无)

## Impact

- 新增文件: `tencentcloud/services/teo/resource_tc_teo_edge_k_v_namespace.go`
- 新增文件: `tencentcloud/services/teo/resource_tc_teo_edge_k_v_namespace_test.go`
- 新增文件: `tencentcloud/services/teo/resource_tc_teo_edge_k_v_namespace.md`
- 修改文件: `tencentcloud/provider.go`(注册资源)
- 修改文件: `tencentcloud/provider.md`(添加资源文档引用)
- 依赖: `github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo/v20220901`(已在 vendor 中)
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
## ADDED Requirements

### Requirement: Resource schema definition

The resource `tencentcloud_teo_edge_k_v_namespace` SHALL define the following schema fields:
- `zone_id` (Required, ForceNew, String): 站点 ID
- `namespace` (Required, ForceNew, String): 命名空间名称,1-50 个字符,允许 a-z、A-Z、0-9、-
- `remark` (Optional, String): 命名空间描述,最大 256 个字符

The resource SHALL use `zone_id#namespace` as the composite resource ID (using `tccommon.FILED_SP` as separator).

#### Scenario: Schema fields are correctly defined
- **WHEN** user defines a `tencentcloud_teo_edge_k_v_namespace` resource block with `zone_id`, `namespace`, and `remark`
- **THEN** Terraform SHALL accept the configuration and plan the resource creation

#### Scenario: Import with composite ID
- **WHEN** user runs `terraform import tencentcloud_teo_edge_k_v_namespace.example zone-xxx#my-namespace`
- **THEN** the resource SHALL be imported successfully by parsing `zone_id` and `namespace` from the composite ID

### Requirement: Create operation

The resource Create function SHALL call `CreateEdgeKVNamespace` API with `ZoneId`, `Namespace`, and `Remark` parameters. After successful creation, the resource ID SHALL be set to `zone_id#namespace`. The Create function SHALL verify that the API call succeeds before setting the ID.

#### Scenario: Successful creation
- **WHEN** user applies a configuration with valid `zone_id`, `namespace`, and `remark`
- **THEN** the system SHALL call `CreateEdgeKVNamespace` API and set the resource ID to `zone_id#namespace`

#### Scenario: Creation with retry on failure
- **WHEN** the `CreateEdgeKVNamespace` API call fails with a retryable error
- **THEN** the system SHALL retry the request using `tccommon.ReadRetryTimeout` and `resource.RetryContext`

### Requirement: Read operation

The resource Read function SHALL call `DescribeEdgeKVNamespaces` API with `ZoneId` and a `namespace` filter to retrieve the namespace details. It SHALL set `zone_id`, `namespace`, and `remark` from the response. If the namespace is not found, it SHALL remove the resource from state.

#### Scenario: Successful read
- **WHEN** the resource exists in the cloud
- **THEN** the system SHALL call `DescribeEdgeKVNamespaces` with namespace filter, find the matching namespace, and set `zone_id`, `namespace`, `remark` in state

#### Scenario: Resource not found
- **WHEN** the `DescribeEdgeKVNamespaces` API returns empty results for the namespace
- **THEN** the system SHALL remove the resource from Terraform state (call `d.SetId("")`)

### Requirement: Update operation

The resource Update function SHALL call `ModifyEdgeKVNamespace` API when `remark` changes. Since `zone_id` and `namespace` are ForceNew, they cannot be updated in-place.

#### Scenario: Update remark
- **WHEN** user changes the `remark` field value
- **THEN** the system SHALL call `ModifyEdgeKVNamespace` API with the new `remark` value

#### Scenario: Update with retry on failure
- **WHEN** the `ModifyEdgeKVNamespace` API call fails with a retryable error
- **THEN** the system SHALL retry the request using `tccommon.ReadRetryTimeout` and `resource.RetryContext`

### Requirement: Delete operation

The resource Delete function SHALL call `DeleteEdgeKVNamespace` API with `ZoneId` and `Namespace` parameters to remove the namespace.

#### Scenario: Successful deletion
- **WHEN** user destroys the resource
- **THEN** the system SHALL call `DeleteEdgeKVNamespace` API with the correct `ZoneId` and `Namespace`

#### Scenario: Delete with retry on failure
- **WHEN** the `DeleteEdgeKVNamespace` API call fails with a retryable error
- **THEN** the system SHALL retry the request using `tccommon.ReadRetryTimeout` and `resource.RetryContext`

### Requirement: Provider registration

The resource SHALL be registered in `tencentcloud/provider.go` under the TEO service section, and referenced in `tencentcloud/provider.md`.

#### Scenario: Resource is available in provider
- **WHEN** user configures the tencentcloud provider
- **THEN** the resource `tencentcloud_teo_edge_k_v_namespace` SHALL be available for use

### Requirement: Unit tests with gomonkey mock

The resource SHALL have unit tests in `resource_tc_teo_edge_k_v_namespace_test.go` that use gomonkey to mock cloud API calls. Tests SHALL cover Create, Read, Update, and Delete operations and SHALL pass with `go test -gcflags=all=-l`.

#### Scenario: Unit tests pass
- **WHEN** running `go test -gcflags=all=-l` on the test file
- **THEN** all unit tests SHALL pass without requiring real cloud credentials

### Requirement: Resource documentation

The resource SHALL have a documentation file at `tencentcloud/services/teo/resource_tc_teo_edge_k_v_namespace.md` with:
- A one-line description mentioning TEO product
- Example Usage section
- Import section showing the composite ID format `zone_id#namespace`

#### Scenario: Documentation is complete
- **WHEN** the documentation file is generated
- **THEN** it SHALL contain description, Example Usage, and Import sections
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
## 1. Resource Implementation

- [x] 1.1 Create resource file `tencentcloud/services/teo/resource_tc_teo_edge_k_v_namespace.go` with schema definition (zone_id, namespace, remark) and CRUD functions (Create, Read, Update, Delete) following the igtm_strategy resource pattern
- [x] 1.2 Implement Create function: call CreateEdgeKVNamespace API with retry, set composite ID (zone_id#namespace)
- [x] 1.3 Implement Read function: call DescribeEdgeKVNamespaces API with namespace filter, set state fields, handle resource not found
- [x] 1.4 Implement Update function: call ModifyEdgeKVNamespace API with retry when remark changes
- [x] 1.5 Implement Delete function: call DeleteEdgeKVNamespace API with retry

## 2. Provider Registration

- [x] 2.1 Register `tencentcloud_teo_edge_k_v_namespace` resource in `tencentcloud/provider.go` under TEO service section
- [x] 2.2 Add resource reference in `tencentcloud/provider.md`

## 3. Documentation

- [x] 3.1 Create resource documentation file `tencentcloud/services/teo/resource_tc_teo_edge_k_v_namespace.md` with description, Example Usage, and Import sections

## 4. Unit Tests

- [x] 4.1 Create unit test file `tencentcloud/services/teo/resource_tc_teo_edge_k_v_namespace_test.go` with gomonkey mock tests covering Create, Read, Update, and Delete operations
- [x] 4.2 Run unit tests with `go test -gcflags=all=-l` to verify they pass
93 changes: 93 additions & 0 deletions openspec/specs/teo-edge-kv-namespace-resource/spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
## ADDED Requirements

### Requirement: Resource schema definition

The resource `tencentcloud_teo_edge_k_v_namespace` SHALL define the following schema fields:
- `zone_id` (Required, ForceNew, String): 站点 ID
- `namespace` (Required, ForceNew, String): 命名空间名称,1-50 个字符,允许 a-z、A-Z、0-9、-
- `remark` (Optional, String): 命名空间描述,最大 256 个字符

The resource SHALL use `zone_id#namespace` as the composite resource ID (using `tccommon.FILED_SP` as separator).

#### Scenario: Schema fields are correctly defined
- **WHEN** user defines a `tencentcloud_teo_edge_k_v_namespace` resource block with `zone_id`, `namespace`, and `remark`
- **THEN** Terraform SHALL accept the configuration and plan the resource creation

#### Scenario: Import with composite ID
- **WHEN** user runs `terraform import tencentcloud_teo_edge_k_v_namespace.example zone-xxx#my-namespace`
- **THEN** the resource SHALL be imported successfully by parsing `zone_id` and `namespace` from the composite ID

### Requirement: Create operation

The resource Create function SHALL call `CreateEdgeKVNamespace` API with `ZoneId`, `Namespace`, and `Remark` parameters. After successful creation, the resource ID SHALL be set to `zone_id#namespace`. The Create function SHALL verify that the API call succeeds before setting the ID.

#### Scenario: Successful creation
- **WHEN** user applies a configuration with valid `zone_id`, `namespace`, and `remark`
- **THEN** the system SHALL call `CreateEdgeKVNamespace` API and set the resource ID to `zone_id#namespace`

#### Scenario: Creation with retry on failure
- **WHEN** the `CreateEdgeKVNamespace` API call fails with a retryable error
- **THEN** the system SHALL retry the request using `tccommon.ReadRetryTimeout` and `resource.RetryContext`

### Requirement: Read operation

The resource Read function SHALL call `DescribeEdgeKVNamespaces` API with `ZoneId` and a `namespace` filter to retrieve the namespace details. It SHALL set `zone_id`, `namespace`, and `remark` from the response. If the namespace is not found, it SHALL remove the resource from state.

#### Scenario: Successful read
- **WHEN** the resource exists in the cloud
- **THEN** the system SHALL call `DescribeEdgeKVNamespaces` with namespace filter, find the matching namespace, and set `zone_id`, `namespace`, `remark` in state

#### Scenario: Resource not found
- **WHEN** the `DescribeEdgeKVNamespaces` API returns empty results for the namespace
- **THEN** the system SHALL remove the resource from Terraform state (call `d.SetId("")`)

### Requirement: Update operation

The resource Update function SHALL call `ModifyEdgeKVNamespace` API when `remark` changes. Since `zone_id` and `namespace` are ForceNew, they cannot be updated in-place.

#### Scenario: Update remark
- **WHEN** user changes the `remark` field value
- **THEN** the system SHALL call `ModifyEdgeKVNamespace` API with the new `remark` value

#### Scenario: Update with retry on failure
- **WHEN** the `ModifyEdgeKVNamespace` API call fails with a retryable error
- **THEN** the system SHALL retry the request using `tccommon.ReadRetryTimeout` and `resource.RetryContext`

### Requirement: Delete operation

The resource Delete function SHALL call `DeleteEdgeKVNamespace` API with `ZoneId` and `Namespace` parameters to remove the namespace.

#### Scenario: Successful deletion
- **WHEN** user destroys the resource
- **THEN** the system SHALL call `DeleteEdgeKVNamespace` API with the correct `ZoneId` and `Namespace`

#### Scenario: Delete with retry on failure
- **WHEN** the `DeleteEdgeKVNamespace` API call fails with a retryable error
- **THEN** the system SHALL retry the request using `tccommon.ReadRetryTimeout` and `resource.RetryContext`

### Requirement: Provider registration

The resource SHALL be registered in `tencentcloud/provider.go` under the TEO service section, and referenced in `tencentcloud/provider.md`.

#### Scenario: Resource is available in provider
- **WHEN** user configures the tencentcloud provider
- **THEN** the resource `tencentcloud_teo_edge_k_v_namespace` SHALL be available for use

### Requirement: Unit tests with gomonkey mock

The resource SHALL have unit tests in `resource_tc_teo_edge_k_v_namespace_test.go` that use gomonkey to mock cloud API calls. Tests SHALL cover Create, Read, Update, and Delete operations and SHALL pass with `go test -gcflags=all=-l`.

#### Scenario: Unit tests pass
- **WHEN** running `go test -gcflags=all=-l` on the test file
- **THEN** all unit tests SHALL pass without requiring real cloud credentials

### Requirement: Resource documentation

The resource SHALL have a documentation file at `tencentcloud/services/teo/resource_tc_teo_edge_k_v_namespace.md` with:
- A one-line description mentioning TEO product
- Example Usage section
- Import section showing the composite ID format `zone_id#namespace`

#### Scenario: Documentation is complete
- **WHEN** the documentation file is generated
- **THEN** it SHALL contain description, Example Usage, and Import sections
Loading
Loading