Skip to content

Commit 173b68f

Browse files
committed
feat(dlc): add tencentcloud_dlc_dms_table resource
1 parent 7f7ccb9 commit 173b68f

22 files changed

Lines changed: 5148 additions & 279 deletions

File tree

.changelog/4297.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:new-resource
2+
tencentcloud_dlc_dms_table
3+
```

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ require (
4646
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.3.105
4747
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cloudaudit v1.0.1033
4848
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cls v1.3.129
49-
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.130
49+
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.132
5050
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/config v1.3.80
5151
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm v1.3.127
5252
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cwp v1.3.30
@@ -55,7 +55,7 @@ require (
5555
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dbbrain v1.3.26
5656
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dc v1.0.633
5757
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dcdb v1.0.673
58-
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dlc v1.1.35
58+
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dlc v1.3.132
5959
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.3.124
6060
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/domain v1.0.414
6161
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dts v1.1.46

go.sum

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -958,7 +958,6 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.1.7/go.mod h1
958958
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.1.11/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
959959
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.1.13/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
960960
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.1.30/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
961-
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.1.35/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
962961
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.1.42/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
963962
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.1.46/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
964963
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.1.50/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
@@ -1006,8 +1005,9 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.124/go.mod
10061005
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.125/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
10071006
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.127/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
10081007
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.129/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
1009-
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.130 h1:sQJUwGwOw3HL9L334UgI+CysqczIjicSItyqg7seeqk=
10101008
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.130/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
1009+
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.132 h1:42RfJnwzMprfKEJrM9fyhHu1jXyg8xvSJ1A1qb9Qun8=
1010+
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.132/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
10111011
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/config v1.3.80 h1:chnsNBeJn3MieFLki4hpbzoml5NiTvLVzOTqYRVxQho=
10121012
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/config v1.3.80/go.mod h1:B/ezGtlvDhZlleNM+2QdvZccrUi+J+fN6vMnDDsZnuM=
10131013
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/controlcenter v1.1.51 h1:pGwrfCBBCt1u+EDHwfNj9NLQpvk5MVKVMcsE7SvwqM4=
@@ -1032,8 +1032,8 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dc v1.0.633 h1:Ul5iNhXo
10321032
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dc v1.0.633/go.mod h1:tc6Hvf03M1cBtMC1IKSa5mlOn3kpxWOwhWU1fRy+KEE=
10331033
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dcdb v1.0.673 h1:YyjGLjvPDKNlpbGt89WLFif7TjId0fHzcrGOaHSQRNQ=
10341034
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dcdb v1.0.673/go.mod h1:hXPMop1kJFqAvHj+7TyxxxXS/HGUP4SuKx5gGoAl0Zc=
1035-
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dlc v1.1.35 h1:YBartSeOD6M1hFzVytGXcILAlXfzzrCxdjcAAbcHi5U=
1036-
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dlc v1.1.35/go.mod h1:Hb8V1r7scNF9Zjk0fiEavzW2dx+Lr2FEYrXDPa9f0TE=
1035+
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dlc v1.3.132 h1:LHD2gW7BiKEDWuvKgYniUcPzb3D+Jv6pJFii0JNz+PQ=
1036+
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dlc v1.3.132/go.mod h1:TX8Cko5rAacJQ0J5Hvg9qCPm7GHTqMtkgV595AuUmoc=
10371037
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.3.124 h1:atQm8S0BLrr3E+Yn2383KQUEEXpQ6z31MsprAKzMDDE=
10381038
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.3.124/go.mod h1:zxlW9EAn0Hqx6Eub6MMocnHZz/gHundkyI7CdbIhU3o=
10391039
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/domain v1.0.414 h1:egwjvOEUKBaxsoRVn/YSEhp2E8qdh77Ous9A/wftDo0=
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
schema: spec-driven
2+
created: 2026-07-13
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
## Context
2+
3+
Terraform Provider for TencentCloud 已具备 DLC(Data Lake Compute)服务的数据源与部分资源(如 `tencentcloud_dlc_data_engine``tencentcloud_dlc_user` 等),但尚未覆盖 DMS 元数据表的管理。DLC DMS 提供了 `CreateDMSTable``DescribeDMSTable``AlterDMSTable``DropDMSTable` 四个云 API,均已 vendored 在 `vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dlc/v20210125` 中,支持对元数据表做完整 CRUD。
4+
5+
该表资源依赖多个复杂嵌套结构:`Asset`(基础对象,含 PermValues/Params/BizParams 等 KVPair 列表)、`DMSSds`(存储描述,含 SerdeParams/Params/Cols/SortColumns 等嵌套)、`DMSColumn`(列定义,含 Params/BizParams)、`DMSPartition`(分区,含 Params 与嵌套 Sds)、`KVPair`(键值对)。
6+
7+
云 API 的特殊性:
8+
- `CreateDMSTable`/`AlterDMSTable`/`DropDMSTable` 的 Response 仅返回 RequestId,无业务 ID,资源需以业务键(db_name + name)作为复合 ID。
9+
- `CreateDMSTable` 不接受 `schema_name`/`catalog`/`keyword`/`pattern`,这些只在 `DescribeDMSTable` 入参中存在;`DescribeDMSTable` 出参会返回 `schema_name``retention` 等创建时不可设置的只读字段。
10+
- `AlterDMSTable` 额外需要 `CurrentName`/`CurrentDbName`(旧名称),用于改名场景;其余字段与 Create 对齐。
11+
- `DropDMSTable` 需要 `delete_data``env_props``datasource_connection_name`,其中 `env_props``KVPair` 结构。
12+
13+
当前约束:本资源为 RESOURCE_KIND_GENERAL 通用资源,必须支持 import;复合 ID 用 `tccommon.FILED_SP` 分隔;调用云 API 需以 `tccommon.ReadRetryTimeout`/`tccommon.WriteRetryTimeout` 做最终一致性重试。
14+
15+
## Goals / Non-Goals
16+
17+
**Goals:**
18+
- 提供 `tencentcloud_dlc_dms_table` 资源,支持对 DLC DMS 元数据表的创建、读取、更新、删除全生命周期管理。
19+
- 支持通过 `terraform import` 导入已存在的表(使用 `db_name` + `name` 复合 ID)。
20+
- 正确映射云 API 的复杂嵌套结构(Asset、DMSSds、DMSColumn、DMSPartition、KVPair)到 Terraform schema。
21+
- 在更新场景下正确处理 `AlterDMSTable``CurrentName`/`CurrentDbName`(取变更前的旧值)。
22+
- 满足 provider 代码规范:Create 返回值空检查、Read 字段 nil 检查、retry 块仅放接口调用、使用资源蛇形命名做日志。
23+
- 通过 gomonkey mock 云 API 的单元测试覆盖核心 CRUD 业务逻辑。
24+
25+
**Non-Goals:**
26+
- 不实现 DMS 表的权限管理(PermValues 仅作为 Asset 属性透传,不做细粒度权限资源化)。
27+
- 不暴露 `DescribeDMSTable` 专用的查询参数(`keyword``pattern``catalog``schema_name`)作为用户可配置的创建参数;其中 `schema_name` 作为只读 computed 字段从出参回填,`catalog`/`keyword`/`pattern` 不纳入 schema。
28+
- 不实现数据源(datasource)形式的 `tencentcloud_dlc_dms_table`,本变更仅交付 resource。
29+
- 不修改任何已有 DLC 资源的 schema。
30+
31+
## Decisions
32+
33+
### 决策 1:复合 ID 设计 = `db_name` + `name`
34+
- **选择**:使用 `db_name``name` 通过 `tccommon.FILED_SP` 拼接作为资源 ID。
35+
- **理由**`CreateDMSTable` 无返回 ID;DMS 表在云端的唯一键即“数据库名 + 表名”。`DescribeDMSTable` 入参也正是 `DbName` + `Name`。二者组合可在 Read/Update/Delete 中拆分还原。
36+
- **备选**:仅用 `name` 作 ID——不可行,因为同名表可存在于不同数据库,无法唯一定位。
37+
- **影响**:Import 需用户提供 `db_name``name` 的复合 ID;文档需说明。
38+
39+
### 决策 2:Schema 字段分层与 ForceNew 策略
40+
- **选择**
41+
- `db_name``name``datasource_connection_name`:Required,且 `db_name`/`name` 标记 `ForceNew`(改库名/表名走 AlterDMSTable 的改名逻辑而非重建)。但由于 AlterDMSTable 支持改名(通过 CurrentName/CurrentDbName + 新 Name/DbName),故 `db_name`/`name` **** ForceNew,而在 Update 时通过 d.HasChange 判断并把旧值映射到 `CurrentName`/`CurrentDbName`
42+
- `delete_data``env_props`:仅 DropDMSTable 使用,作为 Optional 字段(`delete_data` 默认可设为 true 或由用户指定)。
43+
- `type``storage_size``record_count``life_time``data_update_time``struct_update_time``last_access_time``view_original_text``view_expanded_text`:Optional,可更新。
44+
- `asset``sds``columns``partition_keys``partitions`:Optional 复杂嵌套结构,可更新。
45+
- `schema_name``retention`:Computed only(从 DescribeDMSTable 出参回填,不可由用户设置)。
46+
- **理由**:严格对照云 API Create/Alter 入参字段,确保 Create 入参字段均在 CreateDMSTable 存在、Update 入参字段均在 AlterDMSTable 存在。`schema_name`/`retention` 仅在出参出现,设为 Computed。
47+
48+
### 决策 3:Update 改名通过 CurrentName/CurrentDbName
49+
- **选择**:在 `resourceTencentCloudDlcDmsTableUpdate` 中,先构造 `AlterDMSTableRequest`,对 `db_name`/`name` 使用 `d.GetOk` 取新值填入 `DbName`/`Name`,并使用 `d.GetChange("db_name")`/`d.GetChange("name")` 取旧值填入 `CurrentDbName`/`CurrentName`;其余可变字段从 schema 读取填入。无 immutableArgs 限制(因为 AlterDMSTable 支持所有 Create 字段)。
50+
- **理由**:AlterDMSTable 设计即用于改名与字段更新,符合云 API 语义。
51+
- **备选**:把改名视为 ForceNew 重建——会产生删表再建表的副作用,破坏数据,不可接受。
52+
53+
### 决策 4:嵌套结构 schema 扁平化与 KVPair 复用
54+
- **选择**:对 `KVPair` 定义为可复用的 list-of-map(`key`/`value` 两个字符串字段),在 Asset.PermValues/Params/BizParams、DMSSds.SerdeParams/Params、DMSColumn.Params/BizParams、DMSPartition.Params、DropDMSTable.EnvProps 等位置统一使用该结构。`DMSColumnOrder`(SortCols/SortColumns)定义为含 `col`/`order` 的对象。
55+
- **理由**:保持与 SDK 结构一致,便于双向映射;KVPair 是云 API 通用键值结构。
56+
57+
### 决策 5:Retry 与空值检查遵循 provider 规范
58+
- **选择**
59+
- Create/Update/Delete 使用 `resource.Retry(tccommon.WriteRetryTimeout, ...)`,retry 块内仅调用接口,错误用 `tccommon.RetryError(e)` 包装;Create 成功后在 retry 外做 `response == nil || response.Response == nil` 空检查(返回 NonRetryableError),但因 Create Response 无业务字段,仅做 Response 非空校验。
60+
- Read 使用 `service.DescribeDmsTableById`(内部 `resource.Retry(tccommon.ReadRetryTimeout, ...)`)。在 retry 块内检查 `response == nil || response.Response == nil`,返回 NonRetryableError(不直接 SetId("")),让外层重试耗尽后失败;外层失败路径打印 `log.Printf("[DATASOURCE] read empty, skip SetId")`。注意:本资源为 RESOURCE_KIND_GENERAL 非 DATASOURCE,但 Read 为空时仍遵循“先打印含 id 的日志再 SetId("")”规范。
61+
- Read 中 set 字段前逐一判断 Response 字段 nil。
62+
- **理由**:符合项目硬约束与代码生成要求第 8/9/14 条。
63+
64+
### 决策 6:单元测试使用 gomonkey mock
65+
- **选择**:新增资源为全新资源,按规范使用 gomonkey mock 云 API(`UseDlcV20210125Client` 及其 `CreateDMSTableWithContext`/`DescribeDMSTableWithContext`/`AlterDMSTableWithContext`/`DropDMSTableWithContext`),仅测业务逻辑,用 `go test -gcflags=all=-l` 跑通。
66+
- **理由**:规范要求新增 terraform 资源测试用 mock,不使用 TF 测试套件。
67+
68+
## Risks / Trade-offs
69+
70+
- [风险] `AlterDMSTable` 改名时若 `CurrentName`/`CurrentDbName` 传错会导致更新失败或操作到错误的表 → 缓解:Update 中严格使用 `d.GetChange` 获取旧值,并在日志中打印 current/new 便于排障。
71+
- [风险] `Asset` 结构层级深、字段多,schema 映射易遗漏或与 SDK 类型不一致 → 缓解:严格按 vendor models.go 逐字段核对类型(int64/string/[]*KVPair/[]*DMSColumn 等),Read 时对每个字段做 nil 判断。
72+
- [风险] `DropDMSTable``delete_data`(bool)与 `env_props`(KVPair)若未在 schema 暴露,删除时无法控制是否清除底层数据 → 缓解:在 schema 中暴露 `delete_data`(Optional,默认 false 与云 API 一致)与 `env_props`(Optional KVPair 列表)。
73+
- [风险] `DescribeDMSTable` 返回 `schema_name`/`retention` 等只读字段,若误设为可写会导致 update 时云 API 拒绝 → 缓解:这两个字段设为 Computed,不参与 AlterDMSTable 入参构造。
74+
- [权衡] 复杂嵌套结构导致 schema 较大、转换代码冗长 → 接受,以保证功能完整;不抽取通用 helper 以避免影响既有代码。
75+
- [风险] Create Response 无 ID,无法通过返回值判断创建具体实例 → 缓解:Create 成功后用用户输入的 `db_name`+`name` 复合 ID 设置 d.Id(),并立即调用 Read 回查确认表已存在;若 Read 查不到则返回错误。
76+
77+
## Migration Plan
78+
79+
- 纯新增资源,无数据迁移。部署只需合并代码并在 provider 注册新资源。
80+
- 回滚策略:移除 provider.go 中的注册项与资源文件即可,不影响存量 state(该资源类型此前不存在)。
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
## Why
2+
3+
Terraform TencentCloud provider 目前缺少对 DLC(Data Lake Compute)DMS 元数据表的管理能力。用户无法通过 Terraform 声明式地创建、查询、更新和删除 DMS 元数据表(`tencentcloud_dlc_dms_table`),导致涉及 DLC 湖仓元数据的基础设施编排必须依赖手工控制台操作或脚本,无法纳入 IaC 统一管理。新增该资源可以让用户以 Terraform 管理表结构、分区、列、存储描述等完整生命周期,提升湖仓元数据治理的自动化与一致性。
4+
5+
## What Changes
6+
7+
- 新增 Terraform 资源 `tencentcloud_dlc_dms_table`(RESOURCE_KIND_GENERAL),覆盖 DMS 元数据表的完整 CRUD 生命周期:
8+
- 创建:调用 DLC `CreateDMSTable` 接口。
9+
- 查询:调用 DLC `DescribeDMSTable` 接口。
10+
- 更新:调用 DLC `AlterDMSTable` 接口。
11+
- 删除:调用 DLC `DropDMSTable` 接口。
12+
- 资源采用复合 ID(数据库名 + 表名),通过 `tccommon``FILED_SP` 分隔符组合,以支持导入与唯一标识。
13+
-`tencentcloud/provider.go``tencentcloud/provider.md` 中注册新资源。
14+
- 新增资源文档 `tencentcloud/services/dlc/resource_tc_tencentcloud_dlc_dms_table.md`
15+
- 新增单元测试 `tencentcloud/services/dlc/resource_tc_tencentcloud_dlc_dms_table_test.go`,使用 gomonkey mock 云 API 进行业务逻辑测试。
16+
17+
## Capabilities
18+
19+
### New Capabilities
20+
- `dlc-dms-table-resource`: 通过 Terraform 管理 DLC DMS 元数据表资源的完整生命周期(创建、读取、更新、删除),包含表基础信息、列、分区键、分区、存储描述(Sds)、视图文本及数据源连接等参数。
21+
22+
### Modified Capabilities
23+
<!-- 无现有 spec 需要修改 -->
24+
25+
## Impact
26+
27+
- **新增代码文件**
28+
- `tencentcloud/services/dlc/resource_tc_tencentcloud_dlc_dms_table.go`(资源 CRUD 实现)
29+
- `tencentcloud/services/dlc/resource_tc_tencentcloud_dlc_dms_table_test.go`(单元测试)
30+
- `tencentcloud/services/dlc/resource_tc_tencentcloud_dlc_dms_table.md`(资源文档)
31+
- **修改代码文件**
32+
- `tencentcloud/provider.go`:注册 `tencentcloud_dlc_dms_table` 资源。
33+
- `tencentcloud/provider.md`:新增资源文档条目。
34+
- **依赖**:依赖 `vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dlc/v20210125` 中已有的 `CreateDMSTable``DescribeDMSTable``AlterDMSTable``DropDMSTable` 接口及 `Asset``DMSSds``DMSColumn``DMSPartition``KVPair` 等数据结构(已 vendored)。
35+
- **向后兼容**:纯新增资源,不修改任何现有资源 schema,完全向后兼容。

0 commit comments

Comments
 (0)