diff --git a/.changelog/2564.txt b/.changelog/2564.txt new file mode 100644 index 0000000000..8c22acfa83 --- /dev/null +++ b/.changelog/2564.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/tencentcloud_dasb_user_group_members: Fix errors in querying user group members +``` \ No newline at end of file diff --git a/.changelog/2566.txt b/.changelog/2566.txt new file mode 100644 index 0000000000..0d8ab46238 --- /dev/null +++ b/.changelog/2566.txt @@ -0,0 +1,3 @@ +```release-note:new-resource +tencentcloud_dasb_resource +``` \ No newline at end of file diff --git a/.changelog/2567.txt b/.changelog/2567.txt new file mode 100644 index 0000000000..670046d2fd --- /dev/null +++ b/.changelog/2567.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/tencentcloud_private_dns_record: params `zone_id` Add ForceNew +``` \ No newline at end of file diff --git a/.changelog/2568.txt b/.changelog/2568.txt new file mode 100644 index 0000000000..323284c83a --- /dev/null +++ b/.changelog/2568.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/tencentcloud_instance: Output `Uuid` of cvm instance +``` \ No newline at end of file diff --git a/.changelog/2569.txt b/.changelog/2569.txt new file mode 100644 index 0000000000..b23a2947c4 --- /dev/null +++ b/.changelog/2569.txt @@ -0,0 +1,19 @@ +```release-note:enhancement +resource/tencentcloud_vod_adaptive_dynamic_streaming_template: Add vcrf, gop, preserve_hdr_switch, codec_tag. Adjust resource unique id to subAppId#templateId. +``` + +```release-note:enhancement +resource/tencentcloud_vod_image_sprite_template: Add format, type. Adjust resource unique id to subAppId#templateId. +``` + +```release-note:enhancement +resource/tencentcloud_vod_procedure_template: Update params media_process_task, add ai_analysis_task, ai_recognition_task, review_audio_video_task, type. Adjust resource unique id to subAppId#templateId. +``` + +```release-note:enhancement +resource/tencentcloud_vod_sample_snapshot_template: Adjust resource unique id to subAppId#templateId. +``` + +```release-note:enhancement +resource/tencentcloud_vod_snapshot_by_time_offset_template: Add type. Adjust resource unique id to subAppId#templateId. +``` diff --git a/.changelog/2570.txt b/.changelog/2570.txt new file mode 100644 index 0000000000..35d51debfe --- /dev/null +++ b/.changelog/2570.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +datasource/tencentcloud_ckafka_topics: Update ckafka topics docs +``` \ No newline at end of file diff --git a/.changelog/2573.txt b/.changelog/2573.txt new file mode 100644 index 0000000000..d79ff504f2 --- /dev/null +++ b/.changelog/2573.txt @@ -0,0 +1,7 @@ +```release-note:deprecation +resource/tencentcloud_vpc_ipv6_eni_address +``` + +```release-note:new-resource +tencentcloud_eni_ipv6_address +``` \ No newline at end of file diff --git a/.changelog/2574.txt b/.changelog/2574.txt new file mode 100644 index 0000000000..d97418098b --- /dev/null +++ b/.changelog/2574.txt @@ -0,0 +1,3 @@ +```release-note:new-resource +tencentcloud_eni_ipv4_address +``` \ No newline at end of file diff --git a/.changelog/2575.txt b/.changelog/2575.txt new file mode 100644 index 0000000000..9fa06fe8a6 --- /dev/null +++ b/.changelog/2575.txt @@ -0,0 +1,3 @@ +```release-note:new-resource +tencentcloud_vod_event_config +``` \ No newline at end of file diff --git a/.changelog/2578.txt b/.changelog/2578.txt new file mode 100644 index 0000000000..d93626609c --- /dev/null +++ b/.changelog/2578.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/tencentcloud_kubernetes_cluster: Field `cluster_subnet_id` supports ForceNew +``` \ No newline at end of file diff --git a/.changelog/2581.txt b/.changelog/2581.txt new file mode 100644 index 0000000000..5ba9a67bdf --- /dev/null +++ b/.changelog/2581.txt @@ -0,0 +1,3 @@ +```release-note:new-resource +tencentcloud_tse_cngw_network_access_control +``` \ No newline at end of file diff --git a/.changelog/2582.txt b/.changelog/2582.txt new file mode 100644 index 0000000000..4b169ef416 --- /dev/null +++ b/.changelog/2582.txt @@ -0,0 +1,7 @@ +```release-note:enhancement +resource/tencentcloud_vod_adaptive_dynamic_streaming_template: add param `segment_type` +``` + +```release-note:enhancement +resource/tencentcloud_vod_procedure_template: update param `adaptive_dynamic_streaming_task_list` and `review_audio_video_task` +``` \ No newline at end of file diff --git a/.changelog/2583.txt b/.changelog/2583.txt new file mode 100644 index 0000000000..e43e2ecc56 --- /dev/null +++ b/.changelog/2583.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +datasource/tencentcloud_mariadb_db_instances: Support `vip`, `vport`, `internet_domain`, `internet_ip`, `internet_port` field +``` diff --git a/CHANGELOG.md b/CHANGELOG.md index f5c7f6881b..6a8ddb13ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,57 @@ +## 1.81.87 (April 7, 2024) + +FEATURES: + +* **New Resource:** `tencentcloud_tse_cngw_network_access_control` ([#2581](https://github.com/tencentcloudstack/terraform-provider-tencentcloud/pull/2581)) + +ENHANCEMENTS: + +* datasource/tencentcloud_mariadb_db_instances: Support `vip`, `vport`, `internet_domain`, `internet_ip`, `internet_port` field ([#2583](https://github.com/tencentcloudstack/terraform-provider-tencentcloud/pull/2583)) +* resource/tencentcloud_kubernetes_cluster: Field `cluster_subnet_id` supports ForceNew ([#2578](https://github.com/tencentcloudstack/terraform-provider-tencentcloud/pull/2578)) +* resource/tencentcloud_vod_adaptive_dynamic_streaming_template: add param `segment_type` ([#2582](https://github.com/tencentcloudstack/terraform-provider-tencentcloud/pull/2582)) +* resource/tencentcloud_vod_procedure_template: update param `adaptive_dynamic_streaming_task_list` and `review_audio_video_task` ([#2582](https://github.com/tencentcloudstack/terraform-provider-tencentcloud/pull/2582)) + +## 1.81.86 (March 28, 2024) + +FEATURES: + +* **New Resource:** `tencentcloud_vod_event_config` ([#2575](https://github.com/tencentcloudstack/terraform-provider-tencentcloud/pull/2575)) + +## 1.81.85 (March 27, 2024) + +FEATURES: + +* **New Resource:** `tencentcloud_eni_ipv4_address` ([#2574](https://github.com/tencentcloudstack/terraform-provider-tencentcloud/pull/2574)) +* **New Resource:** `tencentcloud_eni_ipv6_address` ([#2573](https://github.com/tencentcloudstack/terraform-provider-tencentcloud/pull/2573)) + +## 1.81.84 (March 25, 2024) + +ENHANCEMENTS: + +* datasource/tencentcloud_ckafka_topics: Update ckafka topics docs ([#2570](https://github.com/tencentcloudstack/terraform-provider-tencentcloud/pull/2570)) +* resource/tencentcloud_vod_adaptive_dynamic_streaming_template: Add vcrf, gop, preserve_hdr_switch, codec_tag. Adjust resource unique id to subAppId#templateId. ([#2569](https://github.com/tencentcloudstack/terraform-provider-tencentcloud/pull/2569)) +* resource/tencentcloud_vod_image_sprite_template: Add format, type. Adjust resource unique id to subAppId#templateId. ([#2569](https://github.com/tencentcloudstack/terraform-provider-tencentcloud/pull/2569)) +* resource/tencentcloud_vod_procedure_template: Update params media_process_task, add ai_analysis_task, ai_recognition_task, review_audio_video_task, type. Adjust resource unique id to subAppId#templateId. ([#2569](https://github.com/tencentcloudstack/terraform-provider-tencentcloud/pull/2569)) +* resource/tencentcloud_vod_sample_snapshot_template: Adjust resource unique id to subAppId#templateId. ([#2569](https://github.com/tencentcloudstack/terraform-provider-tencentcloud/pull/2569)) +* resource/tencentcloud_vod_snapshot_by_time_offset_template: Add type. Adjust resource unique id to subAppId#templateId. ([#2569](https://github.com/tencentcloudstack/terraform-provider-tencentcloud/pull/2569)) + +## 1.81.83 (March 20, 2024) + +FEATURES: + +* **New Resource:** `tencentcloud_dasb_resource` ([#2566](https://github.com/tencentcloudstack/terraform-provider-tencentcloud/pull/2566)) + +ENHANCEMENTS: + +* resource/tencentcloud_instance: Output `Uuid` of cvm instance ([#2568](https://github.com/tencentcloudstack/terraform-provider-tencentcloud/pull/2568)) +* resource/tencentcloud_private_dns_record: params `zone_id` Add ForceNew ([#2567](https://github.com/tencentcloudstack/terraform-provider-tencentcloud/pull/2567)) + +## 1.81.82 (March 15, 2024) + +ENHANCEMENTS: + +* resource/tencentcloud_dasb_user_group_members: Fix errors in querying user group members ([#2564](https://github.com/tencentcloudstack/terraform-provider-tencentcloud/pull/2564)) + ## 1.81.81 (March 13, 2024) FEATURES: diff --git a/go.mod b/go.mod index 296d5b9537..9699931f44 100644 --- a/go.mod +++ b/go.mod @@ -46,7 +46,7 @@ require ( github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.860 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cloudaudit v1.0.544 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cls v1.0.860 - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.860 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.888 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm v1.0.624 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cwp v1.0.762 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cynosdb v1.0.692 diff --git a/go.sum b/go.sum index 4b1340a343..d7697681a8 100644 --- a/go.sum +++ b/go.sum @@ -744,6 +744,8 @@ github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAm github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/sesky4/tencentcloud-sdk-go/tencentcloud/common v1.0.336-0.20240326032455-d61711597f1c h1:yPsYLRZAfaTYX33hyaXD8zgQeXS53hdwknNIo0csY9Y= +github.com/sesky4/tencentcloud-sdk-go/tencentcloud/common v1.0.336-0.20240326032455-d61711597f1c/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= @@ -920,9 +922,12 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.844/go.mod github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.845/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.853/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.856/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.857/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.859/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.860 h1:d5/YwGX6b5YgFU/0thsbs5aBp4aJJXBi7JyU1JHAaw0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.860/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.888 h1:FqVcZ+POUhckq6ZRlwOR819fsXp49YyizpmWZJYAAGg= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.888/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/csip v1.0.860 h1:F3esKBIT3HW9+7Gt8cVgf8X06VdGIczpgLBUECzSEzU= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/csip v1.0.860/go.mod h1:NZo1WplQcC314kMlCRUoy8NQju2BnolIJj7NAWgsuhY= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm v1.0.624 h1:nEZqsoqt1pEoaP9JjkHQy3/H00suCfzlHW1qOm2nYD8= @@ -1021,8 +1026,6 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tke v1.0.807 h1:/ziV4FF github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tke v1.0.807/go.mod h1:uRsVm3rUbE/YH4+G8o1Ppyl4ENtbLWliUxPk1yDr95k= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/trocket v1.0.756 h1:89M6uA8Y/FC1b88TFxvRManGW+i62Isqg1lW8HjHDvU= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/trocket v1.0.756/go.mod h1:AJAItBOTaarpDpUF7pNp0tuz2Y6H2oFuMcyKouPs1IE= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tse v1.0.804 h1:lYkKswjbdCICDATYfUtT1SrHhSBUcVFxnh0j0tSqhEA= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tse v1.0.804/go.mod h1:nE+gtagqpenButXqRAWh1MJBMRFbQchlXK4yCPWbSaQ= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tse v1.0.857 h1:TkJnvSeRSXsRCwOwcwXSvruSK9s/kw8LC3FLeccw+A0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tse v1.0.857/go.mod h1:CSGh7HSEzUoY09G67XTABi/aqNy3dSLCSuenb1i5x6k= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tsf v1.0.674 h1:VsMV1/vsgVzespG7jUzraZS/AbAUllVQjmtVAlA9W/M= @@ -1039,9 +1042,7 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/wss v1.0.199 h1:hMBLtiJ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/wss v1.0.199/go.mod h1:nnY91/H3j/Gu7V/oCA6Zeg8T5D3q36EUdBh4EjmHwqY= github.com/tencentyun/cos-go-sdk-v5 v0.7.42-0.20230629101357-7edd77448a0f h1:yTMDoBvFuXjZat10d98DIKbPnN9FQG+drt1SbNfMW5U= github.com/tencentyun/cos-go-sdk-v5 v0.7.42-0.20230629101357-7edd77448a0f/go.mod h1:LUFnaqRmGk6pEHOaRmdn2dCZR2j0cSsM5xowWFPTPao= -github.com/tenntenn/modver v1.0.1 h1:2klLppGhDgzJrScMpkj9Ujy3rXPUspSjAcev9tSEBgA= github.com/tenntenn/modver v1.0.1/go.mod h1:bePIyQPb7UeioSRkw3Q0XeMhYZSMx9B8ePqg6SAMGH0= -github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3 h1:f+jULpRQGxTSkNYKJ51yaw6ChIqO+Je8UqsTKN/cDag= github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY= github.com/tetafro/godot v1.4.11 h1:BVoBIqAf/2QdbFmSwAWnaIqDivZdOV0ZRwEm6jivLKw= github.com/tetafro/godot v1.4.11/go.mod h1:LR3CJpxDVGlYOWn3ZZg1PgNZdTUvzsZWu8xaEohUpn8= @@ -1079,7 +1080,6 @@ github.com/vmihailenco/tagparser v0.1.1 h1:quXMXlA39OCbd2wAdTsGDlK9RkOk6Wuw+x37w github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= github.com/wI2L/jsondiff v0.3.0 h1:iTzQ9u/d86GE9RsBzVHX88f2EA1vQUboHwLhSQFc1s4= github.com/wI2L/jsondiff v0.3.0/go.mod h1:y1IMzNNjlSsk3IUoJdRJO7VRBtzMvRgyo4Vu0LdHpTc= -github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI= github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8= github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= @@ -1118,7 +1118,6 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= @@ -1362,7 +1361,6 @@ golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1570,7 +1568,6 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= @@ -1580,7 +1577,6 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1628,5 +1624,4 @@ sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= -sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= diff --git a/tencentcloud/acctest/basic.go b/tencentcloud/acctest/basic.go index c6b72d6799..90f716a68a 100644 --- a/tencentcloud/acctest/basic.go +++ b/tencentcloud/acctest/basic.go @@ -940,8 +940,8 @@ const ( DefaultMariadbVpcId = "vpc-k1t8ickr" DefaultMariadbSecurityGroupId = "sg-7kpsbxdb" - DefaultMariadbInstanceSubnetId = "subnet-4w4twlf4" - DefaultMariadbInstanceVpcId = "vpc-9m66acml" + DefaultMariadbInstanceSubnetId = "subnet-8fpt571a" + DefaultMariadbInstanceVpcId = "vpc-axrsmmrv" ) // End of MARIADB diff --git a/tencentcloud/connectivity/client.go b/tencentcloud/connectivity/client.go index f01fa02561..7bf400fc5a 100644 --- a/tencentcloud/connectivity/client.go +++ b/tencentcloud/connectivity/client.go @@ -295,14 +295,20 @@ func (me *TencentCloudClient) UseTencentCosClient(bucket string) *cos.Client { } // UseMysqlClient returns mysql(cdb) client for service -func (me *TencentCloudClient) UseMysqlClient() *cdb.Client { +func (me *TencentCloudClient) UseMysqlClient(iacExtInfo ...IacExtInfo) *cdb.Client { + var logRoundTripper LogRoundTripper + if len(iacExtInfo) != 0 { + logRoundTripper.InstanceId = iacExtInfo[0].InstanceId + } + if me.mysqlConn != nil { + me.mysqlConn.WithHttpTransport(&logRoundTripper) return me.mysqlConn } cpf := me.NewClientProfile(300) me.mysqlConn, _ = cdb.NewClient(me.Credential, me.Region, cpf) - me.mysqlConn.WithHttpTransport(&LogRoundTripper{}) + me.mysqlConn.WithHttpTransport(&logRoundTripper) return me.mysqlConn } @@ -334,28 +340,40 @@ func (me *TencentCloudClient) UseAsClient() *as.Client { } // UseVpcClient returns vpc client for service -func (me *TencentCloudClient) UseVpcClient() *vpc.Client { +func (me *TencentCloudClient) UseVpcClient(iacExtInfo ...IacExtInfo) *vpc.Client { + var logRoundTripper LogRoundTripper + if len(iacExtInfo) != 0 { + logRoundTripper.InstanceId = iacExtInfo[0].InstanceId + } + if me.vpcConn != nil { + me.vpcConn.WithHttpTransport(&logRoundTripper) return me.vpcConn } cpf := me.NewClientProfile(300) me.vpcConn, _ = vpc.NewClient(me.Credential, me.Region, cpf) - me.vpcConn.WithHttpTransport(&LogRoundTripper{}) + me.vpcConn.WithHttpTransport(&logRoundTripper) return me.vpcConn } // UseCbsClient returns cbs client for service -func (me *TencentCloudClient) UseCbsClient() *cbs.Client { +func (me *TencentCloudClient) UseCbsClient(iacExtInfo ...IacExtInfo) *cbs.Client { + var logRoundTripper LogRoundTripper + if len(iacExtInfo) != 0 { + logRoundTripper.InstanceId = iacExtInfo[0].InstanceId + } + if me.cbsConn != nil { + me.cbsConn.WithHttpTransport(&logRoundTripper) return me.cbsConn } var reqTimeout = getEnvDefault(PROVIDER_CBS_REQUEST_TIMEOUT, 300) cpf := me.NewClientProfile(reqTimeout) me.cbsConn, _ = cbs.NewClient(me.Credential, me.Region, cpf) - me.cbsConn.WithHttpTransport(&LogRoundTripper{}) + me.cbsConn.WithHttpTransport(&logRoundTripper) return me.cbsConn } @@ -374,41 +392,59 @@ func (me *TencentCloudClient) UseDcClient() *dc.Client { } // UseMongodbClient returns mongodb client for service -func (me *TencentCloudClient) UseMongodbClient() *mongodb.Client { +func (me *TencentCloudClient) UseMongodbClient(iacExtInfo ...IacExtInfo) *mongodb.Client { + var logRoundTripper LogRoundTripper + if len(iacExtInfo) != 0 { + logRoundTripper.InstanceId = iacExtInfo[0].InstanceId + } + if me.mongodbConn != nil { + me.mongodbConn.WithHttpTransport(&logRoundTripper) return me.mongodbConn } cpf := me.NewClientProfile(300) me.mongodbConn, _ = mongodb.NewClient(me.Credential, me.Region, cpf) - me.mongodbConn.WithHttpTransport(&LogRoundTripper{}) + me.mongodbConn.WithHttpTransport(&logRoundTripper) return me.mongodbConn } // UseClbClient returns clb client for service -func (me *TencentCloudClient) UseClbClient() *clb.Client { +func (me *TencentCloudClient) UseClbClient(iacExtInfo ...IacExtInfo) *clb.Client { + var logRoundTripper LogRoundTripper + if len(iacExtInfo) != 0 { + logRoundTripper.InstanceId = iacExtInfo[0].InstanceId + } + if me.clbConn != nil { + me.clbConn.WithHttpTransport(&logRoundTripper) return me.clbConn } cpf := me.NewClientProfile(300) me.clbConn, _ = clb.NewClient(me.Credential, me.Region, cpf) - me.clbConn.WithHttpTransport(&LogRoundTripper{}) + me.clbConn.WithHttpTransport(&logRoundTripper) return me.clbConn } // UseCvmClient returns cvm client for service -func (me *TencentCloudClient) UseCvmClient() *cvm.Client { +func (me *TencentCloudClient) UseCvmClient(iacExtInfo ...IacExtInfo) *cvm.Client { + var logRoundTripper LogRoundTripper + if len(iacExtInfo) != 0 { + logRoundTripper.InstanceId = iacExtInfo[0].InstanceId + } + if me.cvmConn != nil { + me.cvmConn.WithHttpTransport(&logRoundTripper) return me.cvmConn } var reqTimeout = getEnvDefault(PROVIDER_CVM_REQUEST_TIMEOUT, 300) cpf := me.NewClientProfile(reqTimeout) me.cvmConn, _ = cvm.NewClient(me.Credential, me.Region, cpf) - me.cvmConn.WithHttpTransport(&LogRoundTripper{}) + me.cvmConn.WithHttpTransport(&logRoundTripper) return me.cvmConn } @@ -427,40 +463,58 @@ func (me *TencentCloudClient) UseTagClient() *tag.Client { } // UseTkeClient returns tke client for service -func (me *TencentCloudClient) UseTkeClient() *tke.Client { +func (me *TencentCloudClient) UseTkeClient(iacExtInfo ...IacExtInfo) *tke.Client { + var logRoundTripper LogRoundTripper + if len(iacExtInfo) != 0 { + logRoundTripper.InstanceId = iacExtInfo[0].InstanceId + } + if me.tkeConn != nil { + me.tkeConn.WithHttpTransport(&logRoundTripper) return me.tkeConn } cpf := me.NewClientProfile(300) me.tkeConn, _ = tke.NewClient(me.Credential, me.Region, cpf) - me.tkeConn.WithHttpTransport(&LogRoundTripper{}) + me.tkeConn.WithHttpTransport(&logRoundTripper) return me.tkeConn } // UseTdmqClient returns Tdmq client for service -func (me *TencentCloudClient) UseTdmqClient() *tdmq.Client { +func (me *TencentCloudClient) UseTdmqClient(iacExtInfo ...IacExtInfo) *tdmq.Client { + var logRoundTripper LogRoundTripper + if len(iacExtInfo) != 0 { + logRoundTripper.InstanceId = iacExtInfo[0].InstanceId + } + if me.tdmqConn != nil { + me.tdmqConn.WithHttpTransport(&logRoundTripper) return me.tdmqConn } cpf := me.NewClientProfile(300) me.tdmqConn, _ = tdmq.NewClient(me.Credential, me.Region, cpf) - me.tdmqConn.WithHttpTransport(&LogRoundTripper{}) + me.tdmqConn.WithHttpTransport(&logRoundTripper) return me.tdmqConn } // UseGaapClient returns gaap client for service -func (me *TencentCloudClient) UseGaapClient() *gaap.Client { +func (me *TencentCloudClient) UseGaapClient(iacExtInfo ...IacExtInfo) *gaap.Client { + var logRoundTripper LogRoundTripper + if len(iacExtInfo) != 0 { + logRoundTripper.InstanceId = iacExtInfo[0].InstanceId + } + if me.gaapConn != nil { + me.gaapConn.WithHttpTransport(&logRoundTripper) return me.gaapConn } cpf := me.NewClientProfile(300) me.gaapConn, _ = gaap.NewClient(me.Credential, me.Region, cpf) - me.gaapConn.WithHttpTransport(&LogRoundTripper{}) + me.gaapConn.WithHttpTransport(&logRoundTripper) return me.gaapConn } @@ -521,14 +575,20 @@ func (me *TencentCloudClient) UseCfsClient() *cfs.Client { } // UseScfClient returns scf client for service -func (me *TencentCloudClient) UseScfClient() *scf.Client { +func (me *TencentCloudClient) UseScfClient(iacExtInfo ...IacExtInfo) *scf.Client { + var logRoundTripper LogRoundTripper + if len(iacExtInfo) != 0 { + logRoundTripper.InstanceId = iacExtInfo[0].InstanceId + } + if me.scfConn != nil { + me.scfConn.WithHttpTransport(&logRoundTripper) return me.scfConn } cpf := me.NewClientProfile(300) me.scfConn, _ = scf.NewClient(me.Credential, me.Region, cpf) - me.scfConn.WithHttpTransport(&LogRoundTripper{}) + me.scfConn.WithHttpTransport(&logRoundTripper) return me.scfConn } @@ -560,14 +620,20 @@ func (me *TencentCloudClient) UseDayuClient() *dayu.Client { } // UseCdnClient returns cdn client for service -func (me *TencentCloudClient) UseCdnClient() *cdn.Client { +func (me *TencentCloudClient) UseCdnClient(iacExtInfo ...IacExtInfo) *cdn.Client { + var logRoundTripper LogRoundTripper + if len(iacExtInfo) != 0 { + logRoundTripper.InstanceId = iacExtInfo[0].InstanceId + } + if me.cdnConn != nil { + me.cdnConn.WithHttpTransport(&logRoundTripper) return me.cdnConn } cpf := me.NewClientProfile(300) me.cdnConn, _ = cdn.NewClient(me.Credential, me.Region, cpf) - me.cdnConn.WithHttpTransport(&LogRoundTripper{}) + me.cdnConn.WithHttpTransport(&logRoundTripper) return me.cdnConn } @@ -586,54 +652,78 @@ func (me *TencentCloudClient) UseMonitorClient() *monitor.Client { } // UseEsClient returns es client for service -func (me *TencentCloudClient) UseEsClient() *es.Client { +func (me *TencentCloudClient) UseEsClient(iacExtInfo ...IacExtInfo) *es.Client { + var logRoundTripper LogRoundTripper + if len(iacExtInfo) != 0 { + logRoundTripper.InstanceId = iacExtInfo[0].InstanceId + } + if me.esConn != nil { + me.esConn.WithHttpTransport(&logRoundTripper) return me.esConn } cpf := me.NewClientProfile(300) cpf.Language = "zh-CN" me.esConn, _ = es.NewClient(me.Credential, me.Region, cpf) - me.esConn.WithHttpTransport(&LogRoundTripper{}) + me.esConn.WithHttpTransport(&logRoundTripper) return me.esConn } // UsePostgresqlClient returns postgresql client for service -func (me *TencentCloudClient) UsePostgresqlClient() *postgre.Client { +func (me *TencentCloudClient) UsePostgresqlClient(iacExtInfo ...IacExtInfo) *postgre.Client { + var logRoundTripper LogRoundTripper + if len(iacExtInfo) != 0 { + logRoundTripper.InstanceId = iacExtInfo[0].InstanceId + } + if me.postgreConn != nil { + me.postgreConn.WithHttpTransport(&logRoundTripper) return me.postgreConn } cpf := me.NewClientProfile(300) me.postgreConn, _ = postgre.NewClient(me.Credential, me.Region, cpf) - me.postgreConn.WithHttpTransport(&LogRoundTripper{}) + me.postgreConn.WithHttpTransport(&logRoundTripper) return me.postgreConn } // UseSqlserverClient returns sqlserver client for service -func (me *TencentCloudClient) UseSqlserverClient() *sqlserver.Client { +func (me *TencentCloudClient) UseSqlserverClient(iacExtInfo ...IacExtInfo) *sqlserver.Client { + var logRoundTripper LogRoundTripper + if len(iacExtInfo) != 0 { + logRoundTripper.InstanceId = iacExtInfo[0].InstanceId + } + if me.sqlserverConn != nil { + me.sqlserverConn.WithHttpTransport(&logRoundTripper) return me.sqlserverConn } cpf := me.NewClientProfile(300) me.sqlserverConn, _ = sqlserver.NewClient(me.Credential, me.Region, cpf) - me.sqlserverConn.WithHttpTransport(&LogRoundTripper{}) + me.sqlserverConn.WithHttpTransport(&logRoundTripper) return me.sqlserverConn } // UseCkafkaClient returns ckafka client for service -func (me *TencentCloudClient) UseCkafkaClient() *ckafka.Client { +func (me *TencentCloudClient) UseCkafkaClient(iacExtInfo ...IacExtInfo) *ckafka.Client { + var logRoundTripper LogRoundTripper + if len(iacExtInfo) != 0 { + logRoundTripper.InstanceId = iacExtInfo[0].InstanceId + } + if me.ckafkaConn != nil { + me.ckafkaConn.WithHttpTransport(&logRoundTripper) return me.ckafkaConn } cpf := me.NewClientProfile(300) me.ckafkaConn, _ = ckafka.NewClient(me.Credential, me.Region, cpf) - me.ckafkaConn.WithHttpTransport(&LogRoundTripper{}) + me.ckafkaConn.WithHttpTransport(&logRoundTripper) return me.ckafkaConn } @@ -691,14 +781,20 @@ func (me *TencentCloudClient) UseAPIGatewayClient() *apigateway.Client { } // UseTCRClient returns apigateway client for service -func (me *TencentCloudClient) UseTCRClient() *tcr.Client { +func (me *TencentCloudClient) UseTCRClient(iacExtInfo ...IacExtInfo) *tcr.Client { + var logRoundTripper LogRoundTripper + if len(iacExtInfo) != 0 { + logRoundTripper.InstanceId = iacExtInfo[0].InstanceId + } + if me.tcrConn != nil { + me.tcrConn.WithHttpTransport(&logRoundTripper) return me.tcrConn } cpf := me.NewClientProfile(300) me.tcrConn, _ = tcr.NewClient(me.Credential, me.Region, cpf) - me.tcrConn.WithHttpTransport(&LogRoundTripper{}) + me.tcrConn.WithHttpTransport(&logRoundTripper) return me.tcrConn } @@ -767,25 +863,39 @@ func (me *TencentCloudClient) UseEmrClient() *emr.Client { } // UseClsClient return CLS client for service -func (me *TencentCloudClient) UseClsClient() *cls.Client { +func (me *TencentCloudClient) UseClsClient(iacExtInfo ...IacExtInfo) *cls.Client { + var logRoundTripper LogRoundTripper + if len(iacExtInfo) != 0 { + logRoundTripper.InstanceId = iacExtInfo[0].InstanceId + } + if me.clsConn != nil { + me.clsConn.WithHttpTransport(&logRoundTripper) return me.clsConn } + cpf := me.NewClientProfile(300) me.clsConn, _ = cls.NewClient(me.Credential, me.Region, cpf) - me.clsConn.WithHttpTransport(&LogRoundTripper{}) + me.clsConn.WithHttpTransport(&logRoundTripper) return me.clsConn } // UseLighthouseClient return Lighthouse client for service -func (me *TencentCloudClient) UseLighthouseClient() *lighthouse.Client { +func (me *TencentCloudClient) UseLighthouseClient(iacExtInfo ...IacExtInfo) *lighthouse.Client { + var logRoundTripper LogRoundTripper + if len(iacExtInfo) != 0 { + logRoundTripper.InstanceId = iacExtInfo[0].InstanceId + } + if me.lighthouseConn != nil { + me.lighthouseConn.WithHttpTransport(&logRoundTripper) return me.lighthouseConn } + cpf := me.NewClientProfile(300) me.lighthouseConn, _ = lighthouse.NewClient(me.Credential, me.Region, cpf) - me.lighthouseConn.WithHttpTransport(&LogRoundTripper{}) + me.lighthouseConn.WithHttpTransport(&logRoundTripper) return me.lighthouseConn } @@ -803,13 +913,20 @@ func (me *TencentCloudClient) UseDnsPodClient() *dnspod.Client { } // UsePrivateDnsClient return PrivateDns client for service -func (me *TencentCloudClient) UsePrivateDnsClient() *privatedns.Client { +func (me *TencentCloudClient) UsePrivateDnsClient(iacExtInfo ...IacExtInfo) *privatedns.Client { + var logRoundTripper LogRoundTripper + if len(iacExtInfo) != 0 { + logRoundTripper.InstanceId = iacExtInfo[0].InstanceId + } + if me.privateDnsConn != nil { + me.privateDnsConn.WithHttpTransport(&logRoundTripper) return me.privateDnsConn } + cpf := me.NewClientProfile(300) me.privateDnsConn, _ = privatedns.NewClient(me.Credential, me.Region, cpf) - me.privateDnsConn.WithHttpTransport(&LogRoundTripper{}) + me.privateDnsConn.WithHttpTransport(&logRoundTripper) return me.privateDnsConn } @@ -853,14 +970,20 @@ func (me *TencentCloudClient) UseTemClient() *tem.Client { } // UseTeoClient returns teo client for service -func (me *TencentCloudClient) UseTeoClient() *teo.Client { +func (me *TencentCloudClient) UseTeoClient(iacExtInfo ...IacExtInfo) *teo.Client { + var logRoundTripper LogRoundTripper + if len(iacExtInfo) != 0 { + logRoundTripper.InstanceId = iacExtInfo[0].InstanceId + } + if me.teoConn != nil { + me.teoConn.WithHttpTransport(&logRoundTripper) return me.teoConn } cpf := me.NewClientProfile(300) me.teoConn, _ = teo.NewClient(me.Credential, me.Region, cpf) - me.teoConn.WithHttpTransport(&LogRoundTripper{}) + me.teoConn.WithHttpTransport(&logRoundTripper) return me.teoConn } @@ -944,14 +1067,20 @@ func (me *TencentCloudClient) UseCatClient() *cat.Client { } // UseMariadbClient returns mariadb client for service -func (me *TencentCloudClient) UseMariadbClient() *mariadb.Client { +func (me *TencentCloudClient) UseMariadbClient(iacExtInfo ...IacExtInfo) *mariadb.Client { + var logRoundTripper LogRoundTripper + if len(iacExtInfo) != 0 { + logRoundTripper.InstanceId = iacExtInfo[0].InstanceId + } + if me.mariadbConn != nil { + me.mariadbConn.WithHttpTransport(&logRoundTripper) return me.mariadbConn } cpf := me.NewClientProfile(300) me.mariadbConn, _ = mariadb.NewClient(me.Credential, me.Region, cpf) - me.mariadbConn.WithHttpTransport(&LogRoundTripper{}) + me.mariadbConn.WithHttpTransport(&logRoundTripper) return me.mariadbConn } @@ -996,14 +1125,20 @@ func (me *TencentCloudClient) UseOrganizationClient() *organization.Client { } // UseTdcpgClient returns tdcpg client for service -func (me *TencentCloudClient) UseTdcpgClient() *tdcpg.Client { +func (me *TencentCloudClient) UseTdcpgClient(iacExtInfo ...IacExtInfo) *tdcpg.Client { + var logRoundTripper LogRoundTripper + if len(iacExtInfo) != 0 { + logRoundTripper.InstanceId = iacExtInfo[0].InstanceId + } + if me.tdcpgConn != nil { + me.tdcpgConn.WithHttpTransport(&logRoundTripper) return me.tdcpgConn } cpf := me.NewClientProfile(300) me.tdcpgConn, _ = tdcpg.NewClient(me.Credential, me.Region, cpf) - me.tdcpgConn.WithHttpTransport(&LogRoundTripper{}) + me.tdcpgConn.WithHttpTransport(&logRoundTripper) return me.tdcpgConn } @@ -1218,15 +1353,21 @@ func (me *TencentCloudClient) UseCiamClient() *ciam.Client { } // UseTseClient returns tse client for service -func (me *TencentCloudClient) UseTseClient() *tse.Client { +func (me *TencentCloudClient) UseTseClient(iacExtInfo ...IacExtInfo) *tse.Client { + var logRoundTripper LogRoundTripper + if len(iacExtInfo) != 0 { + logRoundTripper.InstanceId = iacExtInfo[0].InstanceId + } + if me.tseConn != nil { + me.tseConn.WithHttpTransport(&logRoundTripper) return me.tseConn } cpf := me.NewClientProfile(300) cpf.Language = "zh-CN" me.tseConn, _ = tse.NewClient(me.Credential, me.Region, cpf) - me.tseConn.WithHttpTransport(&LogRoundTripper{}) + me.tseConn.WithHttpTransport(&logRoundTripper) return me.tseConn } @@ -1287,28 +1428,40 @@ func (me *TencentCloudClient) UseWedataClient() *wedata.Client { return me.wedataConn } -func (me *TencentCloudClient) UseWafClient() *waf.Client { +func (me *TencentCloudClient) UseWafClient(iacExtInfo ...IacExtInfo) *waf.Client { + var logRoundTripper LogRoundTripper + if len(iacExtInfo) != 0 { + logRoundTripper.InstanceId = iacExtInfo[0].InstanceId + } + if me.wafConn != nil { + me.wafConn.WithHttpTransport(&logRoundTripper) return me.wafConn } cpf := me.NewClientProfile(300) cpf.Language = "zh-CN" me.wafConn, _ = waf.NewClient(me.Credential, me.Region, cpf) - me.wafConn.WithHttpTransport(&LogRoundTripper{}) + me.wafConn.WithHttpTransport(&logRoundTripper) return me.wafConn } -func (me *TencentCloudClient) UseCfwClient() *cfw.Client { +func (me *TencentCloudClient) UseCfwClient(iacExtInfo ...IacExtInfo) *cfw.Client { + var logRoundTripper LogRoundTripper + if len(iacExtInfo) != 0 { + logRoundTripper.InstanceId = iacExtInfo[0].InstanceId + } + if me.cfwConn != nil { + me.cfwConn.WithHttpTransport(&logRoundTripper) return me.cfwConn } cpf := me.NewClientProfile(300) cpf.Language = "zh-CN" me.cfwConn, _ = cfw.NewClient(me.Credential, me.Region, cpf) - me.cfwConn.WithHttpTransport(&LogRoundTripper{}) + me.cfwConn.WithHttpTransport(&logRoundTripper) return me.cfwConn } diff --git a/tencentcloud/connectivity/transport.go b/tencentcloud/connectivity/transport.go index 02c2a4c1f2..dbb1b4eb26 100644 --- a/tencentcloud/connectivity/transport.go +++ b/tencentcloud/connectivity/transport.go @@ -25,6 +25,11 @@ func SetReqClient(name string) { } type LogRoundTripper struct { + InstanceId string +} + +type IacExtInfo struct { + InstanceId string } func (me *LogRoundTripper) RoundTrip(request *http.Request) (response *http.Response, errRet error) { @@ -39,22 +44,29 @@ func (me *LogRoundTripper) RoundTrip(request *http.Request) (response *http.Resp if errRet != nil { return } + var headName = "X-TC-Action" if envReqClient := os.Getenv(REQUEST_CLIENT); envReqClient != "" { ReqClient = envReqClient } + if routeUserID := os.Getenv(ENV_TESTING_ROUTE_USER_ID); routeUserID != "" { request.Header.Set(ENV_TESTING_ROUTE_HEADER_KEY, routeUserID) } + + if me.InstanceId != "" { + ReqClient = fmt.Sprintf("%s,id=%s", ReqClient, me.InstanceId) + } + request.Header.Set("X-TC-RequestClient", ReqClient) inBytes = []byte(fmt.Sprintf("%s, request: ", request.Header[headName])) requestBody, errRet := ioutil.ReadAll(bodyReader) if errRet != nil { return } - inBytes = append(inBytes, requestBody...) + inBytes = append(inBytes, requestBody...) headName = "X-TC-Region" appendMessage := []byte(fmt.Sprintf( ", (host %+v, region:%+v)", @@ -63,15 +75,16 @@ func (me *LogRoundTripper) RoundTrip(request *http.Request) (response *http.Resp )) inBytes = append(inBytes, appendMessage...) - response, errRet = http.DefaultTransport.RoundTrip(request) if errRet != nil { return } + outBytes, errRet = ioutil.ReadAll(response.Body) if errRet != nil { return } + response.Body = ioutil.NopCloser(bytes.NewBuffer(outBytes)) return } @@ -83,11 +96,13 @@ func (me *LogRoundTripper) log(in []byte, out []byte, err error, start time.Time if err != nil { tag = "[CRITICAL]" } + buf.WriteString(tag) if len(in) > 0 { buf.WriteString("tencentcloud-sdk-go: ") buf.Write(in) } + if len(out) > 0 { buf.WriteString("; response:") err := json.Compact(&buf, out) diff --git a/tencentcloud/provider.go b/tencentcloud/provider.go index 3fe7c1c23f..0fe00be2c6 100644 --- a/tencentcloud/provider.go +++ b/tencentcloud/provider.go @@ -14,6 +14,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/mitchellh/go-homedir" sdkcommon "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" + commonJson "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/json" sdksts "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/sts/v20180813" tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/connectivity" @@ -139,6 +140,10 @@ type TencentCloudClient struct { var _ tccommon.ProviderMeta = &TencentCloudClient{} +func init() { + commonJson.OmitBehaviour = commonJson.OmitEmpty +} + // GetAPIV3Conn 返回访问云 API 的客户端连接对象 func (meta *TencentCloudClient) GetAPIV3Conn() *connectivity.TencentCloudClient { return meta.apiV3Conn @@ -1050,6 +1055,8 @@ func Provider() *schema.Provider { "tencentcloud_eni": vpc.ResourceTencentCloudEni(), "tencentcloud_eni_attachment": vpc.ResourceTencentCloudEniAttachment(), "tencentcloud_eni_sg_attachment": vpc.ResourceTencentCloudEniSgAttachment(), + "tencentcloud_eni_ipv6_address": vpc.ResourceTencentCloudEniIpv6Address(), + "tencentcloud_eni_ipv4_address": vpc.ResourceTencentCloudEniIpv4Address(), "tencentcloud_ccn": ccn.ResourceTencentCloudCcn(), "tencentcloud_ccn_attachment": ccn.ResourceTencentCloudCcnAttachment(), "tencentcloud_ccn_bandwidth_limit": ccn.ResourceTencentCloudCcnBandwidthLimit(), @@ -1428,6 +1435,7 @@ func Provider() *schema.Provider { "tencentcloud_vod_sample_snapshot_template": vod.ResourceTencentCloudVodSampleSnapshotTemplate(), "tencentcloud_vod_transcode_template": vod.ResourceTencentCloudVodTranscodeTemplate(), "tencentcloud_vod_watermark_template": vod.ResourceTencentCloudVodWatermarkTemplate(), + "tencentcloud_vod_event_config": vod.ResourceTencentCloudVodEventConfig(), "tencentcloud_sqlserver_publish_subscribe": sqlserver.ResourceTencentCloudSqlserverPublishSubscribe(), "tencentcloud_api_gateway_usage_plan": apigateway.ResourceTencentCloudAPIGatewayUsagePlan(), "tencentcloud_api_gateway_usage_plan_attachment": apigateway.ResourceTencentCloudAPIGatewayUsagePlanAttachment(), @@ -1842,6 +1850,7 @@ func Provider() *schema.Provider { "tencentcloud_tse_waf_protection": tse.ResourceTencentCloudTseWafProtection(), "tencentcloud_tse_waf_domains": tse.ResourceTencentCloudTseWafDomains(), "tencentcloud_tse_cngw_network": tse.ResourceTencentCloudTseCngwNetwork(), + "tencentcloud_tse_cngw_network_access_control": tse.ResourceTencentCloudTseCngwNetworkAccessControl(), "tencentcloud_tse_cngw_strategy": tse.ResourceTencentCloudTseCngwStrategy(), "tencentcloud_tse_cngw_strategy_bind_group": tse.ResourceTencentCloudTseCngwStrategyBindGroup(), "tencentcloud_clickhouse_instance": cdwch.ResourceTencentCloudClickhouseInstance(), diff --git a/tencentcloud/provider.md b/tencentcloud/provider.md index 4ede571801..dc3f36b513 100644 --- a/tencentcloud/provider.md +++ b/tencentcloud/provider.md @@ -1117,11 +1117,11 @@ Video on Demand(VOD) tencentcloud_vod_procedure_template tencentcloud_vod_snapshot_by_time_offset_template tencentcloud_vod_image_sprite_template - tencentcloud_vod_super_player_config tencentcloud_vod_sub_application tencentcloud_vod_sample_snapshot_template tencentcloud_vod_transcode_template tencentcloud_vod_watermark_template + tencentcloud_vod_event_config Oceanus Data Source @@ -1199,6 +1199,8 @@ Virtual Private Cloud(VPC) tencentcloud_eni tencentcloud_eni_attachment tencentcloud_eni_sg_attachment + tencentcloud_eni_ipv4_address + tencentcloud_eni_ipv6_address tencentcloud_vpc tencentcloud_vpc_acl tencentcloud_vpc_acl_attachment @@ -1927,6 +1929,7 @@ Tencent Cloud Service Engine(TSE) tencentcloud_tse_cngw_network tencentcloud_tse_cngw_strategy tencentcloud_tse_cngw_strategy_bind_group + tencentcloud_tse_cngw_network_access_control ClickHouse(CDWCH) Data Source @@ -2080,6 +2083,7 @@ Cloud Firewall(CFW) Bastion Host(BH) Resource + tencentcloud_dasb_resource tencentcloud_dasb_acl tencentcloud_dasb_cmd_template tencentcloud_dasb_device_group @@ -2088,7 +2092,6 @@ Bastion Host(BH) tencentcloud_dasb_device_group_members tencentcloud_dasb_user_group_members tencentcloud_dasb_bind_device_resource - tencentcloud_dasb_resource tencentcloud_dasb_device tencentcloud_dasb_user_group tencentcloud_dasb_reset_user diff --git a/tencentcloud/services/bh/resource_tc_dasb_acl.go b/tencentcloud/services/bh/resource_tc_dasb_acl.go index d142fa20dd..880d001c13 100644 --- a/tencentcloud/services/bh/resource_tc_dasb_acl.go +++ b/tencentcloud/services/bh/resource_tc_dasb_acl.go @@ -149,11 +149,13 @@ func ResourceTencentCloudDasbAcl() *schema.Resource { }, "validate_from": { Optional: true, + Computed: true, Type: schema.TypeString, Description: "Access permission effective time, such as: 2021-09-22T00:00:00+08:00If the effective and expiry time are not filled in, the access rights will be valid for a long time.", }, "validate_to": { Optional: true, + Computed: true, Type: schema.TypeString, Description: "Access permission expiration time, such as: 2021-09-23T00:00:00+08:00If the effective and expiry time are not filled in, the access rights will be valid for a long time.", }, diff --git a/tencentcloud/services/bh/resource_tc_dasb_acl.md b/tencentcloud/services/bh/resource_tc_dasb_acl.md index 43de5266ef..3e225853ae 100644 --- a/tencentcloud/services/bh/resource_tc_dasb_acl.md +++ b/tencentcloud/services/bh/resource_tc_dasb_acl.md @@ -3,6 +3,39 @@ Provides a resource to create a dasb acl Example Usage ```hcl +resource "tencentcloud_dasb_user" "example" { + user_name = "tf_example" + real_name = "terraform" + phone = "+86|18345678782" + email = "demo@tencent.com" + auth_type = 0 +} + +resource "tencentcloud_dasb_user_group" "example" { + name = "tf_example" +} + +resource "tencentcloud_dasb_device" "example" { + os_name = "Linux" + ip = "192.168.0.1" + port = 80 + name = "tf_example" +} + +resource "tencentcloud_dasb_device_group" "example" { + name = "tf_example" +} + +resource "tencentcloud_dasb_device_account" "example" { + device_id = tencentcloud_dasb_device.example.id + account = "root" +} + +resource "tencentcloud_dasb_cmd_template" "example" { + name = "tf_example" + cmd_list = "rm -rf*" +} + resource "tencentcloud_dasb_acl" "example" { name = "tf_example" allow_disk_redirect = true @@ -15,12 +48,12 @@ resource "tencentcloud_dasb_acl" "example" { allow_file_down = true max_file_up_size = 0 max_file_down_size = 0 - user_id_set = ["6", "2"] - user_group_id_set = ["6", "36"] - device_id_set = ["39", "81"] - device_group_id_set = ["2", "3"] - account_set = ["root"] - cmd_template_id_set = ["1", "7"] + user_id_set = [tencentcloud_dasb_user.example.id] + user_group_id_set = [tencentcloud_dasb_user_group.example.id] + device_id_set = [tencentcloud_dasb_device.example.id] + device_group_id_set = [tencentcloud_dasb_device_group.example.id] + account_set = [tencentcloud_dasb_device_account.example.id] + cmd_template_id_set = [tencentcloud_dasb_cmd_template.example.id] ac_template_id_set = [] allow_disk_file_up = true allow_disk_file_down = true @@ -28,9 +61,6 @@ resource "tencentcloud_dasb_acl" "example" { allow_shell_file_down = true allow_file_del = true allow_access_credential = true - department_id = "1.2" - validate_from = "2023-09-22T00:00:00+08:00" - validate_to = "2024-09-23T00:00:00+08:00" } ``` diff --git a/tencentcloud/services/bh/resource_tc_dasb_bind_device_account_password.md b/tencentcloud/services/bh/resource_tc_dasb_bind_device_account_password.md index 78a1955a19..8e609b346b 100644 --- a/tencentcloud/services/bh/resource_tc_dasb_bind_device_account_password.md +++ b/tencentcloud/services/bh/resource_tc_dasb_bind_device_account_password.md @@ -3,8 +3,20 @@ Provides a resource to create a dasb bind_device_account_password Example Usage ```hcl +resource "tencentcloud_dasb_device" "example" { + os_name = "Linux" + ip = "192.168.0.1" + port = 80 + name = "tf_example" +} + +resource "tencentcloud_dasb_device_account" "example" { + device_id = tencentcloud_dasb_device.example.id + account = "root" +} + resource "tencentcloud_dasb_bind_device_account_password" "example" { - device_account_id = 16 + device_account_id = tencentcloud_dasb_device_account.example.id password = "TerraformPassword" } ``` \ No newline at end of file diff --git a/tencentcloud/services/bh/resource_tc_dasb_bind_device_account_private_key.md b/tencentcloud/services/bh/resource_tc_dasb_bind_device_account_private_key.md index 8e46909bf6..52a3fb4eb1 100644 --- a/tencentcloud/services/bh/resource_tc_dasb_bind_device_account_private_key.md +++ b/tencentcloud/services/bh/resource_tc_dasb_bind_device_account_private_key.md @@ -3,8 +3,20 @@ Provides a resource to create a dasb bind_device_account_private_key Example Usage ```hcl +resource "tencentcloud_dasb_device" "example" { + os_name = "Linux" + ip = "192.168.0.1" + port = 80 + name = "tf_example" +} + +resource "tencentcloud_dasb_device_account" "example" { + device_id = tencentcloud_dasb_device.example.id + account = "root" +} + resource "tencentcloud_dasb_bind_device_account_private_key" "example" { - device_account_id = 16 + device_account_id = tencentcloud_dasb_device_account.example.id private_key = "MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUpwmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ51s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh" private_key_password = "TerraformPassword" } diff --git a/tencentcloud/services/bh/resource_tc_dasb_bind_device_resource.md b/tencentcloud/services/bh/resource_tc_dasb_bind_device_resource.md index b0228dfc9b..9ade33f175 100644 --- a/tencentcloud/services/bh/resource_tc_dasb_bind_device_resource.md +++ b/tencentcloud/services/bh/resource_tc_dasb_bind_device_resource.md @@ -4,7 +4,7 @@ Example Usage ```hcl resource "tencentcloud_dasb_bind_device_resource" "example" { - resource_id = "bh-saas-ocmzo6lgxiv" + resource_id = "bh-saas-weyosfym" device_id_set = [17, 18] } ``` \ No newline at end of file diff --git a/tencentcloud/services/bh/resource_tc_dasb_device.go b/tencentcloud/services/bh/resource_tc_dasb_device.go index 1e57e4352d..1026e36978 100644 --- a/tencentcloud/services/bh/resource_tc_dasb_device.go +++ b/tencentcloud/services/bh/resource_tc_dasb_device.go @@ -55,6 +55,7 @@ func ResourceTencentCloudDasbDevice() *schema.Resource { Type: schema.TypeSet, Elem: &schema.Schema{Type: schema.TypeString}, Optional: true, + Computed: true, Description: "Asset multi-node: fields ip and port.", }, }, @@ -159,8 +160,8 @@ func resourceTencentCloudDasbDeviceRead(d *schema.ResourceData, meta interface{} _ = d.Set("os_name", device.OsName) } - if device.PublicIp != nil { - _ = d.Set("ip", device.PublicIp) + if device.PrivateIp != nil { + _ = d.Set("ip", device.PrivateIp) } if device.Port != nil { diff --git a/tencentcloud/services/bh/resource_tc_dasb_device_account.go b/tencentcloud/services/bh/resource_tc_dasb_device_account.go index 438073fd44..573c71c88a 100644 --- a/tencentcloud/services/bh/resource_tc_dasb_device_account.go +++ b/tencentcloud/services/bh/resource_tc_dasb_device_account.go @@ -67,7 +67,7 @@ func resourceTencentCloudDasbDeviceAccountCreate(d *schema.ResourceData, meta in log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) } - if result == nil || result.Response.Id != nil { + if result == nil || result.Response.Id == nil { e = fmt.Errorf("dasb DeviceAccount not exists") return resource.NonRetryableError(e) } diff --git a/tencentcloud/services/bh/resource_tc_dasb_device_account.md b/tencentcloud/services/bh/resource_tc_dasb_device_account.md index 24d0227fbc..3a8d1c8d4c 100644 --- a/tencentcloud/services/bh/resource_tc_dasb_device_account.md +++ b/tencentcloud/services/bh/resource_tc_dasb_device_account.md @@ -3,8 +3,15 @@ Provides a resource to create a dasb device_account Example Usage ```hcl +resource "tencentcloud_dasb_device" "example" { + os_name = "Linux" + ip = "192.168.0.1" + port = 80 + name = "tf_example" +} + resource "tencentcloud_dasb_device_account" "example" { - device_id = 100 + device_id = tencentcloud_dasb_device.example.id account = "root" } ``` diff --git a/tencentcloud/services/bh/resource_tc_dasb_device_group_members.go b/tencentcloud/services/bh/resource_tc_dasb_device_group_members.go index 847121a52a..fe80902277 100644 --- a/tencentcloud/services/bh/resource_tc_dasb_device_group_members.go +++ b/tencentcloud/services/bh/resource_tc_dasb_device_group_members.go @@ -124,7 +124,8 @@ func resourceTencentCloudDasbDeviceGroupMembersRead(d *schema.ResourceData, meta return nil } - _ = d.Set("device_group_id", deviceGroupId) + deviceGroupIdInt, _ := strconv.Atoi(deviceGroupId) + _ = d.Set("device_group_id", deviceGroupIdInt) _ = d.Set("member_id_set", DeviceGroupMembers) return nil diff --git a/tencentcloud/services/bh/resource_tc_dasb_device_group_members.md b/tencentcloud/services/bh/resource_tc_dasb_device_group_members.md index e22faef1ec..60f1eab6cf 100644 --- a/tencentcloud/services/bh/resource_tc_dasb_device_group_members.md +++ b/tencentcloud/services/bh/resource_tc_dasb_device_group_members.md @@ -3,9 +3,20 @@ Provides a resource to create a dasb device_group_members Example Usage ```hcl +resource "tencentcloud_dasb_device" "example" { + os_name = "Linux" + ip = "192.168.0.1" + port = 80 + name = "tf_example" +} + +resource "tencentcloud_dasb_device_group" "example" { + name = "tf_example" +} + resource "tencentcloud_dasb_device_group_members" "example" { - device_group_id = 3 - member_id_set = [1, 2, 3] + device_group_id = tencentcloud_dasb_device_group.example.id + member_id_set = [tencentcloud_dasb_device.example.id] } ``` @@ -14,5 +25,5 @@ Import dasb device_group_members can be imported using the id, e.g. ``` -terraform import tencentcloud_dasb_device_group_members.example 3#1,2,3 +terraform import tencentcloud_dasb_device_group_members.example 53#102 ``` \ No newline at end of file diff --git a/tencentcloud/services/bh/resource_tc_dasb_resource.go b/tencentcloud/services/bh/resource_tc_dasb_resource.go index fc0269c51f..00e03ec40c 100644 --- a/tencentcloud/services/bh/resource_tc_dasb_resource.go +++ b/tencentcloud/services/bh/resource_tc_dasb_resource.go @@ -52,16 +52,14 @@ func ResourceTencentCloudDasbResource() *schema.Resource { Description: "Number of resource nodes.", }, "time_unit": { - Required: true, - Type: schema.TypeString, - ValidateFunc: tccommon.ValidateAllowedStringValue([]string{"m"}), - Description: "Billing cycle, only support m: month.", + Optional: true, + Type: schema.TypeString, + Description: "Billing cycle, only support m: month. This field is mandatory, fill in m.", }, "time_span": { - Required: true, - Type: schema.TypeInt, - ValidateFunc: tccommon.ValidateIntegerMin(1), - Description: "Billing time.", + Optional: true, + Type: schema.TypeInt, + Description: "Billing time. This field is mandatory, with a minimum value of 1.", }, "auto_renew_flag": { Required: true, @@ -70,22 +68,32 @@ func ResourceTencentCloudDasbResource() *schema.Resource { Description: "Automatic renewal. 1 is auto renew flag, 0 is not.", }, "deploy_zone": { - Optional: true, + Required: true, Type: schema.TypeString, Description: "Deploy zone.", }, - "package_bandwidth": { - Optional: true, - Computed: true, - Type: schema.TypeInt, - Description: "Number of bandwidth expansion packets (4M).", + "cidr_block": { + Required: true, + Type: schema.TypeString, + Description: "Subnet segments that require service activation.", + }, + "vpc_cidr_block": { + Required: true, + Type: schema.TypeString, + Description: "The network segment corresponding to the VPC that requires service activation.", }, - "package_node": { + "package_bandwidth": { Optional: true, Computed: true, Type: schema.TypeInt, - Description: "Number of authorized point extension packages (50 points).", + Description: "Number of bandwidth expansion packets (4M), The set value is an integer multiple of 4.", }, + //"package_node": { + // Optional: true, + // Computed: true, + // Type: schema.TypeInt, + // Description: "Number of authorized point extension packages (50 points). Cannot exceed 100.", + //}, }, } } @@ -98,21 +106,31 @@ func resourceTencentCloudDasbResourceCreate(d *schema.ResourceData, meta interfa logId = tccommon.GetLogId(tccommon.ContextNil) request = dasb.NewCreateResourceRequest() response = dasb.NewCreateResourceResponse() + deployRequest = dasb.NewDeployResourceRequest() describeRequest = dasb.NewDescribeResourcesRequest() modifyRequest = dasb.NewModifyResourceRequest() resourceId string + vpcId string + subnetId string + deployRegion string + deployZone string + cidrBlock string + vpcCidrBlock string ) if v, ok := d.GetOk("deploy_region"); ok { request.DeployRegion = helper.String(v.(string)) + deployRegion = v.(string) } if v, ok := d.GetOk("vpc_id"); ok { request.VpcId = helper.String(v.(string)) + vpcId = v.(string) } if v, ok := d.GetOk("subnet_id"); ok { request.SubnetId = helper.String(v.(string)) + subnetId = v.(string) } if v, ok := d.GetOk("resource_edition"); ok { @@ -139,6 +157,15 @@ func resourceTencentCloudDasbResourceCreate(d *schema.ResourceData, meta interfa if v, ok := d.GetOk("deploy_zone"); ok { request.DeployZone = helper.String(v.(string)) + deployZone = v.(string) + } + + if v, ok := d.GetOk("cidr_block"); ok { + cidrBlock = v.(string) + } + + if v, ok := d.GetOk("vpc_cidr_block"); ok { + vpcCidrBlock = v.(string) } err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { @@ -149,7 +176,7 @@ func resourceTencentCloudDasbResourceCreate(d *schema.ResourceData, meta interfa log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) } - if result == nil || result.Response.ResourceId == nil { + if result == nil || *result.Response.ResourceId == "" { e = fmt.Errorf("dasb Resource not exists") return resource.NonRetryableError(e) } @@ -166,9 +193,39 @@ func resourceTencentCloudDasbResourceCreate(d *schema.ResourceData, meta interfa resourceId = *response.Response.ResourceId d.SetId(resourceId) + // deploy resource + deployRequest.ResourceId = helper.String(resourceId) + deployRequest.ApCode = helper.String(deployRegion) + deployRequest.Zone = helper.String(deployZone) + deployRequest.VpcId = helper.String(vpcId) + deployRequest.SubnetId = helper.String(subnetId) + deployRequest.CidrBlock = helper.String(cidrBlock) + deployRequest.VpcCidrBlock = helper.String(vpcCidrBlock) + + err = resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseDasbClient().DeployResource(deployRequest) + if e != nil { + return tccommon.RetryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, deployRequest.GetAction(), deployRequest.ToJsonString(), deployRequest.ToJsonString()) + } + + if result == nil { + e = fmt.Errorf("dasb Resource deploy error") + return resource.NonRetryableError(e) + } + + return nil + }) + + if err != nil { + log.Printf("[CRITAL]%s deploy dasb Resource failed, reason:%+v", logId, err) + return err + } + // wait describeRequest.ResourceIds = helper.Strings([]string{resourceId}) - err = resource.Retry(tccommon.WriteRetryTimeout*4, func() *resource.RetryError { + err = resource.Retry(tccommon.WriteRetryTimeout*6, func() *resource.RetryError { result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseDasbClient().DescribeResources(describeRequest) if e != nil { return tccommon.RetryError(e) @@ -181,6 +238,11 @@ func resourceTencentCloudDasbResourceCreate(d *schema.ResourceData, meta interfa return resource.NonRetryableError(e) } + if *result.Response.ResourceSet[0].Status == 4 { + e = fmt.Errorf("dasb Resource deploy error") + return resource.NonRetryableError(e) + } + if *result.Response.ResourceSet[0].Status == 1 { return nil } @@ -193,15 +255,16 @@ func resourceTencentCloudDasbResourceCreate(d *schema.ResourceData, meta interfa return err } + // modify if v, ok := d.GetOkExists("package_bandwidth"); ok { modifyRequest.PackageBandwidth = helper.IntInt64(v.(int)) } - if v, ok := d.GetOkExists("package_node"); ok { - modifyRequest.PackageNode = helper.IntInt64(v.(int)) - } + //if v, ok := d.GetOkExists("package_node"); ok { + // modifyRequest.PackageNode = helper.IntInt64(v.(int)) + //} - if modifyRequest.PackageBandwidth != nil || modifyRequest.PackageNode != nil { + if modifyRequest.PackageBandwidth != nil { modifyRequest.ResourceId = &resourceId err = resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseDasbClient().ModifyResource(modifyRequest) @@ -282,13 +345,21 @@ func resourceTencentCloudDasbResourceRead(d *schema.ResourceData, meta interface _ = d.Set("deploy_zone", Resource.Zone) } + if Resource.CidrBlock != nil { + _ = d.Set("cidr_block", Resource.CidrBlock) + } + + if Resource.VpcCidrBlock != nil { + _ = d.Set("vpc_cidr_block", Resource.VpcCidrBlock) + } + if Resource.PackageBandwidth != nil { _ = d.Set("package_bandwidth", Resource.PackageBandwidth) } - if Resource.PackageNode != nil { - _ = d.Set("package_node", Resource.PackageNode) - } + //if Resource.PackageNode != nil { + // _ = d.Set("package_node", Resource.PackageNode) + //} return nil } @@ -303,7 +374,7 @@ func resourceTencentCloudDasbResourceUpdate(d *schema.ResourceData, meta interfa resourceId = d.Id() ) - immutableArgs := []string{"deploy_region", "vpc_id", "subnet_id", "time_unit", "time_span", "pay_mode", "deploy_zone"} + immutableArgs := []string{"deploy_region", "vpc_id", "subnet_id", "time_unit", "time_span", "pay_mode", "deploy_zone", "cidr_block", "vpc_cidr_block"} for _, v := range immutableArgs { if d.HasChange(v) { @@ -336,11 +407,11 @@ func resourceTencentCloudDasbResourceUpdate(d *schema.ResourceData, meta interfa } } - if d.HasChange("package_node") { - if v, ok := d.GetOkExists("package_node"); ok { - request.PackageNode = helper.IntInt64(v.(int)) - } - } + //if d.HasChange("package_node") { + // if v, ok := d.GetOkExists("package_node"); ok { + // request.PackageNode = helper.IntInt64(v.(int)) + // } + //} err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseDasbClient().ModifyResource(request) diff --git a/tencentcloud/services/bh/resource_tc_dasb_resource.md b/tencentcloud/services/bh/resource_tc_dasb_resource.md index 36677e745c..cf71744488 100644 --- a/tencentcloud/services/bh/resource_tc_dasb_resource.md +++ b/tencentcloud/services/bh/resource_tc_dasb_resource.md @@ -2,19 +2,41 @@ Provides a resource to create a dasb resource Example Usage +Create a standard version instance + ```hcl resource "tencentcloud_dasb_resource" "example" { deploy_region = "ap-guangzhou" - vpc_id = "vpc-q1of50wz" - subnet_id = "subnet-7uhvm46o" + deploy_zone = "ap-guangzhou-6" + vpc_id = "vpc-fmz6l9nz" + subnet_id = "subnet-g7jhwhi2" + vpc_cidr_block = "10.35.0.0/16" + cidr_block = "10.35.20.0/24" resource_edition = "standard" - resource_node = 2 + resource_node = 50 time_unit = "m" time_span = 1 auto_renew_flag = 1 + package_bandwidth = 1 +} +``` + +Create a professional instance + +```hcl +resource "tencentcloud_dasb_resource" "example" { + deploy_region = "ap-guangzhou" deploy_zone = "ap-guangzhou-6" - package_bandwidth = 10 - package_node = 50 + vpc_id = "vpc-fmz6l9nz" + subnet_id = "subnet-g7jhwhi2" + vpc_cidr_block = "10.35.0.0/16" + cidr_block = "10.35.20.0/24" + resource_edition = "pro" + resource_node = 50 + time_unit = "m" + time_span = 1 + auto_renew_flag = 1 + package_bandwidth = 1 } ``` @@ -23,5 +45,5 @@ Import dasb resource can be imported using the id, e.g. ``` -terraform import tencentcloud_dasb_resource.example bh-saas-kk5rabk0 -``` \ No newline at end of file +terraform import tencentcloud_dasb_resource.example bh-saas-kgckynrt +``` diff --git a/tencentcloud/services/bh/resource_tc_dasb_resource_test.go b/tencentcloud/services/bh/resource_tc_dasb_resource_test.go index 7535074414..665b97c66f 100644 --- a/tencentcloud/services/bh/resource_tc_dasb_resource_test.go +++ b/tencentcloud/services/bh/resource_tc_dasb_resource_test.go @@ -22,8 +22,8 @@ func TestAccTencentCloudNeedFixDasbResourceResource_basic(t *testing.T) { Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttrSet("tencentcloud_dasb_resource.example", "id"), resource.TestCheckResourceAttr("tencentcloud_dasb_resource.example", "deploy_region", "ap-guangzhou"), - resource.TestCheckResourceAttr("tencentcloud_dasb_resource.example", "vpc_id", "vpc-q1of50wz"), - resource.TestCheckResourceAttr("tencentcloud_dasb_resource.example", "subnet_id", "subnet-7uhvm46o"), + resource.TestCheckResourceAttr("tencentcloud_dasb_resource.example", "vpc_id", "vpc-fmz6l9nz"), + resource.TestCheckResourceAttr("tencentcloud_dasb_resource.example", "subnet_id", "subnet-g7jhwhi2"), resource.TestCheckResourceAttr("tencentcloud_dasb_resource.example", "resource_edition", "standard"), resource.TestCheckResourceAttrSet("tencentcloud_dasb_resource.example", "resource_node"), resource.TestCheckResourceAttr("tencentcloud_dasb_resource.example", "time_unit", "m"), @@ -31,7 +31,8 @@ func TestAccTencentCloudNeedFixDasbResourceResource_basic(t *testing.T) { resource.TestCheckResourceAttrSet("tencentcloud_dasb_resource.example", "auto_renew_flag"), resource.TestCheckResourceAttr("tencentcloud_dasb_resource.example", "deploy_zone", "ap-guangzhou-6"), resource.TestCheckResourceAttrSet("tencentcloud_dasb_resource.example", "package_bandwidth"), - resource.TestCheckResourceAttrSet("tencentcloud_dasb_resource.example", "package_node"), + resource.TestCheckResourceAttr("tencentcloud_dasb_resource.example", "vpc_cidr_block", "10.35.0.0/16"), + resource.TestCheckResourceAttr("tencentcloud_dasb_resource.example", "cidr_block", "10.35.20.0/24"), ), }, { @@ -44,8 +45,8 @@ func TestAccTencentCloudNeedFixDasbResourceResource_basic(t *testing.T) { Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttrSet("tencentcloud_dasb_resource.example", "id"), resource.TestCheckResourceAttr("tencentcloud_dasb_resource.example", "deploy_region", "ap-guangzhou"), - resource.TestCheckResourceAttr("tencentcloud_dasb_resource.example", "vpc_id", "vpc-q1of50wz"), - resource.TestCheckResourceAttr("tencentcloud_dasb_resource.example", "subnet_id", "subnet-7uhvm46o"), + resource.TestCheckResourceAttr("tencentcloud_dasb_resource.example", "vpc_id", "vpc-fmz6l9nz"), + resource.TestCheckResourceAttr("tencentcloud_dasb_resource.example", "subnet_id", "subnet-g7jhwhi2"), resource.TestCheckResourceAttr("tencentcloud_dasb_resource.example", "resource_edition", "pro"), resource.TestCheckResourceAttrSet("tencentcloud_dasb_resource.example", "resource_node"), resource.TestCheckResourceAttr("tencentcloud_dasb_resource.example", "time_unit", "m"), @@ -53,7 +54,8 @@ func TestAccTencentCloudNeedFixDasbResourceResource_basic(t *testing.T) { resource.TestCheckResourceAttrSet("tencentcloud_dasb_resource.example", "auto_renew_flag"), resource.TestCheckResourceAttr("tencentcloud_dasb_resource.example", "deploy_zone", "ap-guangzhou-6"), resource.TestCheckResourceAttrSet("tencentcloud_dasb_resource.example", "package_bandwidth"), - resource.TestCheckResourceAttrSet("tencentcloud_dasb_resource.example", "package_node"), + resource.TestCheckResourceAttr("tencentcloud_dasb_resource.example", "vpc_cidr_block", "10.35.0.0/16"), + resource.TestCheckResourceAttr("tencentcloud_dasb_resource.example", "cidr_block", "10.35.20.0/24"), ), }, }, @@ -63,31 +65,33 @@ func TestAccTencentCloudNeedFixDasbResourceResource_basic(t *testing.T) { const testAccDasbResource = ` resource "tencentcloud_dasb_resource" "example" { deploy_region = "ap-guangzhou" - vpc_id = "vpc-q1of50wz" - subnet_id = "subnet-7uhvm46o" + deploy_zone = "ap-guangzhou-6" + vpc_id = "vpc-fmz6l9nz" + subnet_id = "subnet-g7jhwhi2" + vpc_cidr_block = "10.35.0.0/16" + cidr_block = "10.35.20.0/24" resource_edition = "standard" - resource_node = 2 + resource_node = 50 time_unit = "m" time_span = 1 auto_renew_flag = 1 - deploy_zone = "ap-guangzhou-6" - package_bandwidth = 10 - package_node = 50 + package_bandwidth = 1 } ` const testAccDasbResourceUpdate = ` resource "tencentcloud_dasb_resource" "example" { deploy_region = "ap-guangzhou" - vpc_id = "vpc-q1of50wz" - subnet_id = "subnet-7uhvm46o" + deploy_zone = "ap-guangzhou-6" + vpc_id = "vpc-fmz6l9nz" + subnet_id = "subnet-g7jhwhi2" + vpc_cidr_block = "10.35.0.0/16" + cidr_block = "10.35.20.0/24" resource_edition = "pro" - resource_node = 4 + resource_node = 100 time_unit = "m" time_span = 1 auto_renew_flag = 1 - deploy_zone = "ap-guangzhou-6" - package_bandwidth = 20 - package_node = 100 + package_bandwidth = 2 } ` diff --git a/tencentcloud/services/bh/resource_tc_dasb_user.go b/tencentcloud/services/bh/resource_tc_dasb_user.go index 1e7e6b5d8c..3c96b788b9 100644 --- a/tencentcloud/services/bh/resource_tc_dasb_user.go +++ b/tencentcloud/services/bh/resource_tc_dasb_user.go @@ -47,16 +47,19 @@ func ResourceTencentCloudDasbUser() *schema.Resource { }, "validate_from": { Optional: true, + Computed: true, Type: schema.TypeString, Description: "User effective time, such as: 2021-09-22T00:00:00+00:00If the effective and expiry time are not filled in, the user will be valid for a long time.", }, "validate_to": { Optional: true, + Computed: true, Type: schema.TypeString, Description: "User expiration time, such as: 2021-09-23T00:00:00+00:00If the effective and expiry time are not filled in, the user will be valid for a long time.", }, "group_id_set": { Optional: true, + Computed: true, Type: schema.TypeSet, Elem: &schema.Schema{Type: schema.TypeInt}, Description: "The set of user group IDs to which it belongs.", diff --git a/tencentcloud/services/bh/resource_tc_dasb_user_group.md b/tencentcloud/services/bh/resource_tc_dasb_user_group.md index 42bf9098af..74a3b54826 100644 --- a/tencentcloud/services/bh/resource_tc_dasb_user_group.md +++ b/tencentcloud/services/bh/resource_tc_dasb_user_group.md @@ -4,7 +4,7 @@ Example Usage ```hcl resource "tencentcloud_dasb_user_group" "example" { - name = "tf_example_update" + name = "tf_example" } ``` @@ -12,7 +12,7 @@ Or ```hcl resource "tencentcloud_dasb_user_group" "example" { - name = "tf_example_update" + name = "tf_example" department_id = "1.2" } ``` diff --git a/tencentcloud/services/bh/resource_tc_dasb_user_group_members.go b/tencentcloud/services/bh/resource_tc_dasb_user_group_members.go index 535f291e35..181d720e2c 100644 --- a/tencentcloud/services/bh/resource_tc_dasb_user_group_members.go +++ b/tencentcloud/services/bh/resource_tc_dasb_user_group_members.go @@ -125,7 +125,8 @@ func resourceTencentCloudDasbUserGroupMembersRead(d *schema.ResourceData, meta i return nil } - _ = d.Set("user_group_id", userGroupId) + userGroupIdInt, _ := strconv.Atoi(userGroupId) + _ = d.Set("user_group_id", userGroupIdInt) _ = d.Set("member_id_set", UserGroupMembers) return nil diff --git a/tencentcloud/services/bh/resource_tc_dasb_user_group_members.md b/tencentcloud/services/bh/resource_tc_dasb_user_group_members.md index 147b40a4a1..7ae65bebd0 100644 --- a/tencentcloud/services/bh/resource_tc_dasb_user_group_members.md +++ b/tencentcloud/services/bh/resource_tc_dasb_user_group_members.md @@ -3,9 +3,21 @@ Provides a resource to create a dasb user_group_members Example Usage ```hcl +resource "tencentcloud_dasb_user" "example" { + user_name = "tf_example" + real_name = "terraform" + phone = "+86|18345678782" + email = "demo@tencent.com" + auth_type = 0 +} + +resource "tencentcloud_dasb_user_group" "example" { + name = "tf_example" +} + resource "tencentcloud_dasb_user_group_members" "example" { - user_group_id = 3 - member_id_set = [1, 2, 3] + user_group_id = tencentcloud_dasb_user_group.example.id + member_id_set = [tencentcloud_dasb_user.example.id] } ``` @@ -14,5 +26,5 @@ Import dasb user_group_members can be imported using the id, e.g. ``` -terraform import tencentcloud_dasb_user_group_members.example 3#1,2,3 +terraform import tencentcloud_dasb_user_group_members.example 3#14 ``` \ No newline at end of file diff --git a/tencentcloud/services/bh/service_tencentcloud_dasb.go b/tencentcloud/services/bh/service_tencentcloud_dasb.go index 3824742390..04e5979426 100644 --- a/tencentcloud/services/bh/service_tencentcloud_dasb.go +++ b/tencentcloud/services/bh/service_tencentcloud_dasb.go @@ -308,6 +308,7 @@ func (me *DasbService) DescribeDasbDeviceGroupMembersById(ctx context.Context, d request := dasb.NewDescribeDeviceGroupMembersRequest() deviceGroupIdInt, _ := strconv.ParseUint(deviceGroupId, 10, 64) request.Id = &deviceGroupIdInt + request.Bound = common.BoolPtr(true) defer func() { if errRet != nil { @@ -378,6 +379,7 @@ func (me *DasbService) DescribeDasbUserGroupMembersById(ctx context.Context, use request := dasb.NewDescribeUserGroupMembersRequest() userGroupIdInt, _ := strconv.ParseUint(userGroupId, 10, 64) request.Id = &userGroupIdInt + request.Bound = common.BoolPtr(true) defer func() { if errRet != nil { diff --git a/tencentcloud/services/cbs/service_tencentcloud_cbs.go b/tencentcloud/services/cbs/service_tencentcloud_cbs.go index 7584545e1e..72dcf7e017 100644 --- a/tencentcloud/services/cbs/service_tencentcloud_cbs.go +++ b/tencentcloud/services/cbs/service_tencentcloud_cbs.go @@ -3,6 +3,7 @@ package cbs import ( "context" "log" + "strings" "sync" tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" @@ -10,6 +11,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" cbs "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cbs/v20170312" + "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/connectivity" "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/ratelimit" @@ -44,14 +46,34 @@ func (me *CbsService) DescribeDiskSetByIds(ctx context.Context, diskSetIds strin } func (me *CbsService) DescribeDiskById(ctx context.Context, diskId string) (disk *cbs.Disk, errRet error) { - disks, err := me.DescribeDiskList(ctx, []*string{&diskId}) + logId := tccommon.GetLogId(ctx) + request := cbs.NewDescribeDisksRequest() + request.DiskIds = common.StringPtrs([]string{diskId}) + request.Limit = helper.IntUint64(100) + ratelimit.Check(request.GetAction()) + + var iacExtInfo connectivity.IacExtInfo + iacExtInfo.InstanceId = diskId + response, err := me.client.UseCbsClient(iacExtInfo).DescribeDisks(request) if err != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", + logId, request.GetAction(), request.ToJsonString(), err.Error()) errRet = err return } - if len(disks) > 0 { - disk = disks[0] + + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", + logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + + if err != nil { + errRet = err + return + } + + if len(response.Response.DiskSet) > 0 { + disk = response.Response.DiskSet[0] } + return } @@ -61,7 +83,14 @@ func (me *CbsService) DescribeDiskList(ctx context.Context, diskIds []*string) ( request.DiskIds = diskIds request.Limit = helper.IntUint64(100) ratelimit.Check(request.GetAction()) - response, err := me.client.UseCbsClient().DescribeDisks(request) + + var iacExtInfo connectivity.IacExtInfo + tmpList := make([]string, len(diskIds)) + for k, v := range diskIds { + tmpList[k] = *v + } + iacExtInfo.InstanceId = strings.Join(tmpList, tccommon.FILED_SP) + response, err := me.client.UseCbsClient(iacExtInfo).DescribeDisks(request) if err != nil { log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", logId, request.GetAction(), request.ToJsonString(), err.Error()) diff --git a/tencentcloud/services/cdb/service_tencentcloud_mysql.go b/tencentcloud/services/cdb/service_tencentcloud_mysql.go index f4c9de53a1..ce39ea5756 100644 --- a/tencentcloud/services/cdb/service_tencentcloud_mysql.go +++ b/tencentcloud/services/cdb/service_tencentcloud_mysql.go @@ -810,7 +810,9 @@ func (me *MysqlService) _innerDescribeDBInstanceById(ctx context.Context, mysqlI } }() ratelimit.Check(request.GetAction()) - response, err := me.client.UseMysqlClient().DescribeDBInstances(request) + var iacExtInfo connectivity.IacExtInfo + iacExtInfo.InstanceId = mysqlId + response, err := me.client.UseMysqlClient(iacExtInfo).DescribeDBInstances(request) if err != nil { errRet = err return diff --git a/tencentcloud/services/cdn/service_tencentcloud_cdn.go b/tencentcloud/services/cdn/service_tencentcloud_cdn.go index 42d4ed34f2..5559f6cf52 100644 --- a/tencentcloud/services/cdn/service_tencentcloud_cdn.go +++ b/tencentcloud/services/cdn/service_tencentcloud_cdn.go @@ -41,7 +41,9 @@ func (me *CdnService) DescribeDomainsConfigByDomain(ctx context.Context, domain request.Filters = append(request.Filters, filter) ratelimit.Check(request.GetAction()) - response, err := me.client.UseCdnClient().DescribeDomainsConfig(request) + var iacExtInfo connectivity.IacExtInfo + iacExtInfo.InstanceId = domain + response, err := me.client.UseCdnClient(iacExtInfo).DescribeDomainsConfig(request) if err != nil { if sdkErr, ok := err.(*errors.TencentCloudSDKError); ok { if sdkErr.Code == CDN_HOST_NOT_FOUND { diff --git a/tencentcloud/services/cfw/service_tencentcloud_cfw.go b/tencentcloud/services/cfw/service_tencentcloud_cfw.go index fd81a52735..95be68859a 100644 --- a/tencentcloud/services/cfw/service_tencentcloud_cfw.go +++ b/tencentcloud/services/cfw/service_tencentcloud_cfw.go @@ -245,8 +245,9 @@ func (me *CfwService) DescribeCfwNatInstanceById(ctx context.Context, natinsId s }() ratelimit.Check(request.GetAction()) - - response, err := me.client.UseCfwClient().DescribeNatFwInstancesInfo(request) + var iacExtInfo connectivity.IacExtInfo + iacExtInfo.InstanceId = natinsId + response, err := me.client.UseCfwClient(iacExtInfo).DescribeNatFwInstancesInfo(request) if err != nil { errRet = err return @@ -442,8 +443,9 @@ func (me *CfwService) DescribeCfwVpcInstanceById(ctx context.Context, fwGroupId }() ratelimit.Check(request.GetAction()) - - response, err := me.client.UseCfwClient().DescribeFwGroupInstanceInfo(request) + var iacExtInfo connectivity.IacExtInfo + iacExtInfo.InstanceId = fwGroupId + response, err := me.client.UseCfwClient(iacExtInfo).DescribeFwGroupInstanceInfo(request) if err != nil { errRet = err return diff --git a/tencentcloud/services/ckafka/data_source_tc_ckafka_topics.md b/tencentcloud/services/ckafka/data_source_tc_ckafka_topics.md index bf2061e6f9..12a89b2726 100644 --- a/tencentcloud/services/ckafka/data_source_tc_ckafka_topics.md +++ b/tencentcloud/services/ckafka/data_source_tc_ckafka_topics.md @@ -3,19 +3,8 @@ Use this data source to query detailed information of ckafka topic. Example Usage ```hcl -resource "tencentcloud_ckafka_topic" "foo" { - instance_id = "ckafka-f9ife4zz" - topic_name = "example" - note = "topic note" - replica_num = 2 - partition_num = 1 - enable_white_list = true - ip_white_list = ["ip1","ip2"] - clean_up_policy = "delete" - sync_replica_min_num = 1 - unclean_leader_election_enable = false - segment = 3600000 - retention = 60000 - max_message_bytes = 1024 +data "tencentcloud_ckafka_topics" "example" { + instance_id = "ckafka-vv7wp5nx" + topic_name = "tf_example" } ``` \ No newline at end of file diff --git a/tencentcloud/services/ckafka/service_tencentcloud_ckafka.go b/tencentcloud/services/ckafka/service_tencentcloud_ckafka.go index bbe1da94e3..2792750c4d 100644 --- a/tencentcloud/services/ckafka/service_tencentcloud_ckafka.go +++ b/tencentcloud/services/ckafka/service_tencentcloud_ckafka.go @@ -89,8 +89,10 @@ func (me *CkafkaService) DescribeCkafkaInstanceById(ctx context.Context, } }() request.InstanceId = &instanceId + var iacExtInfo connectivity.IacExtInfo + iacExtInfo.InstanceId = instanceId if err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { - result, err := me.client.UseCkafkaClient().DescribeInstancesDetail(request) + result, err := me.client.UseCkafkaClient(iacExtInfo).DescribeInstancesDetail(request) if err != nil { return tccommon.RetryError(err) } diff --git a/tencentcloud/services/clb/service_tencentcloud_clb.go b/tencentcloud/services/clb/service_tencentcloud_clb.go index c62f9c2ed3..6ef4bdd145 100644 --- a/tencentcloud/services/clb/service_tencentcloud_clb.go +++ b/tencentcloud/services/clb/service_tencentcloud_clb.go @@ -56,7 +56,9 @@ func (me *ClbService) DescribeLoadBalancerById(ctx context.Context, clbId string request := clb.NewDescribeLoadBalancersRequest() request.LoadBalancerIds = []*string{&clbId} ratelimit.Check(request.GetAction()) - response, err := me.client.UseClbClient().DescribeLoadBalancers(request) + var iacExtInfo connectivity.IacExtInfo + iacExtInfo.InstanceId = clbId + response, err := me.client.UseClbClient(iacExtInfo).DescribeLoadBalancers(request) if err != nil { errRet = errors.WithStack(err) return diff --git a/tencentcloud/services/cls/service_tencentcloud_cls.go b/tencentcloud/services/cls/service_tencentcloud_cls.go index dcf454915d..2027b9ba1d 100644 --- a/tencentcloud/services/cls/service_tencentcloud_cls.go +++ b/tencentcloud/services/cls/service_tencentcloud_cls.go @@ -48,12 +48,14 @@ func (me *ClsService) DescribeClsLogset(ctx context.Context, logsetId string) (l var offset int64 = 0 var pageSize int64 = 100 instances := make([]*cls.LogsetInfo, 0) + var iacExtInfo connectivity.IacExtInfo + iacExtInfo.InstanceId = logsetId for { request.Offset = &offset request.Limit = &pageSize ratelimit.Check(request.GetAction()) - response, err := me.client.UseClsClient().DescribeLogsets(request) + response, err := me.client.UseClsClient(iacExtInfo).DescribeLogsets(request) if err != nil { log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", logId, request.GetAction(), request.ToJsonString(), err.Error()) @@ -230,6 +232,8 @@ func (me *ClsService) DescribeClsTopicById(ctx context.Context, topicId string) }, } ratelimit.Check(request.GetAction()) + var iacExtInfo connectivity.IacExtInfo + iacExtInfo.InstanceId = topicId var ( offset int64 = 0 pageSize int64 = 100 @@ -240,7 +244,7 @@ func (me *ClsService) DescribeClsTopicById(ctx context.Context, topicId string) request.Offset = &offset request.Limit = &pageSize ratelimit.Check(request.GetAction()) - response, err := me.client.UseClsClient().DescribeTopics(request) + response, err := me.client.UseClsClient(iacExtInfo).DescribeTopics(request) if err != nil { log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", logId, request.GetAction(), request.ToJsonString(), err.Error()) diff --git a/tencentcloud/services/cvm/resource_tc_instance.go b/tencentcloud/services/cvm/resource_tc_instance.go index f994d7282f..67b1e2ebaa 100644 --- a/tencentcloud/services/cvm/resource_tc_instance.go +++ b/tencentcloud/services/cvm/resource_tc_instance.go @@ -394,6 +394,11 @@ func ResourceTencentCloudInstance() *schema.Resource { Computed: true, Description: "Public IP of the instance.", }, + "uuid": { + Type: schema.TypeString, + Computed: true, + Description: "Globally unique ID of the instance.", + }, "create_time": { Type: schema.TypeString, Computed: true, @@ -739,21 +744,21 @@ func resourceTencentCloudInstanceRead(d *schema.ResourceData, meta interface{}) defer tccommon.LogElapsed("resource.tencentcloud_instance.read")() defer tccommon.InconsistentCheck(d, meta)() - logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + var ( + logId = tccommon.GetLogId(tccommon.ContextNil) + ctx = context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + client = meta.(tccommon.ProviderMeta).GetAPIV3Conn() + cvmService = CvmService{client: client} + cbsService = svccbs.NewCbsService(client) + instanceId = d.Id() + ) - instanceId := d.Id() forceDelete := false if v, ok := d.GetOkExists("force_delete"); ok { forceDelete = v.(bool) _ = d.Set("force_delete", forceDelete) } - client := meta.(tccommon.ProviderMeta).GetAPIV3Conn() - cvmService := CvmService{ - client: client, - } - cbsService := svccbs.NewCbsService(client) var instance *cvm.Instance var errRet error err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { @@ -761,14 +766,18 @@ func resourceTencentCloudInstanceRead(d *schema.ResourceData, meta interface{}) if errRet != nil { return tccommon.RetryError(errRet, tccommon.InternalError) } + if instance != nil && instance.LatestOperationState != nil && *instance.LatestOperationState == "OPERATING" { return resource.RetryableError(fmt.Errorf("waiting for instance %s operation", *instance.InstanceId)) } + return nil }) + if err != nil { return err } + if instance == nil || *instance.InstanceState == CVM_STATUS_LAUNCH_FAILED { d.SetId("") log.Printf("[CRITAL]instance %s not exist or launch failed", instanceId) @@ -821,6 +830,10 @@ func resourceTencentCloudInstanceRead(d *schema.ResourceData, meta interface{}) _ = d.Set("cam_role_name", instance.CamRoleName) _ = d.Set("disable_api_termination", instance.DisableApiTermination) + if instance.Uuid != nil { + _ = d.Set("uuid", instance.Uuid) + } + if *instance.InstanceChargeType == CVM_CHARGE_TYPE_CDHPAID { _ = d.Set("cdh_instance_type", instance.InstanceType) } diff --git a/tencentcloud/services/cvm/service_tencentcloud_cvm.go b/tencentcloud/services/cvm/service_tencentcloud_cvm.go index 607b57fed6..071d5d8f1f 100644 --- a/tencentcloud/services/cvm/service_tencentcloud_cvm.go +++ b/tencentcloud/services/cvm/service_tencentcloud_cvm.go @@ -69,8 +69,10 @@ func (me *CvmService) DescribeInstanceById(ctx context.Context, instanceId strin request := cvm.NewDescribeInstancesRequest() request.InstanceIds = []*string{&instanceId} + var iacExtInfo connectivity.IacExtInfo + iacExtInfo.InstanceId = instanceId ratelimit.Check(request.GetAction()) - response, err := me.client.UseCvmClient().DescribeInstances(request) + response, err := me.client.UseCvmClient(iacExtInfo).DescribeInstances(request) if err != nil { log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", logId, request.GetAction(), request.ToJsonString(), err.Error()) diff --git a/tencentcloud/services/es/service_tencentcloud_elasticsearch.go b/tencentcloud/services/es/service_tencentcloud_elasticsearch.go index 044c337a56..cd06efca8a 100644 --- a/tencentcloud/services/es/service_tencentcloud_elasticsearch.go +++ b/tencentcloud/services/es/service_tencentcloud_elasticsearch.go @@ -30,7 +30,9 @@ func (me *ElasticsearchService) DescribeInstanceById(ctx context.Context, instan request.InstanceIds = []*string{&instanceId} ratelimit.Check(request.GetAction()) - response, err := me.client.UseEsClient().DescribeInstances(request) + var iacExtInfo connectivity.IacExtInfo + iacExtInfo.InstanceId = instanceId + response, err := me.client.UseEsClient(iacExtInfo).DescribeInstances(request) if err != nil { log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", logId, request.GetAction(), request.ToJsonString(), err.Error()) diff --git a/tencentcloud/services/gaap/service_tencentcloud_gaap.go b/tencentcloud/services/gaap/service_tencentcloud_gaap.go index 6a5aba208e..d4a5478257 100644 --- a/tencentcloud/services/gaap/service_tencentcloud_gaap.go +++ b/tencentcloud/services/gaap/service_tencentcloud_gaap.go @@ -8,6 +8,7 @@ import ( "sort" "strconv" "strings" + "time" tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" @@ -586,6 +587,7 @@ func (me *GaapService) DescribeProxies( logId := tccommon.GetLogId(ctx) request := gaap.NewDescribeProxiesRequest() + response := gaap.NewDescribeProxiesResponse() if len(ids) > 0 { request.ProxyIds = common.StringPtrs(ids) } @@ -624,8 +626,15 @@ func (me *GaapService) DescribeProxies( if err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { ratelimit.Check(request.GetAction()) + if len(ids) > 0 { + var iacExtInfo connectivity.IacExtInfo + tmpIds := strings.Join(ids, tccommon.FILED_SP) + iacExtInfo.InstanceId = tmpIds + response, err = me.client.UseGaapClient(iacExtInfo).DescribeProxies(request) + } else { + response, err = me.client.UseGaapClient().DescribeProxies(request) + } - response, err := me.client.UseGaapClient().DescribeProxies(request) if err != nil { count = 0 @@ -733,6 +742,8 @@ func (me *GaapService) ModifyProxyConfiguration(ctx context.Context, id string, return err } + time.Sleep(5 * time.Second) + describeRequest := gaap.NewDescribeProxiesRequest() describeRequest.ProxyIds = []*string{&id} diff --git a/tencentcloud/services/lighthouse/service_tencentcloud_lighthouse.go b/tencentcloud/services/lighthouse/service_tencentcloud_lighthouse.go index 340be3c5d5..6a90694e00 100644 --- a/tencentcloud/services/lighthouse/service_tencentcloud_lighthouse.go +++ b/tencentcloud/services/lighthouse/service_tencentcloud_lighthouse.go @@ -40,6 +40,8 @@ func (me *LightHouseService) DescribeLighthouseInstanceById(ctx context.Context, request.InstanceIds = append(request.InstanceIds, helper.String(instanceId)) ratelimit.Check(request.GetAction()) + var iacExtInfo connectivity.IacExtInfo + iacExtInfo.InstanceId = instanceId var offset int64 = 0 var pageSize int64 = 100 @@ -49,7 +51,7 @@ func (me *LightHouseService) DescribeLighthouseInstanceById(ctx context.Context, request.Offset = &offset request.Limit = &pageSize ratelimit.Check(request.GetAction()) - response, err := me.client.UseLighthouseClient().DescribeInstances(request) + response, err := me.client.UseLighthouseClient(iacExtInfo).DescribeInstances(request) if err != nil { log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", logId, request.GetAction(), request.ToJsonString(), err.Error()) diff --git a/tencentcloud/services/mariadb/data_source_tc_mariadb_db_instances.go b/tencentcloud/services/mariadb/data_source_tc_mariadb_db_instances.go index 6697031159..6dd4c41834 100644 --- a/tencentcloud/services/mariadb/data_source_tc_mariadb_db_instances.go +++ b/tencentcloud/services/mariadb/data_source_tc_mariadb_db_instances.go @@ -110,6 +110,31 @@ func DataSourceTencentCloudMariadbDbInstances() *schema.Resource { Computed: true, Description: "db version id.", }, + "vip": { + Type: schema.TypeString, + Computed: true, + Description: "Intranet IP address.", + }, + "vport": { + Type: schema.TypeInt, + Computed: true, + Description: "Intranet port.", + }, + "internet_domain": { + Type: schema.TypeString, + Computed: true, + Description: "Public network access domain name.", + }, + "internet_ip": { + Type: schema.TypeString, + Computed: true, + Description: "Public IP address.", + }, + "internet_port": { + Type: schema.TypeInt, + Computed: true, + Description: "Public network port.", + }, "resource_tags": { Type: schema.TypeList, Computed: true, @@ -231,6 +256,21 @@ func dataSourceTencentCloudMariadbDbInstancesRead(d *schema.ResourceData, meta i if instance.DbVersionId != nil { instanceMap["db_version_id"] = instance.DbVersionId } + if instance.Vip != nil { + instanceMap["vip"] = instance.Vip + } + if instance.Vport != nil { + instanceMap["vport"] = instance.Vport + } + if instance.WanDomain != nil { + instanceMap["internet_domain"] = instance.WanDomain + } + if instance.WanVip != nil { + instanceMap["internet_ip"] = instance.WanVip + } + if instance.WanPort != nil { + instanceMap["internet_port"] = instance.WanPort + } if instance.ResourceTags != nil { resourceTagsList := []interface{}{} for _, resourceTags := range instance.ResourceTags { diff --git a/tencentcloud/services/mariadb/data_source_tc_mariadb_db_instances_test.go b/tencentcloud/services/mariadb/data_source_tc_mariadb_db_instances_test.go index d6faae65b2..cbe8cd48a2 100644 --- a/tencentcloud/services/mariadb/data_source_tc_mariadb_db_instances_test.go +++ b/tencentcloud/services/mariadb/data_source_tc_mariadb_db_instances_test.go @@ -20,14 +20,29 @@ func TestAccTencentCloudMariadbDbInstancesDataSource(t *testing.T) { Config: testAccDataSourceMariadbDbInstances, Check: resource.ComposeTestCheckFunc( tcacctest.AccCheckTencentCloudDataSourceID("data.tencentcloud_mariadb_db_instances.db_instances"), + resource.TestCheckResourceAttrSet("data.tencentcloud_mariadb_db_instances.db_instances", "instances.#"), + resource.TestCheckResourceAttrSet("data.tencentcloud_mariadb_db_instances.db_instances", "instances.0.instance_id"), + resource.TestCheckResourceAttrSet("data.tencentcloud_mariadb_db_instances.db_instances", "instances.0.instance_name"), + resource.TestCheckResourceAttrSet("data.tencentcloud_mariadb_db_instances.db_instances", "instances.0.project_id"), + resource.TestCheckResourceAttrSet("data.tencentcloud_mariadb_db_instances.db_instances", "instances.0.region"), + resource.TestCheckResourceAttrSet("data.tencentcloud_mariadb_db_instances.db_instances", "instances.0.zone"), + resource.TestCheckResourceAttrSet("data.tencentcloud_mariadb_db_instances.db_instances", "instances.0.memory"), + resource.TestCheckResourceAttrSet("data.tencentcloud_mariadb_db_instances.db_instances", "instances.0.storage"), + resource.TestCheckResourceAttrSet("data.tencentcloud_mariadb_db_instances.db_instances", "instances.0.vpc_id"), + resource.TestCheckResourceAttrSet("data.tencentcloud_mariadb_db_instances.db_instances", "instances.0.subnet_id"), + resource.TestCheckResourceAttrSet("data.tencentcloud_mariadb_db_instances.db_instances", "instances.0.db_version_id"), + resource.TestCheckResourceAttrSet("data.tencentcloud_mariadb_db_instances.db_instances", "instances.0.vip"), + resource.TestCheckResourceAttrSet("data.tencentcloud_mariadb_db_instances.db_instances", "instances.0.vport"), ), }, }, }) } -const testAccDataSourceMariadbDbInstances = ` +const testAccDataSourceMariadbDbInstances = testAccMariadbInstance + ` -data "tencentcloud_mariadb_db_instances" "db_instances" {} +data "tencentcloud_mariadb_db_instances" "db_instances" { + depends_on = [ tencentcloud_mariadb_instance.instance ] +} ` diff --git a/tencentcloud/services/mariadb/service_tencentcloud_mariadb.go b/tencentcloud/services/mariadb/service_tencentcloud_mariadb.go index ecc346ae25..c3644d26ba 100644 --- a/tencentcloud/services/mariadb/service_tencentcloud_mariadb.go +++ b/tencentcloud/services/mariadb/service_tencentcloud_mariadb.go @@ -755,8 +755,9 @@ func (me *MariadbService) DescribeMariadbDbInstanceDetail(ctx context.Context, i }() request.InstanceId = &instanceId - - response, err := me.client.UseMariadbClient().DescribeDBInstanceDetail(request) + var iacExtInfo connectivity.IacExtInfo + iacExtInfo.InstanceId = instanceId + response, err := me.client.UseMariadbClient(iacExtInfo).DescribeDBInstanceDetail(request) if err != nil { log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", logId, request.GetAction(), request.ToJsonString(), err.Error()) @@ -1125,8 +1126,9 @@ func (me *MariadbService) DescribeMariadbInstanceById(ctx context.Context, insta }() ratelimit.Check(request.GetAction()) - - response, err := me.client.UseMariadbClient().DescribeDBInstances(request) + var iacExtInfo connectivity.IacExtInfo + iacExtInfo.InstanceId = instanceId + response, err := me.client.UseMariadbClient(iacExtInfo).DescribeDBInstances(request) if err != nil { errRet = err return diff --git a/tencentcloud/services/mongodb/service_tencentcloud_mongodb.go b/tencentcloud/services/mongodb/service_tencentcloud_mongodb.go index 6e05ac289a..b3df2e2aad 100644 --- a/tencentcloud/services/mongodb/service_tencentcloud_mongodb.go +++ b/tencentcloud/services/mongodb/service_tencentcloud_mongodb.go @@ -29,10 +29,13 @@ func (me *MongodbService) DescribeInstanceById(ctx context.Context, instanceId s logId := tccommon.GetLogId(ctx) request := mongodb.NewDescribeDBInstancesRequest() request.InstanceIds = []*string{&instanceId} + + var iacExtInfo connectivity.IacExtInfo + iacExtInfo.InstanceId = instanceId var response *mongodb.DescribeDBInstancesResponse err := resource.Retry(20*tccommon.ReadRetryTimeout, func() *resource.RetryError { ratelimit.Check(request.GetAction()) - result, e := me.client.UseMongodbClient().DescribeDBInstances(request) + result, e := me.client.UseMongodbClient(iacExtInfo).DescribeDBInstances(request) if e != nil { return resource.NonRetryableError(e) } diff --git a/tencentcloud/services/postgresql/service_tencentcloud_postgresql.go b/tencentcloud/services/postgresql/service_tencentcloud_postgresql.go index 81c2159eb2..b6a01aef25 100644 --- a/tencentcloud/services/postgresql/service_tencentcloud_postgresql.go +++ b/tencentcloud/services/postgresql/service_tencentcloud_postgresql.go @@ -440,7 +440,9 @@ func (me *PostgresqlService) DescribePostgresqlInstanceById(ctx context.Context, request.DBInstanceId = &instanceId ratelimit.Check(request.GetAction()) - response, err := me.client.UsePostgresqlClient().DescribeDBInstanceAttribute(request) + var iacExtInfo connectivity.IacExtInfo + iacExtInfo.InstanceId = instanceId + response, err := me.client.UsePostgresqlClient(iacExtInfo).DescribeDBInstanceAttribute(request) if err != nil { errRet = err return diff --git a/tencentcloud/services/privatedns/resource_tc_private_dns_record.go b/tencentcloud/services/privatedns/resource_tc_private_dns_record.go index d9f3945e92..4737f3b9e4 100644 --- a/tencentcloud/services/privatedns/resource_tc_private_dns_record.go +++ b/tencentcloud/services/privatedns/resource_tc_private_dns_record.go @@ -29,6 +29,7 @@ func ResourceTencentCloudPrivateDnsRecord() *schema.Resource { "zone_id": { Type: schema.TypeString, Required: true, + ForceNew: true, Description: "Private domain ID.", }, "record_type": { @@ -42,10 +43,9 @@ func ResourceTencentCloudPrivateDnsRecord() *schema.Resource { Description: "Subdomain, such as \"www\", \"m\", and \"@\".", }, "record_value": { - Type: schema.TypeString, - Required: true, - Description: "Record value, such as IP: 192.168.10.2," + - " CNAME: cname.qcloud.com, and MX: mail.qcloud.com..", + Type: schema.TypeString, + Required: true, + Description: "Record value, such as IP: 192.168.10.2, CNAME: cname.qcloud.com, and MX: mail.qcloud.com.", }, "weight": { Type: schema.TypeInt, @@ -59,10 +59,10 @@ func ResourceTencentCloudPrivateDnsRecord() *schema.Resource { " Valid values: 5, 10, 15, 20, 30, 40, 50.", }, "ttl": { - Type: schema.TypeInt, - Optional: true, - Description: "Record cache time. The smaller the value, the faster the record will take effect." + - " Value range: 1~86400s.", + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Record cache time. The smaller the value, the faster the record will take effect. Value range: 1~86400s.", }, }, } @@ -71,42 +71,64 @@ func ResourceTencentCloudPrivateDnsRecord() *schema.Resource { func resourceTencentCloudDPrivateDnsRecordCreate(d *schema.ResourceData, meta interface{}) error { defer tccommon.LogElapsed("resource.tencentcloud_private_dns_record.create")() - logId := tccommon.GetLogId(tccommon.ContextNil) + var ( + logId = tccommon.GetLogId(tccommon.ContextNil) + request = privatedns.NewCreatePrivateZoneRecordRequest() + response = privatedns.NewCreatePrivateZoneRecordResponse() + zoneId string + ) - request := privatedns.NewCreatePrivateZoneRecordRequest() - - zoneId := d.Get("zone_id").(string) - request.ZoneId = &zoneId + if v, ok := d.GetOk("zone_id"); ok { + request.ZoneId = helper.String(v.(string)) + zoneId = v.(string) + } - recordType := d.Get("record_type").(string) - request.RecordType = &recordType + if v, ok := d.GetOk("record_type"); ok { + request.RecordType = helper.String(v.(string)) + } - subDomain := d.Get("sub_domain").(string) - request.SubDomain = &subDomain + if v, ok := d.GetOk("sub_domain"); ok { + request.SubDomain = helper.String(v.(string)) + } - recordValue := d.Get("record_value").(string) - request.RecordValue = &recordValue + if v, ok := d.GetOk("record_value"); ok { + request.RecordValue = helper.String(v.(string)) + } - if v, ok := d.GetOk("weight"); ok { + if v, ok := d.GetOkExists("weight"); ok { request.Weight = helper.Int64(int64(v.(int))) } - if v, ok := d.GetOk("mx"); ok { + if v, ok := d.GetOkExists("mx"); ok { request.MX = helper.Int64(int64(v.(int))) } - if v, ok := d.GetOk("ttl"); ok { + + if v, ok := d.GetOkExists("ttl"); ok { request.TTL = helper.Int64(int64(v.(int))) } - result, err := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UsePrivateDnsClient().CreatePrivateZoneRecord(request) + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UsePrivateDnsClient().CreatePrivateZoneRecord(request) + if e != nil { + return tccommon.RetryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) + } + + if result == nil { + e = fmt.Errorf("create PrivateDns record failed") + return resource.NonRetryableError(e) + } + + response = result + return nil + }) if err != nil { log.Printf("[CRITAL]%s create PrivateDns record failed, reason:%s\n", logId, err.Error()) return err } - response := result - recordId := *response.Response.RecordId d.SetId(strings.Join([]string{zoneId, recordId}, tccommon.FILED_SP)) @@ -117,17 +139,17 @@ func resourceTencentCloudDPrivateDnsRecordRead(d *schema.ResourceData, meta inte defer tccommon.LogElapsed("resource.tencentcloud_private_dns_zone.read")() defer tccommon.InconsistentCheck(d, meta)() - logId := tccommon.GetLogId(tccommon.ContextNil) - ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - - service := PrivateDnsService{ - client: meta.(tccommon.ProviderMeta).GetAPIV3Conn(), - } + var ( + logId = tccommon.GetLogId(tccommon.ContextNil) + ctx = context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + service = PrivateDnsService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + ) idSplit := strings.Split(d.Id(), tccommon.FILED_SP) if len(idSplit) != 2 { return fmt.Errorf("record id strategy is can't read, id is borken, id is %s", d.Id()) } + zoneId := idSplit[0] recordId := idSplit[1] @@ -169,73 +191,57 @@ func resourceTencentCloudDPrivateDnsRecordRead(d *schema.ResourceData, meta inte func resourceTencentCloudDPrivateDnsRecordUpdate(d *schema.ResourceData, meta interface{}) error { defer tccommon.LogElapsed("resource.tencentcloud_private_dns_record.update")() + var ( + logId = tccommon.GetLogId(tccommon.ContextNil) + request = privatedns.NewModifyPrivateZoneRecordRequest() + ) + idSplit := strings.Split(d.Id(), tccommon.FILED_SP) if len(idSplit) != 2 { return fmt.Errorf("record id strategy is can't read, id is borken, id is %s", d.Id()) } - logId := tccommon.GetLogId(tccommon.ContextNil) + zoneId := idSplit[0] recordId := idSplit[1] - request := privatedns.NewModifyPrivateZoneRecordRequest() request.ZoneId = helper.String(zoneId) request.RecordId = helper.String(recordId) - - needModify := false - if d.HasChange("record_type") { - needModify = true + if v, ok := d.GetOk("record_type"); ok { + request.RecordType = helper.String(v.(string)) } - if d.HasChange("sub_domain") { - needModify = true + if v, ok := d.GetOk("sub_domain"); ok { + request.SubDomain = helper.String(v.(string)) } - if d.HasChange("record_value") { - needModify = true + if v, ok := d.GetOk("record_value"); ok { + request.RecordValue = helper.String(v.(string)) } - if d.HasChange("weight") { - needModify = true - if v, ok := d.GetOk("weight"); ok { - request.Weight = helper.Int64(int64(v.(int))) - } + if v, ok := d.GetOk("weight"); ok { + request.Weight = helper.Int64(int64(v.(int))) } - if d.HasChange("mx") { - needModify = true - if v, ok := d.GetOk("mx"); ok { - request.MX = helper.Int64(int64(v.(int))) - } + if v, ok := d.GetOk("mx"); ok { + request.MX = helper.Int64(int64(v.(int))) } - if d.HasChange("ttl") { - needModify = true - if v, ok := d.GetOk("ttl"); ok { - request.TTL = helper.Int64(int64(v.(int))) - } + if v, ok := d.GetOk("ttl"); ok { + request.TTL = helper.Int64(int64(v.(int))) } - if needModify { - if v, ok := d.GetOk("record_type"); ok { - request.RecordType = helper.String(v.(string)) - } - if v, ok := d.GetOk("sub_domain"); ok { - request.SubDomain = helper.String(v.(string)) - } - if v, ok := d.GetOk("record_value"); ok { - request.RecordValue = helper.String(v.(string)) - } - err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - _, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UsePrivateDnsClient().ModifyPrivateZoneRecord(request) - if e != nil { - return tccommon.RetryError(e) - } - return nil - }) - if err != nil { - log.Printf("[CRITAL]%s modify privateDns record info failed, reason:%s\n", logId, err.Error()) - return err + err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { + _, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UsePrivateDnsClient().ModifyPrivateZoneRecord(request) + if e != nil { + return tccommon.RetryError(e) } + + return nil + }) + + if err != nil { + log.Printf("[CRITAL]%s modify privateDns record info failed, reason:%s\n", logId, err.Error()) + return err } return resourceTencentCloudDPrivateDnsRecordRead(d, meta) @@ -244,21 +250,22 @@ func resourceTencentCloudDPrivateDnsRecordUpdate(d *schema.ResourceData, meta in func resourceTencentCloudDPrivateDnsRecordDelete(d *schema.ResourceData, meta interface{}) error { defer tccommon.LogElapsed("resource.tencentcloud_private_dns_record.delete")() - logId := tccommon.GetLogId(tccommon.ContextNil) + var ( + logId = tccommon.GetLogId(tccommon.ContextNil) + request = privatedns.NewDescribePrivateZoneRequest() + ) idSplit := strings.Split(d.Id(), tccommon.FILED_SP) if len(idSplit) != 2 { return fmt.Errorf("record id strategy is can't read, id is borken, id is %s", d.Id()) } + zoneId := idSplit[0] recordId := idSplit[1] // unbind - request := privatedns.NewDescribePrivateZoneRequest() - request.ZoneId = helper.String(zoneId) - var response *privatedns.DescribePrivateZoneResponse - + request.ZoneId = helper.String(zoneId) err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UsePrivateDnsClient().DescribePrivateZone(request) if e != nil { @@ -268,6 +275,7 @@ func resourceTencentCloudDPrivateDnsRecordDelete(d *schema.ResourceData, meta in response = result return nil }) + if err != nil { log.Printf("[CRITAL]%s read private dns failed, reason:%s\n", logId, err.Error()) return err @@ -287,8 +295,10 @@ func resourceTencentCloudDPrivateDnsRecordDelete(d *schema.ResourceData, meta in if e != nil { return tccommon.RetryError(e) } + return nil }) + if err != nil { log.Printf("[CRITAL]%s unbind privateDns zone vpc failed, reason:%s\n", logId, err.Error()) return err @@ -304,8 +314,10 @@ func resourceTencentCloudDPrivateDnsRecordDelete(d *schema.ResourceData, meta in if e != nil { return tccommon.RetryError(e) } + return nil }) + if err != nil { log.Printf("[CRITAL]%s delete privateDns record failed, reason:%s\n", logId, err.Error()) return err @@ -333,8 +345,10 @@ func resourceTencentCloudDPrivateDnsRecordDelete(d *schema.ResourceData, meta in if e != nil { return tccommon.RetryError(e) } + return nil }) + if err != nil { log.Printf("[CRITAL]%s rebind privateDns zone vpc failed, reason:%s\n", logId, err.Error()) return err diff --git a/tencentcloud/services/privatedns/resource_tc_private_dns_record.md b/tencentcloud/services/privatedns/resource_tc_private_dns_record.md index 8d354a0ef5..1614929111 100644 --- a/tencentcloud/services/privatedns/resource_tc_private_dns_record.md +++ b/tencentcloud/services/privatedns/resource_tc_private_dns_record.md @@ -3,8 +3,30 @@ Provide a resource to create a Private Dns Record. Example Usage ```hcl -resource "tencentcloud_private_dns_record" "foo" { - zone_id = "zone-rqndjnki" +resource "tencentcloud_vpc" "vpc" { + name = "vpc-example" + cidr_block = "10.0.0.0/16" +} + +resource "tencentcloud_private_dns_zone" "example" { + domain = "domain.com" + remark = "remark." + + vpc_set { + region = "ap-guangzhou" + uniq_vpc_id = tencentcloud_vpc.vpc.id + } + + dns_forward_status = "DISABLED" + cname_speedup_status = "ENABLED" + + tags = { + createdBy : "terraform" + } +} + +resource "tencentcloud_private_dns_record" "example" { + zone_id = tencentcloud_private_dns_zone.example.id record_type = "A" record_value = "192.168.1.2" sub_domain = "www" @@ -19,5 +41,5 @@ Import Private Dns Record can be imported, e.g. ``` -$ terraform import tencentcloud_private_dns_zone.foo zone_id#record_id +$ terraform import tencentcloud_private_dns_record.example zone-iza3a33s#1983030 ``` \ No newline at end of file diff --git a/tencentcloud/services/privatedns/resource_tc_private_dns_record_test.go b/tencentcloud/services/privatedns/resource_tc_private_dns_record_test.go index a979625203..438e9cc5f1 100644 --- a/tencentcloud/services/privatedns/resource_tc_private_dns_record_test.go +++ b/tencentcloud/services/privatedns/resource_tc_private_dns_record_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) +// go test -i; go test -test.run TestAccTencentCloudPrivateDnsRecord_basic -v func TestAccTencentCloudPrivateDnsRecord_basic(t *testing.T) { t.Parallel() @@ -16,37 +17,102 @@ func TestAccTencentCloudPrivateDnsRecord_basic(t *testing.T) { Providers: tcacctest.AccProviders, Steps: []resource.TestStep{ { - Config: testAccPrivateDnsRecord_basic, + Config: testAccPrivateDnsRecord, Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("tencentcloud_private_dns_record.record", "weight", "1"), + resource.TestCheckResourceAttrSet("tencentcloud_private_dns_record.example", "zone_id"), + resource.TestCheckResourceAttr("tencentcloud_private_dns_record.example", "record_type", "A"), + resource.TestCheckResourceAttr("tencentcloud_private_dns_record.example", "record_value", "192.168.1.2"), + resource.TestCheckResourceAttr("tencentcloud_private_dns_record.example", "sub_domain", "www"), + resource.TestCheckResourceAttrSet("tencentcloud_private_dns_record.example", "ttl"), + resource.TestCheckResourceAttrSet("tencentcloud_private_dns_record.example", "weight"), + resource.TestCheckResourceAttrSet("tencentcloud_private_dns_record.example", "mx"), ), }, { - ResourceName: "tencentcloud_private_dns_record.record", + ResourceName: "tencentcloud_private_dns_record.example", ImportState: true, ImportStateVerify: true, }, + { + Config: testAccPrivateDnsRecordUpdate, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("tencentcloud_private_dns_record.example", "zone_id"), + resource.TestCheckResourceAttr("tencentcloud_private_dns_record.example", "record_type", "A"), + resource.TestCheckResourceAttr("tencentcloud_private_dns_record.example", "record_value", "192.168.1.3"), + resource.TestCheckResourceAttr("tencentcloud_private_dns_record.example", "sub_domain", "www"), + resource.TestCheckResourceAttrSet("tencentcloud_private_dns_record.example", "ttl"), + resource.TestCheckResourceAttrSet("tencentcloud_private_dns_record.example", "weight"), + resource.TestCheckResourceAttrSet("tencentcloud_private_dns_record.example", "mx"), + ), + }, }, }) } -const testAccPrivateDnsRecord_basic = tcacctest.DefaultInstanceVariable + ` -resource "tencentcloud_private_dns_zone" "zone" { - dns_forward_status = "DISABLED" - domain = "domain.com" - remark = "test_record" +const testAccPrivateDnsRecord = ` +resource "tencentcloud_vpc" "vpc" { + name = "vpc-example" + cidr_block = "10.0.0.0/16" +} + +resource "tencentcloud_private_dns_zone" "example" { + domain = "domain.com" + remark = "remark." + + vpc_set { + region = "ap-guangzhou" + uniq_vpc_id = tencentcloud_vpc.vpc.id + } + + dns_forward_status = "DISABLED" + cname_speedup_status = "ENABLED" + tags = { - "created-by" : "terraform", + createdBy : "terraform" } } -resource "tencentcloud_private_dns_record" "record" { - mx = 0 +resource "tencentcloud_private_dns_record" "example" { + zone_id = tencentcloud_private_dns_zone.example.id record_type = "A" record_value = "192.168.1.2" sub_domain = "www" ttl = 300 weight = 1 - zone_id = tencentcloud_private_dns_zone.zone.id + mx = 0 +} +` + +const testAccPrivateDnsRecordUpdate = ` +resource "tencentcloud_vpc" "vpc" { + name = "vpc-example" + cidr_block = "10.0.0.0/16" +} + +resource "tencentcloud_private_dns_zone" "example" { + domain = "domain.com" + remark = "remark." + + vpc_set { + region = "ap-guangzhou" + uniq_vpc_id = tencentcloud_vpc.vpc.id + } + + dns_forward_status = "DISABLED" + cname_speedup_status = "ENABLED" + + tags = { + createdBy : "terraform" + } +} + +resource "tencentcloud_private_dns_record" "example" { + zone_id = tencentcloud_private_dns_zone.example.id + record_type = "A" + record_value = "192.168.1.3" + sub_domain = "www" + ttl = 300 + weight = 1 + mx = 0 } ` diff --git a/tencentcloud/services/privatedns/resource_tc_private_dns_zone.go b/tencentcloud/services/privatedns/resource_tc_private_dns_zone.go index 3c19b63176..897d68132b 100644 --- a/tencentcloud/services/privatedns/resource_tc_private_dns_zone.go +++ b/tencentcloud/services/privatedns/resource_tc_private_dns_zone.go @@ -6,6 +6,7 @@ import ( "log" tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/connectivity" svctag "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/services/tag" "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" @@ -256,9 +257,10 @@ func resourceTencentCloudDPrivateDnsZoneRead(d *schema.ResourceData, meta interf ) request.ZoneId = &id - + var iacExtInfo connectivity.IacExtInfo + iacExtInfo.InstanceId = id err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UsePrivateDnsClient().DescribePrivateZone(request) + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UsePrivateDnsClient(iacExtInfo).DescribePrivateZone(request) if e != nil { return tccommon.RetryError(e) } diff --git a/tencentcloud/services/privatedns/resource_tc_private_dns_zone.md b/tencentcloud/services/privatedns/resource_tc_private_dns_zone.md index 219167f832..cebe7cb498 100644 --- a/tencentcloud/services/privatedns/resource_tc_private_dns_zone.md +++ b/tencentcloud/services/privatedns/resource_tc_private_dns_zone.md @@ -61,5 +61,5 @@ Import Private Dns Zone can be imported, e.g. ``` -$ terraform import tencentcloud_private_dns_zone.foo zone_id +$ terraform import tencentcloud_private_dns_zone.example zone-6xg5xgky ``` \ No newline at end of file diff --git a/tencentcloud/services/scf/service_tencentcloud_scf.go b/tencentcloud/services/scf/service_tencentcloud_scf.go index b71d890d1d..ea9c2626b8 100644 --- a/tencentcloud/services/scf/service_tencentcloud_scf.go +++ b/tencentcloud/services/scf/service_tencentcloud_scf.go @@ -148,16 +148,14 @@ func (me *ScfService) CreateFunction(ctx context.Context, info scfFunctionInfo) } func (me *ScfService) DescribeFunction(ctx context.Context, name, namespace string) (resp *scf.GetFunctionResponse, err error) { - client := me.client.UseScfClient() - request := scf.NewGetFunctionRequest() request.FunctionName = &name request.Namespace = &namespace - + var iacExtInfo connectivity.IacExtInfo + iacExtInfo.InstanceId = strings.Join([]string{name, namespace}, tccommon.FILED_SP) if err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { ratelimit.Check(request.GetAction()) - - response, err := client.GetFunction(request) + response, err := me.client.UseScfClient(iacExtInfo).GetFunction(request) if err != nil { if sdkError, ok := err.(*sdkErrors.TencentCloudSDKError); ok { for _, code := range SCF_FUNCTIONS_NOT_FOUND_SET { diff --git a/tencentcloud/services/sqlserver/service_tencentcloud_sqlserver.go b/tencentcloud/services/sqlserver/service_tencentcloud_sqlserver.go index 0980fa0e18..9e777e406a 100644 --- a/tencentcloud/services/sqlserver/service_tencentcloud_sqlserver.go +++ b/tencentcloud/services/sqlserver/service_tencentcloud_sqlserver.go @@ -331,11 +331,14 @@ func (me *SqlserverService) DescribeSqlserverInstances(ctx context.Context, inst } var offset, limit int64 = 0, 20 + var iacExtInfo connectivity.IacExtInfo + iacExtInfo.InstanceId = instanceId + for { request.Offset = &offset request.Limit = &limit ratelimit.Check(request.GetAction()) - response, err := me.client.UseSqlserverClient().DescribeDBInstances(request) + response, err := me.client.UseSqlserverClient(iacExtInfo).DescribeDBInstances(request) if err != nil { errRet = err return @@ -2667,7 +2670,10 @@ func (me *SqlserverService) DescribeSqlserverGeneralCloudInstanceById(ctx contex ratelimit.Check(request.GetAction()) - response, err := me.client.UseSqlserverClient().DescribeDBInstances(request) + var specArgs connectivity.IacExtInfo + specArgs.InstanceId = instanceId + + response, err := me.client.UseSqlserverClient(specArgs).DescribeDBInstances(request) if err != nil { errRet = err return diff --git a/tencentcloud/services/tcr/service_tencentcloud_tcr.go b/tencentcloud/services/tcr/service_tencentcloud_tcr.go index 86bb9cb36b..5c68478be1 100644 --- a/tencentcloud/services/tcr/service_tencentcloud_tcr.go +++ b/tencentcloud/services/tcr/service_tencentcloud_tcr.go @@ -177,7 +177,9 @@ func (me *TCRService) DescribeTCRInstanceById(ctx context.Context, instanceId st request.Registryids = []*string{&instanceId} ratelimit.Check(request.GetAction()) - response, err := me.client.UseTCRClient().DescribeInstances(request) + var iacExtInfo connectivity.IacExtInfo + iacExtInfo.InstanceId = instanceId + response, err := me.client.UseTCRClient(iacExtInfo).DescribeInstances(request) if err != nil { ee, ok := err.(*sdkErrors.TencentCloudSDKError) if !ok { diff --git a/tencentcloud/services/tdcpg/service_tencentcloud_tdcpg.go b/tencentcloud/services/tdcpg/service_tencentcloud_tdcpg.go index a448143091..6f235535bc 100644 --- a/tencentcloud/services/tdcpg/service_tencentcloud_tdcpg.go +++ b/tencentcloud/services/tdcpg/service_tencentcloud_tdcpg.go @@ -330,9 +330,11 @@ func (me *TdcpgService) DescribeTdcpgClustersByFilter(ctx context.Context, param var ( logId = tccommon.GetLogId(ctx) request = tdcpg.NewDescribeClustersRequest() + response = tdcpg.NewDescribeClustersResponse() indx = 0 currNumber = 1 pageSize = 20 + err error ) defer func() { @@ -342,6 +344,7 @@ func (me *TdcpgService) DescribeTdcpgClustersByFilter(ctx context.Context, param } }() + var tmpId string request.Filters = make([]*tdcpg.Filter, len(param)) for k, v := range param { if k == "cluster_id" { @@ -350,6 +353,7 @@ func (me *TdcpgService) DescribeTdcpgClustersByFilter(ctx context.Context, param Values: []*string{v.(*string)}, } indx++ + tmpId = v.(string) continue } @@ -390,12 +394,18 @@ func (me *TdcpgService) DescribeTdcpgClustersByFilter(ctx context.Context, param } } ratelimit.Check(request.GetAction()) + var iacExtInfo connectivity.IacExtInfo + iacExtInfo.InstanceId = tmpId for { request.PageNumber = helper.IntUint64(currNumber) request.PageSize = helper.IntUint64(pageSize) + if tmpId != "" { + response, err = me.client.UseTdcpgClient(iacExtInfo).DescribeClusters(request) + } else { + response, err = me.client.UseTdcpgClient().DescribeClusters(request) + } - response, err := me.client.UseTdcpgClient().DescribeClusters(request) if err != nil { log.Printf("[CRITICAL]%s api[%s] fail, request body [%s], reason[%s]\n", logId, request.GetAction(), request.ToJsonString(), err.Error()) @@ -422,9 +432,11 @@ func (me *TdcpgService) DescribeTdcpgInstancesByFilter(ctx context.Context, clus var ( logId = tccommon.GetLogId(ctx) request = tdcpg.NewDescribeClusterInstancesRequest() + response = tdcpg.NewDescribeClusterInstancesResponse() indx = 0 currNumber = 1 pageSize = 20 + err error ) defer func() { @@ -434,6 +446,7 @@ func (me *TdcpgService) DescribeTdcpgInstancesByFilter(ctx context.Context, clus } }() + var tmpId string request.Filters = make([]*tdcpg.Filter, len(param)) for k, v := range param { if k == "instance_id" { @@ -442,6 +455,7 @@ func (me *TdcpgService) DescribeTdcpgInstancesByFilter(ctx context.Context, clus Values: []*string{v.(*string)}, } indx++ + tmpId = v.(string) continue } @@ -473,13 +487,18 @@ func (me *TdcpgService) DescribeTdcpgInstancesByFilter(ctx context.Context, clus } } ratelimit.Check(request.GetAction()) + var iacExtInfo connectivity.IacExtInfo + iacExtInfo.InstanceId = tmpId for { request.PageNumber = helper.IntUint64(currNumber) request.PageSize = helper.IntUint64(pageSize) request.ClusterId = clusterId - - response, err := me.client.UseTdcpgClient().DescribeClusterInstances(request) + if tmpId != "" { + response, err = me.client.UseTdcpgClient(iacExtInfo).DescribeClusterInstances(request) + } else { + response, err = me.client.UseTdcpgClient().DescribeClusterInstances(request) + } if err != nil { log.Printf("[CRITICAL]%s api[%s] fail, request body [%s], reason[%s]\n", logId, request.GetAction(), request.ToJsonString(), err.Error()) diff --git a/tencentcloud/services/tdmq/service_tencentcloud_tdmq.go b/tencentcloud/services/tdmq/service_tencentcloud_tdmq.go index 29256b51be..cfbb63575f 100644 --- a/tencentcloud/services/tdmq/service_tencentcloud_tdmq.go +++ b/tencentcloud/services/tdmq/service_tencentcloud_tdmq.go @@ -44,9 +44,11 @@ func (me *TdmqService) DescribeTdmqInstanceById(ctx context.Context, var response *tdmq.DescribeClustersResponse + var iacExtInfo connectivity.IacExtInfo + iacExtInfo.InstanceId = clusterId if err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { ratelimit.Check(request.GetAction()) - result, err := me.client.UseTdmqClient().DescribeClusters(request) + result, err := me.client.UseTdmqClient(iacExtInfo).DescribeClusters(request) if err != nil { return tccommon.RetryError(err, tccommon.InternalError) } @@ -642,8 +644,9 @@ func (me *TdmqService) DescribeTdmqProfessionalClusterById(ctx context.Context, }() ratelimit.Check(request.GetAction()) - - response, err := me.client.UseTdmqClient().DescribePulsarProInstanceDetail(request) + var iacExtInfo connectivity.IacExtInfo + iacExtInfo.InstanceId = clusterId + response, err := me.client.UseTdmqClient(iacExtInfo).DescribePulsarProInstanceDetail(request) if err != nil { errRet = err return @@ -696,6 +699,8 @@ func (me *TdmqService) DescribePulsarProInstances(ctx context.Context, clusterId }() ratelimit.Check(request.GetAction()) + var iacExtInfo connectivity.IacExtInfo + iacExtInfo.InstanceId = clusterId var ( offset uint64 = 0 @@ -705,7 +710,7 @@ func (me *TdmqService) DescribePulsarProInstances(ctx context.Context, clusterId for { request.Offset = &offset request.Limit = &limit - response, err := me.client.UseTdmqClient().DescribePulsarProInstances(request) + response, err := me.client.UseTdmqClient(iacExtInfo).DescribePulsarProInstances(request) if err != nil { errRet = err return @@ -1618,8 +1623,9 @@ func (me *TdmqService) DescribeTdmqRabbitmqVipInstanceById(ctx context.Context, }() ratelimit.Check(request.GetAction()) - - response, err := me.client.UseTdmqClient().DescribeRabbitMQVipInstance(request) + var iacExtInfo connectivity.IacExtInfo + iacExtInfo.InstanceId = instanceId + response, err := me.client.UseTdmqClient(iacExtInfo).DescribeRabbitMQVipInstance(request) if err != nil { errRet = err return diff --git a/tencentcloud/services/teo/service_tencentcloud_teo.go b/tencentcloud/services/teo/service_tencentcloud_teo.go index 3dd27ba317..cdfd8dfe0b 100644 --- a/tencentcloud/services/teo/service_tencentcloud_teo.go +++ b/tencentcloud/services/teo/service_tencentcloud_teo.go @@ -47,6 +47,8 @@ func (me *TeoService) DescribeTeoZone(ctx context.Context, zoneId string) (zone } ratelimit.Check(request.GetAction()) + var iacExtInfo connectivity.IacExtInfo + iacExtInfo.InstanceId = zoneId var offset int64 = 0 var pageSize int64 = 100 @@ -56,7 +58,7 @@ func (me *TeoService) DescribeTeoZone(ctx context.Context, zoneId string) (zone request.Offset = &offset request.Limit = &pageSize ratelimit.Check(request.GetAction()) - response, err := me.client.UseTeoClient().DescribeZones(request) + response, err := me.client.UseTeoClient(iacExtInfo).DescribeZones(request) if err != nil { log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", logId, request.GetAction(), request.ToJsonString(), err.Error()) diff --git a/tencentcloud/services/tke/resource_tc_kubernetes_cluster.go b/tencentcloud/services/tke/resource_tc_kubernetes_cluster.go index 40cbe522ae..d2094174c6 100644 --- a/tencentcloud/services/tke/resource_tc_kubernetes_cluster.go +++ b/tencentcloud/services/tke/resource_tc_kubernetes_cluster.go @@ -474,6 +474,7 @@ func ResourceTencentCloudTkeCluster() *schema.Resource { "cluster_subnet_id": { Type: schema.TypeString, Optional: true, + ForceNew: true, Description: "Subnet ID of the cluster, such as: subnet-b3p7d7q5.", }, @@ -2494,10 +2495,6 @@ func resourceTencentCloudTkeClusterUpdate(d *schema.ResourceData, meta interface region := client.Region d.Partial(true) - if d.HasChange("cluster_subnet_id") { - return fmt.Errorf("argument cluster_subnet_id cannot be changed") - } - if d.HasChange("tags") { oldTags, newTags := d.GetChange("tags") replaceTags, deleteTags := svctag.DiffTags(oldTags.(map[string]interface{}), newTags.(map[string]interface{})) diff --git a/tencentcloud/services/tke/resource_tc_kubernetes_node_pool.md b/tencentcloud/services/tke/resource_tc_kubernetes_node_pool.md index 43a9bdaa95..391cfa4df8 100644 --- a/tencentcloud/services/tke/resource_tc_kubernetes_node_pool.md +++ b/tencentcloud/services/tke/resource_tc_kubernetes_node_pool.md @@ -141,4 +141,12 @@ resource "tencentcloud_kubernetes_node_pool" "mynodepool" { } +``` + +Import + +tke node pool can be imported, e.g. + +``` +$ terraform import tencentcloud_kubernetes_node_pool.test cls-xxx#np-xxx ``` \ No newline at end of file diff --git a/tencentcloud/services/tke/service_tencentcloud_tke.go b/tencentcloud/services/tke/service_tencentcloud_tke.go index fc4618e132..d9b06cd153 100644 --- a/tencentcloud/services/tke/service_tencentcloud_tke.go +++ b/tencentcloud/services/tke/service_tencentcloud_tke.go @@ -414,8 +414,10 @@ func (me *TkeService) DescribeCluster(ctx context.Context, id string) ( request.ClusterIds = []*string{&id} + var iacExtInfo connectivity.IacExtInfo + iacExtInfo.InstanceId = id ratelimit.Check(request.GetAction()) - response, err := me.client.UseTkeClient().DescribeClusters(request) + response, err := me.client.UseTkeClient(iacExtInfo).DescribeClusters(request) if err != nil { errRet = err diff --git a/tencentcloud/services/tse/resource_tc_tse_cngw_network_access_control.go b/tencentcloud/services/tse/resource_tc_tse_cngw_network_access_control.go new file mode 100644 index 0000000000..4624830126 --- /dev/null +++ b/tencentcloud/services/tse/resource_tc_tse_cngw_network_access_control.go @@ -0,0 +1,235 @@ +package tse + +import ( + "context" + "fmt" + "log" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + tse "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tse/v20201207" + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" +) + +func ResourceTencentCloudTseCngwNetworkAccessControl() *schema.Resource { + return &schema.Resource{ + Create: resourceTencentCloudTseCngwNetworkAccessControlCreate, + Read: resourceTencentCloudTseCngwNetworkAccessControlRead, + Update: resourceTencentCloudTseCngwNetworkAccessControlUpdate, + Delete: resourceTencentCloudTseCngwNetworkAccessControlDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Schema: map[string]*schema.Schema{ + "gateway_id": { + Required: true, + ForceNew: true, + Type: schema.TypeString, + Description: "gateway ID.", + }, + + "group_id": { + Required: true, + ForceNew: true, + Type: schema.TypeString, + Description: "gateway group ID.", + }, + + "network_id": { + Required: true, + ForceNew: true, + Type: schema.TypeString, + Description: "network id.", + }, + + "access_control": { + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + Description: "access control policy.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "mode": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Access mode: `Whitelist`, `Blacklist`.", + }, + "cidr_white_list": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Description: "White list.", + }, + "cidr_black_list": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Description: "Black list.", + }, + }, + }, + }, + }, + } +} + +func resourceTencentCloudTseCngwNetworkAccessControlCreate(d *schema.ResourceData, meta interface{}) error { + defer tccommon.LogElapsed("resource.tencentcloud_tse_cngw_network_access_control.create")() + defer tccommon.InconsistentCheck(d, meta)() + + var ( + gatewayId string + groupId string + networkId string + ) + if v, ok := d.GetOk("gateway_id"); ok { + gatewayId = v.(string) + } + if v, ok := d.GetOk("group_id"); ok { + groupId = v.(string) + } + if v, ok := d.GetOk("network_id"); ok { + networkId = v.(string) + } + d.SetId(gatewayId + tccommon.FILED_SP + groupId + tccommon.FILED_SP + networkId) + + return resourceTencentCloudTseCngwNetworkAccessControlUpdate(d, meta) +} + +func resourceTencentCloudTseCngwNetworkAccessControlRead(d *schema.ResourceData, meta interface{}) error { + defer tccommon.LogElapsed("resource.tencentcloud_tse_cngw_network_access_control.read")() + defer tccommon.InconsistentCheck(d, meta)() + + logId := tccommon.GetLogId(tccommon.ContextNil) + ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + + service := TseService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + + idSplit := strings.Split(d.Id(), tccommon.FILED_SP) + if len(idSplit) != 3 { + return fmt.Errorf("id is broken,%s", d.Id()) + } + gatewayId := idSplit[0] + groupId := idSplit[1] + networkId := idSplit[2] + + cngwNetwork, err := service.DescribeTseCngwNetworkById(ctx, gatewayId, groupId, networkId) + if err != nil { + return err + } + + if cngwNetwork == nil { + d.SetId("") + log.Printf("[WARN]%s resource `TseCngwNetworkAccessControl` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) + return nil + } + + _ = d.Set("gateway_id", gatewayId) + _ = d.Set("group_id", groupId) + _ = d.Set("network_id", networkId) + + if cngwNetwork.PublicNetwork != nil { + internetConfig := cngwNetwork.PublicNetwork + if internetConfig.AccessControl != nil { + accessControlMap := map[string]interface{}{} + + accessControl := internetConfig.AccessControl + if accessControl.Mode != nil { + accessControlMap["mode"] = accessControl.Mode + } + if accessControl.Mode != nil { + accessControlMap["cidr_white_list"] = accessControl.CidrWhiteList + } + if accessControl.Mode != nil { + accessControlMap["cidr_black_list"] = accessControl.CidrBlackList + } + _ = d.Set("access_control", []interface{}{accessControlMap}) + } + } + + return nil +} + +func resourceTencentCloudTseCngwNetworkAccessControlUpdate(d *schema.ResourceData, meta interface{}) error { + defer tccommon.LogElapsed("resource.tencentcloud_tse_cngw_network_access_control.update")() + defer tccommon.InconsistentCheck(d, meta)() + + logId := tccommon.GetLogId(tccommon.ContextNil) + ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + + request := tse.NewModifyNetworkAccessStrategyRequest() + + idSplit := strings.Split(d.Id(), tccommon.FILED_SP) + if len(idSplit) != 3 { + return fmt.Errorf("id is broken,%s", d.Id()) + } + gatewayId := idSplit[0] + groupId := idSplit[1] + networkId := idSplit[2] + + service := TseService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + cngwNetwork, err := service.DescribeTseCngwNetworkById(ctx, gatewayId, groupId, networkId) + if err != nil { + return err + } + if cngwNetwork == nil { + return fmt.Errorf("[WARN]%s resource `TseCngwNetworkAccessControl` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) + } + + request.GatewayId = helper.String(gatewayId) + request.GroupId = helper.String(groupId) + // The interface only supports public network + request.NetworkType = helper.String("Open") + request.Vip = cngwNetwork.PublicNetwork.Vip + + if d.HasChange("access_control") { + if dMap, ok := helper.InterfacesHeadMap(d, "access_control"); ok { + accessControl := tse.NetworkAccessControl{} + if v, ok := dMap["mode"]; ok { + accessControl.Mode = helper.String(v.(string)) + } + if v, ok := dMap["cidr_white_list"]; ok { + whitelist := v.([]interface{}) + accessControl.CidrWhiteList = helper.InterfacesStringsPoint(whitelist) + } + if v, ok := dMap["cidr_black_list"]; ok { + blacklist := v.([]interface{}) + accessControl.CidrBlackList = helper.InterfacesStringsPoint(blacklist) + } + request.AccessControl = &accessControl + } + } + + err = resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseTseClient().ModifyNetworkAccessStrategy(request) + if e != nil { + return tccommon.RetryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) + } + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s update tse cngwNetworkAccessStrategy failed, reason:%+v", logId, err) + return err + } + + conf := tccommon.BuildStateChangeConf([]string{}, []string{"Open"}, 5*tccommon.ReadRetryTimeout, time.Second, service.TseCngwNetworkStateRefreshFunc(gatewayId, groupId, networkId, []string{})) + + if _, e := conf.WaitForState(); e != nil { + return e + } + + return resourceTencentCloudTseCngwNetworkAccessControlRead(d, meta) +} + +func resourceTencentCloudTseCngwNetworkAccessControlDelete(d *schema.ResourceData, meta interface{}) error { + defer tccommon.LogElapsed("resource.tencentcloud_tse_cngw_network_access_control.delete")() + defer tccommon.InconsistentCheck(d, meta)() + + return nil +} diff --git a/tencentcloud/services/tse/resource_tc_tse_cngw_network_access_control.md b/tencentcloud/services/tse/resource_tc_tse_cngw_network_access_control.md new file mode 100644 index 0000000000..802be65882 --- /dev/null +++ b/tencentcloud/services/tse/resource_tc_tse_cngw_network_access_control.md @@ -0,0 +1,23 @@ +Provides a resource to create a tse cngw_network_access_control + +Example Usage + +```hcl +resource "tencentcloud_tse_cngw_network_access_control" "cngw_network_access_control" { + gateway_id = "gateway-cf8c99c3" + group_id = "group-a160d123" + network_id = "network-372b1e84" + access_control { + mode = "Whitelist" + cidr_white_list = ["1.1.1.0"] + } +} +``` + +Import + +tse cngw_route_rate_limit can be imported using the id, e.g. + +``` +terraform import tencentcloud_tse_cngw_network_access_control.cngw_network_access_control gatewayId#groupId#networkId +``` \ No newline at end of file diff --git a/tencentcloud/services/tse/resource_tc_tse_cngw_network_access_control_test.go b/tencentcloud/services/tse/resource_tc_tse_cngw_network_access_control_test.go new file mode 100644 index 0000000000..2697bd8101 --- /dev/null +++ b/tencentcloud/services/tse/resource_tc_tse_cngw_network_access_control_test.go @@ -0,0 +1,48 @@ +package tse_test + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + tcacctest "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/acctest" +) + +func TestAccTencentCloudNeedFixTseCngwNetworkAccessControlResource_basic(t *testing.T) { + t.Parallel() + resource.Test(t, resource.TestCase{ + PreCheck: func() { + tcacctest.AccPreCheck(t) + }, + Providers: tcacctest.AccProviders, + Steps: []resource.TestStep{ + { + Config: testAccTseCngwNetworkAccessControl, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("tencentcloud_tse_cngw_network_access_control.cngw_network_access_control", "id"), + resource.TestCheckResourceAttr("tencentcloud_tse_cngw_network_access_control.cngw_network_access_control", "access_control.#", "1"), + resource.TestCheckResourceAttr("tencentcloud_tse_cngw_network_access_control.cngw_network_access_control", "access_control.0.mode", "Whitelist"), + resource.TestCheckResourceAttr("tencentcloud_tse_cngw_network_access_control.cngw_network_access_control", "access_control.0.cidr_white_list.#", "1"), + ), + }, + { + ResourceName: "tencentcloud_tse_cngw_network_access_control.cngw_network_access_control", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +const testAccTseCngwNetworkAccessControl = ` + +resource "tencentcloud_tse_cngw_network_access_control" "cngw_network_access_control" { + gateway_id = "gateway-cf1790c7" + group_id = "group-d8d99615" + network_id = "network-9cd9821f" + access_control { + mode = "Whitelist" + cidr_white_list = ["1.1.1.0"] + } + } + +` diff --git a/tencentcloud/services/tse/service_tencentcloud_tse.go b/tencentcloud/services/tse/service_tencentcloud_tse.go index e0eaa41f14..c8590aaa85 100644 --- a/tencentcloud/services/tse/service_tencentcloud_tse.go +++ b/tencentcloud/services/tse/service_tencentcloud_tse.go @@ -43,8 +43,9 @@ func (me *TseService) DescribeTseInstanceById(ctx context.Context, instanceId st }() ratelimit.Check(request.GetAction()) - - response, err := me.client.UseTseClient().DescribeSREInstances(request) + var iacExtInfo connectivity.IacExtInfo + iacExtInfo.InstanceId = instanceId + response, err := me.client.UseTseClient(iacExtInfo).DescribeSREInstances(request) if err != nil { errRet = err return diff --git a/tencentcloud/services/vod/resource_tc_vod_adaptive_dynamic_streaming_template.go b/tencentcloud/services/vod/resource_tc_vod_adaptive_dynamic_streaming_template.go index af14e6810f..217942ef87 100644 --- a/tencentcloud/services/vod/resource_tc_vod_adaptive_dynamic_streaming_template.go +++ b/tencentcloud/services/vod/resource_tc_vod_adaptive_dynamic_streaming_template.go @@ -5,12 +5,14 @@ import ( "fmt" "log" "strconv" + "strings" "time" tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + sdkErrors "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors" vod "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vod/v20180717" "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" @@ -66,7 +68,7 @@ func ResourceTencentCloudVodAdaptiveDynamicStreamingTemplate() *schema.Resource "sub_app_id": { Type: schema.TypeInt, Optional: true, - Description: "Subapplication ID in VOD. If you need to access a resource in a subapplication, enter the subapplication ID in this field; otherwise, leave it empty.", + Description: "The VOD [application](https://intl.cloud.tencent.com/document/product/266/14574) ID. For customers who activate VOD service from December 25, 2023, if they want to access resources in a VOD application (whether it's the default application or a newly created one), they must fill in this field with the application ID.", }, "stream_info": { Type: schema.TypeList, @@ -123,6 +125,40 @@ func ResourceTencentCloudVodAdaptiveDynamicStreamingTemplate() *schema.Resource ValidateFunc: tccommon.ValidateAllowedStringValue([]string{"stretch", "black"}), Description: "Fill type. Fill refers to the way of processing a screenshot when its aspect ratio is different from that of the source video. The following fill types are supported: `stretch`: stretch. The screenshot will be stretched frame by frame to match the aspect ratio of the source video, which may make the screenshot shorter or longer; `black`: fill with black. This option retains the aspect ratio of the source video for the screenshot and fills the unmatched area with black color blocks. Default value: black. Note: this field may return null, indicating that no valid values can be obtained.", }, + "vcrf": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Video constant bit rate control factor, value range is [1,51].\n" + + "Note:\n" + + "- If this parameter is specified, the bitrate control method of CRF will be used for transcoding (the video bitrate will no longer take effect);\n" + + "- This field is required when the video stream encoding format is H.266. The recommended value is 28;\n" + + "- If there are no special requirements, it is not recommended to specify this parameter.", + }, + "gop": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Interval between Keyframe I frames, value range: 0 and [1, 100000], unit: number of frames. When you fill in 0 or leave it empty, the gop length is automatically set.", + }, + "preserve_hdr_switch": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Whether the transcoding output still maintains HDR when the original video is HDR (High Dynamic Range). Value range:\n" + + "- ON: if the original file is HDR, the transcoding output remains HDR;, otherwise the transcoding output is SDR (Standard Dynamic Range);\n" + + "- OFF: regardless of whether the original file is HDR or SDR, the transcoding output is SDR;\n" + + "Default value: OFF.", + }, + "codec_tag": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Encoding label, valid only if the encoding format of the video stream is H.265 encoding. Available values:\n" + + "- hvc1: stands for hvc1 tag;\n" + + "- hev1: stands for the hev1 tag;\n" + + "Default value: hvc1.", + }, }, }, }, @@ -164,9 +200,49 @@ func ResourceTencentCloudVodAdaptiveDynamicStreamingTemplate() *schema.Resource Default: false, Description: "Whether to remove audio stream. Valid values: `false`: no, `true`: yes. `false` by default.", }, + "remove_video": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Whether to remove video stream. Valid values: `false`: no, `true`: yes. `false` by default.", + }, + "tehd_config": { + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + MinItems: 1, + Description: "Extremely fast HD transcoding parameters.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "type": { + Type: schema.TypeString, + Required: true, + Description: "Extreme high-speed HD type, available values:\n" + + "- TEHD-100: super high definition-100th;\n" + + "- OFF: turn off Ultra High definition.", + }, + "max_video_bitrate": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Video bitrate limit, which is valid when Type specifies extreme speed HD type. If you leave it empty or enter 0, there is no video bitrate limit.", + }, + }, + }, + }, }, }, }, + "segment_type": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Segment type, valid when Format is HLS, optional values:\n" + + "- ts: ts segment;\n" + + "- fmp4: fmp4 segment;\n" + + "Default value: ts.", + }, // computed "create_time": { Type: schema.TypeString, @@ -190,6 +266,9 @@ func resourceTencentCloudVodAdaptiveDynamicStreamingTemplateCreate(d *schema.Res request = vod.NewCreateAdaptiveDynamicStreamingTemplateRequest() ) + if v, ok := d.GetOk("segment_type"); ok { + request.SegmentType = helper.String(v.(string)) + } request.Format = helper.String(d.Get("format").(string)) request.Name = helper.String(d.Get("name").(string)) if v, ok := d.GetOk("drm_type"); ok { @@ -200,8 +279,12 @@ func resourceTencentCloudVodAdaptiveDynamicStreamingTemplateCreate(d *schema.Res if v, ok := d.GetOk("comment"); ok { request.Comment = helper.String(v.(string)) } + var resourceId string if v, ok := d.GetOk("sub_app_id"); ok { - request.SubAppId = helper.IntUint64(v.(int)) + subAppId := v.(int) + resourceId += helper.IntToStr(subAppId) + resourceId += tccommon.FILED_SP + request.SubAppId = helper.IntUint64(subAppId) } streamInfos := d.Get("stream_info").([]interface{}) request.StreamInfos = make([]*vod.AdaptiveStreamTemplate, 0, len(streamInfos)) @@ -210,16 +293,39 @@ func resourceTencentCloudVodAdaptiveDynamicStreamingTemplateCreate(d *schema.Res video := v["video"].([]interface{})[0].(map[string]interface{}) audio := v["audio"].([]interface{})[0].(map[string]interface{}) rAudio := REMOVE_AUDIO_TO_UNINT[v["remove_audio"].(bool)] + videoTemplateInfo := &vod.VideoTemplateInfo{ + Codec: helper.String(video["codec"].(string)), + Fps: helper.IntUint64(video["fps"].(int)), + Bitrate: helper.IntUint64(video["bitrate"].(int)), + ResolutionAdaptive: helper.String(RESOLUTION_ADAPTIVE_TO_STRING[video["resolution_adaptive"].(bool)]), + Width: helper.IntUint64(video["width"].(int)), + Height: helper.IntUint64(video["height"].(int)), + FillType: helper.String(video["fill_type"].(string)), + } + var rVideo uint64 + if v, ok := video["remove_video"]; ok && v.(bool) { + rVideo = REMOVE_AUDIO_TO_UNINT[v.(bool)] + } + if v, ok := video["vcrf"]; ok && v.(int) != 0 { + videoTemplateInfo.Vcrf = helper.IntUint64(v.(int)) + } + if v, ok := video["gop"]; ok { + videoTemplateInfo.Gop = helper.IntUint64(v.(int)) + } + if v, ok := video["preserve_hdr_switch"]; ok && v.(string) != "" { + videoTemplateInfo.PreserveHDRSwitch = helper.String(v.(string)) + } + if v, ok := video["codec_tag"]; ok && v.(string) != "" { + videoTemplateInfo.CodecTag = helper.String(v.(string)) + } + + var tehdConfig map[string]interface{} + if len(v["tehd_config"].([]interface{})) > 0 { + tehdConfig = v["tehd_config"].([]interface{})[0].(map[string]interface{}) + } request.StreamInfos = append(request.StreamInfos, &vod.AdaptiveStreamTemplate{ - Video: &vod.VideoTemplateInfo{ - Codec: helper.String(video["codec"].(string)), - Fps: helper.IntUint64(video["fps"].(int)), - Bitrate: helper.IntUint64(video["bitrate"].(int)), - ResolutionAdaptive: helper.String(RESOLUTION_ADAPTIVE_TO_STRING[video["resolution_adaptive"].(bool)]), - Width: helper.IntUint64(video["width"].(int)), - Height: helper.IntUint64(video["height"].(int)), - FillType: helper.String(video["fill_type"].(string)), - }, + + Video: videoTemplateInfo, Audio: &vod.AudioTemplateInfo{ Codec: helper.String(audio["codec"].(string)), Bitrate: helper.IntUint64(audio["bitrate"].(int)), @@ -227,6 +333,19 @@ func resourceTencentCloudVodAdaptiveDynamicStreamingTemplateCreate(d *schema.Res AudioChannel: helper.Int64(VOD_AUDIO_CHANNEL_TYPE_TO_INT[audio["audio_channel"].(string)]), }, RemoveAudio: &rAudio, + RemoveVideo: &rVideo, + TEHDConfig: func() *vod.TEHDConfig { + if tehdConfig == nil { + return nil + } + tehd := &vod.TEHDConfig{ + Type: helper.String(tehdConfig["type"].(string)), + } + if v, ok := tehdConfig["max_video_bitrate"]; ok { + tehd.MaxVideoBitrate = helper.IntUint64(v.(int)) + } + return tehd + }(), }) } @@ -236,8 +355,13 @@ func resourceTencentCloudVodAdaptiveDynamicStreamingTemplateCreate(d *schema.Res ratelimit.Check(request.GetAction()) response, err = meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseVodClient().CreateAdaptiveDynamicStreamingTemplate(request) if err != nil { - log.Printf("[CRITAL]%s api[%s] fail, reason:%s", logId, request.GetAction(), err.Error()) - return tccommon.RetryError(err) + if sdkError, ok := err.(*sdkErrors.TencentCloudSDKError); ok { + if sdkError.Code == "FailedOperation" && sdkError.Message == "invalid vod user" { + return resource.RetryableError(err) + } + } + log.Printf("[CRITAL]%s api[%s] fail, reason:%s", logId, request.GetAction(), strconv.ErrRange.Error()) + return resource.NonRetryableError(err) } return nil }) @@ -247,7 +371,8 @@ func resourceTencentCloudVodAdaptiveDynamicStreamingTemplateCreate(d *schema.Res if response == nil || response.Response == nil { return fmt.Errorf("for vod adaptive dynamic streaming template creation, response is nil") } - d.SetId(strconv.FormatUint(*response.Response.Definition, 10)) + resourceId += strconv.FormatUint(*response.Response.Definition, 10) + d.SetId(resourceId) return resourceTencentCloudVodAdaptiveDynamicStreamingTemplateRead(d, meta) } @@ -259,14 +384,21 @@ func resourceTencentCloudVodAdaptiveDynamicStreamingTemplateRead(d *schema.Resou var ( logId = tccommon.GetLogId(tccommon.ContextNil) ctx = context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - id = d.Id() - subAppId = d.Get("sub_app_id").(int) + subAppId int + definition string client = meta.(tccommon.ProviderMeta).GetAPIV3Conn() vodService = VodService{client: client} ) + idSplit := strings.Split(d.Id(), tccommon.FILED_SP) + if len(idSplit) == 2 { + subAppId = helper.StrToInt(idSplit[0]) + definition = idSplit[1] + } else { + definition = d.Id() + } // waiting for refreshing cache time.Sleep(30 * time.Second) - template, has, err := vodService.DescribeAdaptiveDynamicStreamingTemplatesById(ctx, id, subAppId) + template, has, err := vodService.DescribeAdaptiveDynamicStreamingTemplatesById(ctx, definition, subAppId) if err != nil { return err } @@ -283,6 +415,7 @@ func resourceTencentCloudVodAdaptiveDynamicStreamingTemplateRead(d *schema.Resou _ = d.Set("comment", template.Comment) _ = d.Set("create_time", template.CreateTime) _ = d.Set("update_time", template.UpdateTime) + _ = d.Set("segment_type", template.SegmentType) var streamInfos = make([]interface{}, 0, len(template.StreamInfos)) for _, v := range template.StreamInfos { @@ -296,6 +429,10 @@ func resourceTencentCloudVodAdaptiveDynamicStreamingTemplateRead(d *schema.Resou "width": v.Video.Width, "height": v.Video.Height, "fill_type": v.Video.FillType, + "vcrf": v.Video.Vcrf, + "gop": v.Video.Gop, + "preserve_hdr_switch": v.Video.PreserveHDRSwitch, + "codec_tag": v.Video.CodecTag, }, }, "audio": []map[string]interface{}{ @@ -307,9 +444,24 @@ func resourceTencentCloudVodAdaptiveDynamicStreamingTemplateRead(d *schema.Resou }, }, "remove_audio": *v.RemoveAudio == 1, + "remove_video": *v.RemoveVideo == 1, + "tehd_config": func() []map[string]interface{} { + if v.TEHDConfig == nil { + return nil + } + return []map[string]interface{}{ + { + "type": v.TEHDConfig.Type, + "max_video_bitrate": v.TEHDConfig.MaxVideoBitrate, + }, + } + }(), }) } _ = d.Set("stream_info", streamInfos) + if subAppId != 0 { + _ = d.Set("sub_app_id", subAppId) + } return nil } @@ -320,12 +472,33 @@ func resourceTencentCloudVodAdaptiveDynamicStreamingTemplateUpdate(d *schema.Res var ( logId = tccommon.GetLogId(tccommon.ContextNil) request = vod.NewModifyAdaptiveDynamicStreamingTemplateRequest() - id = d.Id() changeFlag = false + subAppId int + definition string ) - idUint, _ := strconv.ParseUint(id, 0, 64) - request.Definition = &idUint + idSplit := strings.Split(d.Id(), tccommon.FILED_SP) + if len(idSplit) == 2 { + subAppId = helper.StrToInt(idSplit[0]) + definition = idSplit[1] + request.SubAppId = helper.IntUint64(subAppId) + } else { + definition = d.Id() + if v, ok := d.GetOk("sub_app_id"); ok { + request.SubAppId = helper.IntUint64(v.(int)) + } + } + + request.Definition = helper.StrToUint64Point(definition) + + immutableArgs := []string{"sub_app_id"} + + for _, v := range immutableArgs { + if d.HasChange(v) { + return fmt.Errorf("argument `%s` cannot be changed", v) + } + } + if d.HasChange("format") { changeFlag = true request.Format = helper.String(d.Get("format").(string)) @@ -346,10 +519,6 @@ func resourceTencentCloudVodAdaptiveDynamicStreamingTemplateUpdate(d *schema.Res changeFlag = true request.Comment = helper.String(d.Get("comment").(string)) } - if d.HasChange("sub_app_id") { - changeFlag = true - request.SubAppId = helper.IntUint64(d.Get("sub_app_id").(int)) - } if d.HasChange("stream_info") { changeFlag = true streamInfos := d.Get("stream_info").([]interface{}) @@ -358,7 +527,15 @@ func resourceTencentCloudVodAdaptiveDynamicStreamingTemplateUpdate(d *schema.Res v := item.(map[string]interface{}) video := v["video"].([]interface{})[0].(map[string]interface{}) audio := v["audio"].([]interface{})[0].(map[string]interface{}) + var tehdConfig map[string]interface{} + if len(v["tehd_config"].([]interface{})) > 0 { + tehdConfig = v["tehd_config"].([]interface{})[0].(map[string]interface{}) + } rAudio := REMOVE_AUDIO_TO_UNINT[v["remove_audio"].(bool)] + var rVideo uint64 + if v, ok := video["remove_video"]; ok && v.(bool) { + rVideo = REMOVE_AUDIO_TO_UNINT[v.(bool)] + } request.StreamInfos = append(request.StreamInfos, &vod.AdaptiveStreamTemplate{ Video: &vod.VideoTemplateInfo{ Codec: helper.String(video["codec"].(string)), @@ -378,6 +555,30 @@ func resourceTencentCloudVodAdaptiveDynamicStreamingTemplateUpdate(d *schema.Res return helper.IntUint64(height) }(video["height"].(int)), FillType: helper.String(video["fill_type"].(string)), + Vcrf: func() *uint64 { + if v, ok := video["vcrf"]; !ok || v.(int) == 0 { + return nil + } + return helper.IntUint64(video["vcrf"].(int)) + }(), + Gop: func() *uint64 { + if _, ok := video["gop"]; !ok { + return nil + } + return helper.IntUint64(video["gop"].(int)) + }(), + PreserveHDRSwitch: func() *string { + if v, ok := video["preserve_hdr_switch"]; !ok || v.(string) == "" { + return nil + } + return helper.String(video["preserve_hdr_switch"].(string)) + }(), + CodecTag: func() *string { + if v, ok := video["codec_tag"]; !ok || v.(string) == "" { + return nil + } + return helper.String(video["codec_tag"].(string)) + }(), }, Audio: &vod.AudioTemplateInfo{ Codec: helper.String(audio["codec"].(string)), @@ -386,6 +587,19 @@ func resourceTencentCloudVodAdaptiveDynamicStreamingTemplateUpdate(d *schema.Res AudioChannel: helper.Int64(VOD_AUDIO_CHANNEL_TYPE_TO_INT[audio["audio_channel"].(string)]), }, RemoveAudio: &rAudio, + RemoveVideo: &rVideo, + TEHDConfig: func() *vod.TEHDConfig { + if tehdConfig == nil { + return nil + } + tehd := &vod.TEHDConfig{ + Type: helper.String(tehdConfig["type"].(string)), + } + if v, ok := tehdConfig["max_video_bitrate"]; ok { + tehd.MaxVideoBitrate = helper.IntUint64(v.(int)) + } + return tehd + }(), }) } } @@ -417,12 +631,25 @@ func resourceTencentCloudVodAdaptiveDynamicStreamingTemplateDelete(d *schema.Res logId := tccommon.GetLogId(tccommon.ContextNil) ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - id := d.Id() + var ( + subAppId int + definition string + ) + idSplit := strings.Split(d.Id(), tccommon.FILED_SP) + if len(idSplit) == 2 { + subAppId = helper.StrToInt(idSplit[0]) + definition = idSplit[1] + } else { + definition = d.Id() + if v, ok := d.GetOk("sub_app_id"); ok { + subAppId = v.(int) + } + } vodService := VodService{ client: meta.(tccommon.ProviderMeta).GetAPIV3Conn(), } - if err := vodService.DeleteAdaptiveDynamicStreamingTemplate(ctx, id, uint64(d.Get("sub_app_id").(int))); err != nil { + if err := vodService.DeleteAdaptiveDynamicStreamingTemplate(ctx, definition, uint64(subAppId)); err != nil { return err } diff --git a/tencentcloud/services/vod/resource_tc_vod_adaptive_dynamic_streaming_template.md b/tencentcloud/services/vod/resource_tc_vod_adaptive_dynamic_streaming_template.md index 487b9c6c04..7644293cea 100644 --- a/tencentcloud/services/vod/resource_tc_vod_adaptive_dynamic_streaming_template.md +++ b/tencentcloud/services/vod/resource_tc_vod_adaptive_dynamic_streaming_template.md @@ -3,52 +3,44 @@ Provide a resource to create a VOD adaptive dynamic streaming template. Example Usage ```hcl +resource "tencentcloud_vod_sub_application" "sub_application" { + name = "adaptive-subapplication" + status = "On" + description = "this is sub application" +} + resource "tencentcloud_vod_adaptive_dynamic_streaming_template" "foo" { format = "HLS" name = "tf-adaptive" + sub_app_id = tonumber(split("#", tencentcloud_vod_sub_application.sub_application.id)[1]) drm_type = "SimpleAES" disable_higher_video_bitrate = false disable_higher_video_resolution = false comment = "test" - stream_info { - video { - codec = "libx265" - fps = 4 - bitrate = 129 - resolution_adaptive = false - width = 128 - height = 128 - fill_type = "stretch" - } - audio { - codec = "libmp3lame" - bitrate = 129 - sample_rate = 44100 - audio_channel = "dual" - } - remove_audio = false - } stream_info { video { codec = "libx264" - fps = 4 - bitrate = 256 + fps = 3 + bitrate = 128 } audio { codec = "libfdk_aac" - bitrate = 256 - sample_rate = 44100 + bitrate = 128 + sample_rate = 32000 } remove_audio = true + tehd_config { + type = "TEHD-100" + } } } ``` Import -VOD adaptive dynamic streaming template can be imported using the id, e.g. +VOD adaptive dynamic streaming template can be imported using the id($subAppId#$templateId), e.g. ``` -$ terraform import tencentcloud_vod_adaptive_dynamic_streaming_template.foo 169141 +$ terraform import tencentcloud_vod_adaptive_dynamic_streaming_template.foo $subAppId#$templateId ``` \ No newline at end of file diff --git a/tencentcloud/services/vod/resource_tc_vod_adaptive_dynamic_streaming_template_test.go b/tencentcloud/services/vod/resource_tc_vod_adaptive_dynamic_streaming_template_test.go index 7ab4ae3b60..d2346110a2 100644 --- a/tencentcloud/services/vod/resource_tc_vod_adaptive_dynamic_streaming_template_test.go +++ b/tencentcloud/services/vod/resource_tc_vod_adaptive_dynamic_streaming_template_test.go @@ -4,10 +4,12 @@ import ( "context" "fmt" "strconv" + "strings" "testing" tcacctest "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/acctest" tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" svcvod "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/services/vod" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" @@ -53,7 +55,6 @@ func TestAccTencentCloudVodAdaptiveDynamicStreamingTemplateResource(t *testing.T { Config: testAccVodAdaptiveDynamicStreamingTemplate, Check: resource.ComposeTestCheckFunc( - testAccCheckVodAdaptiveDynamicStreamingTemplateExists("tencentcloud_vod_adaptive_dynamic_streaming_template.foo"), resource.TestCheckResourceAttr("tencentcloud_vod_adaptive_dynamic_streaming_template.foo", "format", "HLS"), resource.TestCheckResourceAttr("tencentcloud_vod_adaptive_dynamic_streaming_template.foo", "name", "tf-adaptive"), resource.TestCheckResourceAttr("tencentcloud_vod_adaptive_dynamic_streaming_template.foo", "drm_type", "SimpleAES"), @@ -81,6 +82,8 @@ func TestAccTencentCloudVodAdaptiveDynamicStreamingTemplateResource(t *testing.T resource.TestCheckResourceAttr("tencentcloud_vod_adaptive_dynamic_streaming_template.foo", "stream_info.1.remove_audio", "true"), resource.TestCheckResourceAttrSet("tencentcloud_vod_adaptive_dynamic_streaming_template.foo", "create_time"), resource.TestCheckResourceAttrSet("tencentcloud_vod_adaptive_dynamic_streaming_template.foo", "update_time"), + resource.TestCheckResourceAttrSet("tencentcloud_vod_adaptive_dynamic_streaming_template.foo", "sub_app_id"), + resource.TestCheckResourceAttr("tencentcloud_vod_adaptive_dynamic_streaming_template.foo", "segment_type", "ts"), ), }, { @@ -104,13 +107,14 @@ func TestAccTencentCloudVodAdaptiveDynamicStreamingTemplateResource(t *testing.T resource.TestCheckResourceAttr("tencentcloud_vod_adaptive_dynamic_streaming_template.foo", "stream_info.0.audio.0.sample_rate", "44100"), resource.TestCheckResourceAttr("tencentcloud_vod_adaptive_dynamic_streaming_template.foo", "stream_info.0.audio.0.audio_channel", "dual"), resource.TestCheckResourceAttr("tencentcloud_vod_adaptive_dynamic_streaming_template.foo", "stream_info.0.remove_audio", "false"), + resource.TestCheckResourceAttrSet("tencentcloud_vod_adaptive_dynamic_streaming_template.foo", "sub_app_id"), + resource.TestCheckResourceAttr("tencentcloud_vod_adaptive_dynamic_streaming_template.foo", "stream_info.0.tehd_config.0.type", "TEHD-100"), ), }, { - ResourceName: "tencentcloud_vod_adaptive_dynamic_streaming_template.foo", - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"sub_app_id"}, + ResourceName: "tencentcloud_vod_adaptive_dynamic_streaming_template.foo", + ImportState: true, + ImportStateVerify: true, }, }, }) @@ -125,11 +129,13 @@ func testAccCheckVodAdaptiveDynamicStreamingTemplateDestroy(s *terraform.State) if rs.Type != "tencentcloud_vod_adaptive_dynamic_streaming_template" { continue } - var ( - filter = map[string]interface{}{ - "definitions": []string{rs.Primary.ID}, - } - ) + idSplit := strings.Split(rs.Primary.ID, tccommon.FILED_SP) + subAppId := helper.StrToInt(idSplit[0]) + definition := idSplit[1] + filter := map[string]interface{}{ + "definitions": []string{definition}, + "sub_appid": subAppId, + } templates, err := vodService.DescribeAdaptiveDynamicStreamingTemplatesByFilter(ctx, filter) if err != nil { @@ -156,9 +162,13 @@ func testAccCheckVodAdaptiveDynamicStreamingTemplateExists(n string) resource.Te return fmt.Errorf("vod adaptive dynamic streaming template id is not set") } vodService := svcvod.NewVodService(tcacctest.AccProvider.Meta().(tccommon.ProviderMeta).GetAPIV3Conn()) + idSplit := strings.Split(rs.Primary.ID, tccommon.FILED_SP) + subAppId := helper.StrToInt(idSplit[0]) + definition := idSplit[1] var ( filter = map[string]interface{}{ - "definitions": []string{rs.Primary.ID}, + "definitions": []string{definition}, + "sub_appid": subAppId, } ) @@ -174,9 +184,16 @@ func testAccCheckVodAdaptiveDynamicStreamingTemplateExists(n string) resource.Te } const testAccVodAdaptiveDynamicStreamingTemplate = ` +resource "tencentcloud_vod_sub_application" "sub_application" { + name = "adaptive-subapplication" + status = "On" + description = "this is sub application" +} + resource "tencentcloud_vod_adaptive_dynamic_streaming_template" "foo" { format = "HLS" name = "tf-adaptive" + sub_app_id = tonumber(split("#", tencentcloud_vod_sub_application.sub_application.id)[1]) drm_type = "SimpleAES" disable_higher_video_bitrate = false disable_higher_video_resolution = false @@ -212,9 +229,16 @@ resource "tencentcloud_vod_adaptive_dynamic_streaming_template" "foo" { ` const testAccVodAdaptiveDynamicStreamingTemplateUpdate = ` +resource "tencentcloud_vod_sub_application" "sub_application" { + name = "adaptive-subapplication" + status = "On" + description = "this is sub application" +} + resource "tencentcloud_vod_adaptive_dynamic_streaming_template" "foo" { format = "HLS" name = "tf-adaptive-update" + sub_app_id = tonumber(split("#", tencentcloud_vod_sub_application.sub_application.id)[1]) drm_type = "SimpleAES" disable_higher_video_bitrate = true disable_higher_video_resolution = true @@ -237,6 +261,9 @@ resource "tencentcloud_vod_adaptive_dynamic_streaming_template" "foo" { audio_channel = "dual" } remove_audio = false + tehd_config { + type = "TEHD-100" + } } } ` diff --git a/tencentcloud/services/vod/resource_tc_vod_event_config.go b/tencentcloud/services/vod/resource_tc_vod_event_config.go new file mode 100644 index 0000000000..bff61d4502 --- /dev/null +++ b/tencentcloud/services/vod/resource_tc_vod_event_config.go @@ -0,0 +1,182 @@ +package vod + +import ( + "context" + "log" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + sdkErrors "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors" + vod "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vod/v20180717" + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" +) + +func ResourceTencentCloudVodEventConfig() *schema.Resource { + return &schema.Resource{ + Create: resourceTencentCloudVodEventConfigCreate, + Read: resourceTencentCloudVodEventConfigRead, + Update: resourceTencentCloudVodEventConfigUpdate, + Delete: resourceTencentCloudVodEventConfigDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Schema: map[string]*schema.Schema{ + "sub_app_id": { + Required: true, + Type: schema.TypeInt, + Description: "Sub app id.", + }, + + "mode": { + Optional: true, + Computed: true, + Type: schema.TypeString, + Description: "How to receive event notifications. Valid values:\n" + + "- Push: HTTP callback notification;\n" + + "- PULL: Reliable notification based on message queuing.", + }, + + "notification_url": { + Optional: true, + Type: schema.TypeString, + Description: "The address used to receive 3.0 format callbacks when receiving HTTP callback notifications. Note: If you take the NotificationUrl parameter and the value is an empty string, the 3.0 format callback address is cleared.", + }, + + "upload_media_complete_event_switch": { + Optional: true, + Computed: true, + Type: schema.TypeString, + Description: "Whether to receive video upload completion event notification, default `OFF` means to ignore the event notification, `ON` means to receive event notification.", + }, + + "delete_media_complete_event_switch": { + Optional: true, + Computed: true, + Type: schema.TypeString, + Description: "Whether to receive video deletion completion event notification, default `OFF` is to ignore the event notification, `ON` is to receive event notification.", + }, + }, + } +} + +func resourceTencentCloudVodEventConfigCreate(d *schema.ResourceData, meta interface{}) error { + defer tccommon.LogElapsed("resource.tencentcloud_vod_event_config.create")() + defer tccommon.InconsistentCheck(d, meta)() + + var subAppId int + if v, ok := d.GetOk("sub_app_id"); ok { + subAppId = v.(int) + } + + d.SetId(strconv.Itoa(subAppId)) + + return resourceTencentCloudVodEventConfigUpdate(d, meta) +} + +func resourceTencentCloudVodEventConfigRead(d *schema.ResourceData, meta interface{}) error { + defer tccommon.LogElapsed("resource.tencentcloud_vod_event_config.read")() + defer tccommon.InconsistentCheck(d, meta)() + + logId := tccommon.GetLogId(tccommon.ContextNil) + + ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + + service := VodService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + + subAppId, err := strconv.Atoi(d.Id()) + if err != nil { + return err + } + _ = d.Set("sub_app_id", subAppId) + + eventConfig, err := service.DescribeVodEventConfig(ctx, uint64(subAppId)) + if err != nil { + return err + } + + if eventConfig == nil { + d.SetId("") + log.Printf("[WARN]%s resource `VodEventConfig` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) + return nil + } + + if eventConfig.Mode != nil { + _ = d.Set("mode", eventConfig.Mode) + } + + if eventConfig.NotificationUrl != nil { + _ = d.Set("notification_url", eventConfig.NotificationUrl) + } + + if eventConfig.UploadMediaCompleteEventSwitch != nil { + _ = d.Set("upload_media_complete_event_switch", eventConfig.UploadMediaCompleteEventSwitch) + } + + if eventConfig.DeleteMediaCompleteEventSwitch != nil { + _ = d.Set("delete_media_complete_event_switch", eventConfig.DeleteMediaCompleteEventSwitch) + } + + return nil +} + +func resourceTencentCloudVodEventConfigUpdate(d *schema.ResourceData, meta interface{}) error { + defer tccommon.LogElapsed("resource.tencentcloud_vod_event_config.update")() + defer tccommon.InconsistentCheck(d, meta)() + + logId := tccommon.GetLogId(tccommon.ContextNil) + + request := vod.NewModifyEventConfigRequest() + + subAppId, err := strconv.Atoi(d.Id()) + if err != nil { + return err + } + + request.SubAppId = helper.IntUint64(subAppId) + + if v, ok := d.GetOk("mode"); ok { + request.Mode = helper.String(v.(string)) + } + + if v, ok := d.GetOk("notification_url"); ok { + request.NotificationUrl = helper.String(v.(string)) + } + + if v, ok := d.GetOk("upload_media_complete_event_switch"); ok { + request.UploadMediaCompleteEventSwitch = helper.String(v.(string)) + } + + if v, ok := d.GetOk("delete_media_complete_event_switch"); ok { + request.DeleteMediaCompleteEventSwitch = helper.String(v.(string)) + } + + err = resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseVodClient().ModifyEventConfig(request) + if e != nil { + if sdkError, ok := e.(*sdkErrors.TencentCloudSDKError); ok { + if sdkError.Code == "FailedOperation" && sdkError.Message == "invalid vod user" { + return resource.RetryableError(e) + } + } + return resource.NonRetryableError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) + } + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s update vod eventConfig failed, reason:%+v", logId, err) + return err + } + + return resourceTencentCloudVodEventConfigRead(d, meta) +} + +func resourceTencentCloudVodEventConfigDelete(d *schema.ResourceData, meta interface{}) error { + defer tccommon.LogElapsed("resource.tencentcloud_vod_event_config.delete")() + defer tccommon.InconsistentCheck(d, meta)() + + return nil +} diff --git a/tencentcloud/services/vod/resource_tc_vod_event_config.md b/tencentcloud/services/vod/resource_tc_vod_event_config.md new file mode 100644 index 0000000000..86f029c560 --- /dev/null +++ b/tencentcloud/services/vod/resource_tc_vod_event_config.md @@ -0,0 +1,27 @@ +Provide a resource to create a vod event config. + +Example Usage + +```hcl +resource "tencentcloud_vod_sub_application" "sub_application" { + name = "eventconfig-subapplication" + status = "On" + description = "this is sub application" +} + +resource "tencentcloud_vod_event_config" "event_config" { + mode = "PUSH" + notification_url = "http://mydemo.com/receiveevent" + upload_media_complete_event_switch = "ON" + delete_media_complete_event_switch = "ON" + sub_app_id = tonumber(split("#", tencentcloud_vod_sub_application.sub_application.id)[1]) +} +``` + +Import + +VOD event config can be imported using the subAppId, e.g. + +``` +$ terraform import tencentcloud_vod_event_config.foo $subAppId +``` \ No newline at end of file diff --git a/tencentcloud/services/vod/resource_tc_vod_event_config_test.go b/tencentcloud/services/vod/resource_tc_vod_event_config_test.go new file mode 100644 index 0000000000..00ac87ba06 --- /dev/null +++ b/tencentcloud/services/vod/resource_tc_vod_event_config_test.go @@ -0,0 +1,75 @@ +package vod_test + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + tcacctest "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/acctest" +) + +func TestAccTencentCloudVodEventConfigResource_basic(t *testing.T) { + t.Parallel() + resource.Test(t, resource.TestCase{ + PreCheck: func() { tcacctest.AccPreCheck(t) }, + Providers: tcacctest.AccProviders, + Steps: []resource.TestStep{ + { + Config: testAccVodEventConfig, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("tencentcloud_vod_event_config.event_config", "id"), + resource.TestCheckResourceAttrSet("tencentcloud_vod_event_config.event_config", "sub_app_id"), + resource.TestCheckResourceAttr("tencentcloud_vod_event_config.event_config", "mode", "PUSH"), + resource.TestCheckResourceAttr("tencentcloud_vod_event_config.event_config", "notification_url", "http://mydemo.com/receiveevent"), + resource.TestCheckResourceAttr("tencentcloud_vod_event_config.event_config", "upload_media_complete_event_switch", "OFF"), + resource.TestCheckResourceAttr("tencentcloud_vod_event_config.event_config", "delete_media_complete_event_switch", "OFF"), + ), + }, + { + Config: testAccVodEventConfigUpdate, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("tencentcloud_vod_event_config.event_config", "upload_media_complete_event_switch", "ON"), + resource.TestCheckResourceAttr("tencentcloud_vod_event_config.event_config", "delete_media_complete_event_switch", "ON"), + ), + }, + { + ResourceName: "tencentcloud_vod_event_config.event_config", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +const testAccVodEventConfig = ` + +resource "tencentcloud_vod_sub_application" "sub_application" { + name = "eventconfig-subapplication" + status = "On" + description = "this is sub application" +} + +resource "tencentcloud_vod_event_config" "event_config" { + mode = "PUSH" + notification_url = "http://mydemo.com/receiveevent" + sub_app_id = tonumber(split("#", tencentcloud_vod_sub_application.sub_application.id)[1]) +} + +` + +const testAccVodEventConfigUpdate = ` + +resource "tencentcloud_vod_sub_application" "sub_application" { + name = "eventconfig-subapplication" + status = "On" + description = "this is sub application" +} + +resource "tencentcloud_vod_event_config" "event_config" { + mode = "PUSH" + notification_url = "http://mydemo.com/receiveevent" + upload_media_complete_event_switch = "ON" + delete_media_complete_event_switch = "ON" + sub_app_id = tonumber(split("#", tencentcloud_vod_sub_application.sub_application.id)[1]) +} + +` diff --git a/tencentcloud/services/vod/resource_tc_vod_image_sprite_template.go b/tencentcloud/services/vod/resource_tc_vod_image_sprite_template.go index bfa6c9fb0f..82c44a5143 100644 --- a/tencentcloud/services/vod/resource_tc_vod_image_sprite_template.go +++ b/tencentcloud/services/vod/resource_tc_vod_image_sprite_template.go @@ -5,12 +5,14 @@ import ( "fmt" "log" "strconv" + "strings" "time" tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + sdkErrors "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors" vod "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vod/v20180717" "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" @@ -88,7 +90,17 @@ func ResourceTencentCloudVodImageSpriteTemplate() *schema.Resource { "sub_app_id": { Type: schema.TypeInt, Optional: true, - Description: "Subapplication ID in VOD. If you need to access a resource in a subapplication, enter the subapplication ID in this field; otherwise, leave it empty.", + Description: "The VOD [application](https://intl.cloud.tencent.com/document/product/266/14574) ID. For customers who activate VOD service from December 25, 2023, if they want to access resources in a VOD application (whether it's the default application or a newly created one), they must fill in this field with the application ID.", + }, + "format": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Image format, Valid values:\n" + + "- jpg: jpg format;\n" + + "- png: png format;\n" + + "- webp: webp format;\n" + + "Default value: jpg.", }, // computed "create_time": { @@ -101,6 +113,13 @@ func ResourceTencentCloudVodImageSpriteTemplate() *schema.Resource { Computed: true, Description: "Last modified time of template in ISO date format.", }, + "type": { + Type: schema.TypeString, + Computed: true, + Description: "Template type, value range:\n" + + "- Preset: system preset template;\n" + + "- Custom: user-defined templates.", + }, }, } } @@ -125,8 +144,15 @@ func resourceTencentCloudVodImageSpriteTemplateCreate(d *schema.ResourceData, me request.Width = helper.IntUint64(d.Get("width").(int)) request.Height = helper.IntUint64(d.Get("height").(int)) request.ResolutionAdaptive = helper.String(RESOLUTION_ADAPTIVE_TO_STRING[d.Get("resolution_adaptive").(bool)]) + var resourceId string if v, ok := d.GetOk("sub_app_id"); ok { - request.SubAppId = helper.IntUint64(v.(int)) + subAppId := v.(int) + resourceId += helper.IntToStr(subAppId) + resourceId += tccommon.FILED_SP + request.SubAppId = helper.IntUint64(subAppId) + } + if v, ok := d.GetOk("format"); ok { + request.Format = helper.String(v.(string)) } var response *vod.CreateImageSpriteTemplateResponse @@ -135,8 +161,13 @@ func resourceTencentCloudVodImageSpriteTemplateCreate(d *schema.ResourceData, me ratelimit.Check(request.GetAction()) response, err = meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseVodClient().CreateImageSpriteTemplate(request) if err != nil { + if sdkError, ok := err.(*sdkErrors.TencentCloudSDKError); ok { + if sdkError.Code == "FailedOperation" && sdkError.Message == "invalid vod user" { + return resource.RetryableError(err) + } + } log.Printf("[CRITAL]%s api[%s] fail, reason:%s", logId, request.GetAction(), err.Error()) - return tccommon.RetryError(err) + return resource.NonRetryableError(err) } return nil }) @@ -146,7 +177,8 @@ func resourceTencentCloudVodImageSpriteTemplateCreate(d *schema.ResourceData, me if response == nil || response.Response == nil { return fmt.Errorf("for image sprite template creation, response is nil") } - d.SetId(strconv.FormatUint(*response.Response.Definition, 10)) + resourceId += strconv.FormatUint(*response.Response.Definition, 10) + d.SetId(resourceId) return resourceTencentCloudVodImageSpriteTemplateRead(d, meta) } @@ -158,14 +190,21 @@ func resourceTencentCloudVodImageSpriteTemplateRead(d *schema.ResourceData, meta var ( logId = tccommon.GetLogId(tccommon.ContextNil) ctx = context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - id = d.Id() - subAppId = d.Get("sub_app_id").(int) + subAppId int + definition string client = meta.(tccommon.ProviderMeta).GetAPIV3Conn() vodService = VodService{client: client} ) + idSplit := strings.Split(d.Id(), tccommon.FILED_SP) + if len(idSplit) == 2 { + subAppId = helper.StrToInt(idSplit[0]) + definition = idSplit[1] + } else { + definition = d.Id() + } // waiting for refreshing cache time.Sleep(30 * time.Second) - template, has, err := vodService.DescribeImageSpriteTemplatesById(ctx, id, subAppId) + template, has, err := vodService.DescribeImageSpriteTemplatesById(ctx, definition, subAppId) if err != nil { return err } @@ -186,6 +225,11 @@ func resourceTencentCloudVodImageSpriteTemplateRead(d *schema.ResourceData, meta _ = d.Set("resolution_adaptive", *template.ResolutionAdaptive == "open") _ = d.Set("create_time", template.CreateTime) _ = d.Set("update_time", template.UpdateTime) + _ = d.Set("format", template.Format) + _ = d.Set("type", template.Type) + if subAppId != 0 { + _ = d.Set("sub_app_id", subAppId) + } return nil } @@ -196,12 +240,31 @@ func resourceTencentCloudVodImageSpriteTemplateUpdate(d *schema.ResourceData, me var ( logId = tccommon.GetLogId(tccommon.ContextNil) request = vod.NewModifyImageSpriteTemplateRequest() - id = d.Id() changeFlag = false + subAppId int + definition string ) - idUint, _ := strconv.ParseUint(id, 0, 64) - request.Definition = &idUint + idSplit := strings.Split(d.Id(), tccommon.FILED_SP) + if len(idSplit) == 2 { + subAppId = helper.StrToInt(idSplit[0]) + definition = idSplit[1] + request.SubAppId = helper.IntUint64(subAppId) + } else { + definition = d.Id() + if v, ok := d.GetOk("sub_app_id"); ok { + request.SubAppId = helper.IntUint64(v.(int)) + } + } + request.Definition = helper.StrToUint64Point(definition) + immutableArgs := []string{"sub_app_id"} + + for _, v := range immutableArgs { + if d.HasChange(v) { + return fmt.Errorf("argument `%s` cannot be changed", v) + } + } + if d.HasChange("sample_type") { changeFlag = true request.SampleType = helper.String(d.Get("sample_type").(string)) @@ -236,9 +299,9 @@ func resourceTencentCloudVodImageSpriteTemplateUpdate(d *schema.ResourceData, me request.Height = helper.IntUint64(d.Get("height").(int)) request.ResolutionAdaptive = helper.String(RESOLUTION_ADAPTIVE_TO_STRING[d.Get("resolution_adaptive").(bool)]) } - if d.HasChange("sub_app_id") { + if d.HasChange("format") { changeFlag = true - request.SubAppId = helper.IntUint64(d.Get("sub_app_id").(int)) + request.Format = helper.String(d.Get("format").(string)) } if changeFlag { @@ -268,12 +331,25 @@ func resourceTencentCloudVodImageSpriteTemplateDelete(d *schema.ResourceData, me logId := tccommon.GetLogId(tccommon.ContextNil) ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - id := d.Id() + var ( + subAppId int + definition string + ) + idSplit := strings.Split(d.Id(), tccommon.FILED_SP) + if len(idSplit) == 2 { + subAppId = helper.StrToInt(idSplit[0]) + definition = idSplit[1] + } else { + definition = d.Id() + if v, ok := d.GetOk("sub_app_id"); ok { + subAppId = v.(int) + } + } vodService := VodService{ client: meta.(tccommon.ProviderMeta).GetAPIV3Conn(), } - if err := vodService.DeleteImageSpriteTemplate(ctx, id, uint64(d.Get("sub_app_id").(int))); err != nil { + if err := vodService.DeleteImageSpriteTemplate(ctx, definition, uint64(subAppId)); err != nil { return err } diff --git a/tencentcloud/services/vod/resource_tc_vod_image_sprite_template.md b/tencentcloud/services/vod/resource_tc_vod_image_sprite_template.md index d40212a128..75f64e9ce5 100644 --- a/tencentcloud/services/vod/resource_tc_vod_image_sprite_template.md +++ b/tencentcloud/services/vod/resource_tc_vod_image_sprite_template.md @@ -3,8 +3,15 @@ Provide a resource to create a VOD image sprite template. Example Usage ```hcl +resource "tencentcloud_vod_sub_application" "sub_application" { + name = "image-sprite-subapplication" + status = "On" + description = "this is sub application" +} + resource "tencentcloud_vod_image_sprite_template" "foo" { sample_type = "Percent" + sub_app_id = tonumber(split("#", tencentcloud_vod_sub_application.sub_application.id)[1]) sample_interval = 10 row_count = 3 column_count = 3 @@ -19,8 +26,8 @@ resource "tencentcloud_vod_image_sprite_template" "foo" { Import -VOD image sprite template can be imported using the id, e.g. +VOD image sprite template can be imported using the id($subAppId#$templateId), e.g. ``` -$ terraform import tencentcloud_vod_image_sprite_template.foo 51156 +$ terraform import tencentcloud_vod_image_sprite_template.foo $subAppId#$templateId ``` \ No newline at end of file diff --git a/tencentcloud/services/vod/resource_tc_vod_image_sprite_template_test.go b/tencentcloud/services/vod/resource_tc_vod_image_sprite_template_test.go index 23b5cf0805..3a1fc1624d 100644 --- a/tencentcloud/services/vod/resource_tc_vod_image_sprite_template_test.go +++ b/tencentcloud/services/vod/resource_tc_vod_image_sprite_template_test.go @@ -3,10 +3,12 @@ package vod_test import ( "context" "fmt" + "strings" "testing" tcacctest "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/acctest" tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" svcvod "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/services/vod" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" @@ -23,7 +25,6 @@ func TestAccTencentCloudVodImageSpriteTemplateResource(t *testing.T) { { Config: testAccVodImageSpriteTemplate, Check: resource.ComposeTestCheckFunc( - testAccCheckVodImageSpriteTemplateExists("tencentcloud_vod_image_sprite_template.foo"), resource.TestCheckResourceAttr("tencentcloud_vod_image_sprite_template.foo", "sample_type", "Percent"), resource.TestCheckResourceAttr("tencentcloud_vod_image_sprite_template.foo", "sample_interval", "10"), resource.TestCheckResourceAttr("tencentcloud_vod_image_sprite_template.foo", "row_count", "3"), @@ -34,8 +35,10 @@ func TestAccTencentCloudVodImageSpriteTemplateResource(t *testing.T) { resource.TestCheckResourceAttr("tencentcloud_vod_image_sprite_template.foo", "width", "128"), resource.TestCheckResourceAttr("tencentcloud_vod_image_sprite_template.foo", "height", "128"), resource.TestCheckResourceAttr("tencentcloud_vod_image_sprite_template.foo", "resolution_adaptive", "false"), + resource.TestCheckResourceAttr("tencentcloud_vod_image_sprite_template.foo", "format", "jpg"), resource.TestCheckResourceAttrSet("tencentcloud_vod_image_sprite_template.foo", "create_time"), resource.TestCheckResourceAttrSet("tencentcloud_vod_image_sprite_template.foo", "update_time"), + resource.TestCheckResourceAttrSet("tencentcloud_vod_image_sprite_template.foo", "type"), ), }, { @@ -54,10 +57,9 @@ func TestAccTencentCloudVodImageSpriteTemplateResource(t *testing.T) { ), }, { - ResourceName: "tencentcloud_vod_image_sprite_template.foo", - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"sub_app_id"}, + ResourceName: "tencentcloud_vod_image_sprite_template.foo", + ImportState: true, + ImportStateVerify: true, }, }, }) @@ -72,9 +74,13 @@ func testAccCheckVodImageSpriteTemplateDestroy(s *terraform.State) error { if rs.Type != "tencentcloud_vod_image_sprite_template" { continue } + idSplit := strings.Split(rs.Primary.ID, tccommon.FILED_SP) + subAppId := helper.StrToInt(idSplit[0]) + definition := idSplit[1] var ( filter = map[string]interface{}{ - "definitions": []string{rs.Primary.ID}, + "definitions": []string{definition}, + "sub_appid": subAppId, } ) @@ -103,9 +109,13 @@ func testAccCheckVodImageSpriteTemplateExists(n string) resource.TestCheckFunc { return fmt.Errorf("vod image sprite template id is not set") } vodService := svcvod.NewVodService(tcacctest.AccProvider.Meta().(tccommon.ProviderMeta).GetAPIV3Conn()) + idSplit := strings.Split(rs.Primary.ID, tccommon.FILED_SP) + subAppId := helper.StrToInt(idSplit[0]) + definition := idSplit[1] var ( filter = map[string]interface{}{ - "definitions": []string{rs.Primary.ID}, + "definitions": []string{definition}, + "sub_appid": subAppId, } ) templates, err := vodService.DescribeImageSpriteTemplatesByFilter(ctx, filter) @@ -120,8 +130,15 @@ func testAccCheckVodImageSpriteTemplateExists(n string) resource.TestCheckFunc { } const testAccVodImageSpriteTemplate = ` +resource "tencentcloud_vod_sub_application" "sub_application" { + name = "image-sprite-subapplication" + status = "On" + description = "this is sub application" +} + resource "tencentcloud_vod_image_sprite_template" "foo" { sample_type = "Percent" + sub_app_id = tonumber(split("#", tencentcloud_vod_sub_application.sub_application.id)[1]) sample_interval = 10 row_count = 3 column_count = 3 @@ -135,8 +152,15 @@ resource "tencentcloud_vod_image_sprite_template" "foo" { ` const testAccVodImageSpriteTemplateUpdate = ` +resource "tencentcloud_vod_sub_application" "sub_application" { + name = "image-sprite-subapplication" + status = "On" + description = "this is sub application" +} + resource "tencentcloud_vod_image_sprite_template" "foo" { sample_type = "Time" + sub_app_id = tonumber(split("#", tencentcloud_vod_sub_application.sub_application.id)[1]) sample_interval = 11 row_count = 4 column_count = 4 diff --git a/tencentcloud/services/vod/resource_tc_vod_procedure_template.go b/tencentcloud/services/vod/resource_tc_vod_procedure_template.go index 7fb8897cea..3523cec212 100644 --- a/tencentcloud/services/vod/resource_tc_vod_procedure_template.go +++ b/tencentcloud/services/vod/resource_tc_vod_procedure_template.go @@ -2,6 +2,7 @@ package vod import ( "context" + "fmt" "log" "strconv" "strings" @@ -43,7 +44,7 @@ func ResourceTencentCloudVodProcedureTemplate() *schema.Resource { "sub_app_id": { Type: schema.TypeInt, Optional: true, - Description: "Subapplication ID in VOD. For customers who activate VOD from December 25, 2023, if they access the resources in the VOD application (whether it is the default application or the newly created application), you must fill in this field as Application ID.", + Description: "The VOD [application](https://intl.cloud.tencent.com/document/product/266/14574) ID. For customers who activate VOD service from December 25, 2023, if they want to access resources in a VOD application (whether it's the default application or a newly created one), they must fill in this field with the application ID.", }, "media_process_task": { Type: schema.TypeList, @@ -121,6 +122,68 @@ func ResourceTencentCloudVodProcedureTemplate() *schema.Resource { }, }, }, + "trace_watermark": { + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Description: "Digital watermark.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "switch": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Whether to use digital watermarks. This parameter is required. Valid values: ON, OFF.", + }, + }, + }, + }, + "copy_right_watermark": { + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Description: "opyright watermark.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "text": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Copyright information, maximum length is 200 characters.", + }, + }, + }, + }, + "head_tail_list": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Description: "List of video opening/closing credits configuration template IDs. You can enter up to 10 IDs.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "definition": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Video opening/closing credits configuration template ID.", + }, + }, + }, + }, + "start_time_offset": { + Type: schema.TypeFloat, + Optional: true, + Computed: true, + Description: "Start time offset of blur in seconds. If this parameter is left empty or `0` is entered, the blur will appear upon the first video frame. If this parameter is left empty or `0` is entered, the blur will appear upon the first video frame; If this value is greater than `0` (e.g., n), the blur will appear at second n after the first video frame; If this value is smaller than `0` (e.g., -n), the blur will appear at second n before the last video frame.", + }, + "end_time_offset": { + Type: schema.TypeFloat, + Optional: true, + Computed: true, + Description: "End time offset of blur in seconds. If this parameter is left empty or `0` is entered, the blur will exist till the last video frame; If this value is greater than `0` (e.g., n), the blur will exist till second n; If this value is smaller than `0` (e.g., -n), the blur will exist till second n before the last video frame.", + }, }, }, }, @@ -174,6 +237,15 @@ func ResourceTencentCloudVodProcedureTemplate() *schema.Resource { Description: "List of up to `10` image or text watermarks. Note: this field may return null, indicating that no valid values can be obtained.", Elem: VodWatermarkResource(), }, + "time_offset_list": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Description: "List of time points for screencapturing in milliseconds. Note: this field may return null, indicating that no valid values can be obtained.", + Elem: &schema.Schema{ + Type: schema.TypeFloat, + }, + }, }, }, }, @@ -262,12 +334,83 @@ func ResourceTencentCloudVodProcedureTemplate() *schema.Resource { Description: "List of up to `10` image or text watermarks. Note: this field may return null, indicating that no valid values can be obtained.", Elem: VodWatermarkResource(), }, + "subtitle_list": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Description: "Subtitle list, element is subtitle ID, support multiple subtitles, up to 16.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, }, }, }, }, }, }, + "ai_analysis_task": { + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Description: "Parameter of AI-based content analysis task.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "definition": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Video content analysis template ID.", + }, + }, + }, + }, + "ai_recognition_task": { + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Description: "Type parameter of AI-based content recognition task.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "definition": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Intelligent video recognition template ID.", + }, + }, + }, + }, + "review_audio_video_task": { + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Description: "Type parameter of AI-based content recognition task.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "review_contents": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "The type of moderated content. Valid values:\n" + + "- `Media`: The original audio/video;\n" + + "- `Cover`: Thumbnails.", + }, + "definition": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Review template.", + }, + }, + }, + }, "create_time": { Type: schema.TypeString, Computed: true, @@ -278,6 +421,13 @@ func ResourceTencentCloudVodProcedureTemplate() *schema.Resource { Computed: true, Description: "Last modified time of template in ISO date format.", }, + "type": { + Type: schema.TypeString, + Computed: true, + Description: "Template type, value range:\n" + + "- Preset: system preset template;\n" + + "- Custom: user-defined templates.", + }, }, } } @@ -407,6 +557,68 @@ func generateMediaProcessTask(d *schema.ResourceData) (mediaReq *vod.MediaProces }(item["definition"].(string)), WatermarkSet: genWatermarkList(item), MosaicSet: genMosaicList(item), + TraceWatermark: func() *vod.TraceWatermarkInput { + if _, ok := item["trace_watermark"]; !ok { + return nil + } + traceWatermarks := item["trace_watermark"].([]interface{}) + if len(traceWatermarks) <= 0 { + return nil + } + traceWatermarkInput := &vod.TraceWatermarkInput{} + traceWatermarkItem := traceWatermarks[0].(map[string]interface{}) + if v, ok := traceWatermarkItem["switch"]; ok { + traceWatermarkInput.Switch = helper.String(v.(string)) + } + return traceWatermarkInput + }(), + CopyRightWatermark: func() *vod.CopyRightWatermarkInput { + if _, ok := item["copy_right_watermark"]; !ok { + return nil + } + copyRightWatermarks := item["copy_right_watermark"].([]interface{}) + if len(copyRightWatermarks) <= 0 { + return nil + } + + copyRightWatermarkInput := &vod.CopyRightWatermarkInput{} + copyRightWatermarkItem := copyRightWatermarks[0].(map[string]interface{}) + if vv, ok := copyRightWatermarkItem["text"]; ok { + copyRightWatermarkInput = &vod.CopyRightWatermarkInput{ + Text: helper.String(vv.(string)), + } + } + return copyRightWatermarkInput + }(), + HeadTailSet: func() (list []*vod.HeadTailTaskInput) { + if _, ok := item["head_tail_list"]; !ok { + return + } + headTailSet := item["head_tail_list"].([]interface{}) + list = make([]*vod.HeadTailTaskInput, 0, len(headTailSet)) + for _, headTail := range headTailSet { + headTailMap := headTail.(map[string]interface{}) + list = append(list, &vod.HeadTailTaskInput{ + Definition: func(str string) *int64 { + definition, _ := strconv.ParseInt(str, 0, 64) + return &definition + }(headTailMap["definition"].(string)), + }) + } + return + }(), + StartTimeOffset: func() *float64 { + if _, ok := item["start_time_offset"]; !ok { + return nil + } + return helper.Float64(item["start_time_offset"].(float64)) + }(), + EndTimeOffset: func() *float64 { + if _, ok := item["end_time_offset"]; !ok { + return nil + } + return helper.Float64(item["end_time_offset"].(float64)) + }(), }) } mediaReq.TranscodeTaskSet = transcodeReq @@ -451,6 +663,17 @@ func generateMediaProcessTask(d *schema.ResourceData) (mediaReq *vod.MediaProces } return list }(), + TimeOffsetSet: func() (list []*float64) { + if _, ok := item["time_offset_list"]; !ok { + return nil + } + timeOffsetSet := item["time_offset_list"].([]interface{}) + list = make([]*float64, 0, len(timeOffsetSet)) + for _, timeOffset := range timeOffsetSet { + list = append(list, helper.Float64(timeOffset.(float64))) + } + return list + }(), }) } mediaReq.SnapshotByTimeOffsetTaskSet = snapshotReq @@ -516,6 +739,17 @@ func generateMediaProcessTask(d *schema.ResourceData) (mediaReq *vod.MediaProces return &idUint }(item["definition"].(string)), WatermarkSet: genWatermarkList(item), + SubtitleSet: func() (list []*string) { + if _, ok := item["subtitle_list"]; !ok { + return nil + } + subtitleList := item["subtitle_list"].([]interface{}) + list = make([]*string, 0, len(subtitleList)) + for _, subTitle := range subtitleList { + list = append(list, helper.String(subTitle.(string))) + } + return list + }(), }) } mediaReq.AdaptiveDynamicStreamingTaskSet = adaptiveReq @@ -549,7 +783,44 @@ func resourceTencentCloudVodProcedureTemplateCreate(d *schema.ResourceData, meta mediaReq := generateMediaProcessTask(d) request.MediaProcessTask = mediaReq } + //ai_analysis_task + if aiAnalysisTask, ok := d.GetOk("ai_analysis_task"); ok { + aiAnalysisTaskList := aiAnalysisTask.([]interface{}) + aiAnalysisTaskItem := aiAnalysisTaskList[0].(map[string]interface{}) + + request.AiAnalysisTask = &vod.AiAnalysisTaskInput{ + Definition: helper.StrToUint64Point(aiAnalysisTaskItem["definition"].(string)), + } + } + //ai_recognition_task + if aiRecognitionTask, ok := d.GetOk("ai_recognition_task"); ok { + aiRecognitionTaskList := aiRecognitionTask.([]interface{}) + aiRecognitionTaskItem := aiRecognitionTaskList[0].(map[string]interface{}) + + request.AiRecognitionTask = &vod.AiRecognitionTaskInput{ + Definition: helper.StrToUint64Point(aiRecognitionTaskItem["definition"].(string)), + } + } + //review_audio_video_task + if reviewAudioVideoTask, ok := d.GetOk("review_audio_video_task"); ok { + reviewAudioVideoTaskList := reviewAudioVideoTask.([]interface{}) + reviewAudioVideoTaskItem := reviewAudioVideoTaskList[0].(map[string]interface{}) + request.ReviewAudioVideoTask = &vod.ProcedureReviewAudioVideoTaskInput{ + Definition: helper.StrToUint64Point(reviewAudioVideoTaskItem["definition"].(string)), + ReviewContents: func() (list []*string) { + if _, ok := reviewAudioVideoTaskItem["review_contents"]; !ok { + return + } + reviewContentList := reviewAudioVideoTaskItem["review_contents"].([]interface{}) + list = make([]*string, 0, len(reviewContentList)) + for _, reviewContent := range reviewContentList { + list = append(list, helper.String(reviewContent.(string))) + } + return + }(), + } + } var err error err = resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { ratelimit.Check(request.GetAction()) @@ -599,6 +870,7 @@ func resourceTencentCloudVodProcedureTemplateRead(d *schema.ResourceData, meta i } _ = d.Set("name", template.Name) + _ = d.Set("type", template.Type) _ = d.Set("comment", template.Comment) _ = d.Set("create_time", template.CreateTime) _ = d.Set("update_time", template.UpdateTime) @@ -648,6 +920,48 @@ func resourceTencentCloudVodProcedureTemplateRead(d *schema.ResourceData, meta i } return mosaicList }(), + "trace_watermark": func() interface{} { + if item.TraceWatermark == nil { + return nil + } + traceWatermark := map[string]interface{}{ + "switch": item.TraceWatermark.Switch, + } + return []interface{}{traceWatermark} + }(), + "copy_right_watermark": func() interface{} { + if item.CopyRightWatermark == nil { + return nil + } + copyRightWatermark := map[string]interface{}{ + "text": item.CopyRightWatermark.Text, + } + return []interface{}{copyRightWatermark} + }(), + "head_tail_list": func() interface{} { + if item.HeadTailSet == nil { + return nil + } + headTailList := make([]interface{}, 0, len(item.HeadTailSet)) + for _, headTail := range item.HeadTailSet { + headTailList = append(headTailList, map[string]interface{}{ + "definition": headTail.Definition, + }) + } + return headTailList + }(), + "start_time_offset": func() *float64 { + if item.StartTimeOffset == nil { + return nil + } + return item.StartTimeOffset + }(), + "end_time_offset": func() *float64 { + if item.EndTimeOffset == nil { + return nil + } + return item.EndTimeOffset + }(), }) } mediaProcessTaskElem["transcode_task_list"] = list @@ -696,6 +1010,16 @@ func resourceTencentCloudVodProcedureTemplateRead(d *schema.ResourceData, meta i } return extList }(), + "time_offset_list": func() interface{} { + if item.TimeOffsetSet == nil { + return nil + } + timeOffsetList := make([]interface{}, 0, len(item.TimeOffsetSet)) + for _, timeOffset := range item.TimeOffsetSet { + timeOffsetList = append(timeOffsetList, timeOffset) + } + return timeOffsetList + }(), }) } mediaProcessTaskElem["snapshot_by_time_offset_task_list"] = list @@ -786,6 +1110,16 @@ func resourceTencentCloudVodProcedureTemplateRead(d *schema.ResourceData, meta i } return waterList }(), + "subtitle_list": func() interface{} { + if item.SubtitleSet == nil { + return nil + } + subtitleList := make([]interface{}, 0, len(item.SubtitleSet)) + for _, subtitleV := range item.SubtitleSet { + subtitleList = append(subtitleList, subtitleV) + } + return subtitleList + }(), }) } mediaProcessTaskElem["adaptive_dynamic_streaming_task_list"] = list @@ -793,7 +1127,30 @@ func resourceTencentCloudVodProcedureTemplateRead(d *schema.ResourceData, meta i _ = d.Set("media_process_task", []interface{}{mediaProcessTaskElem}) } - + aiAnalysisTask := make(map[string]interface{}) + if template.AiAnalysisTask != nil && template.AiAnalysisTask.Definition != nil { + aiAnalysisTask["definition"] = template.AiAnalysisTask.Definition + } + _ = d.Set("ai_analysis_task", []interface{}{aiAnalysisTask}) + aiRecognitionTask := make(map[string]interface{}) + if template.AiRecognitionTask != nil && template.AiRecognitionTask.Definition != nil { + aiRecognitionTask["definition"] = template.AiRecognitionTask.Definition + } + _ = d.Set("ai_recognition_task", []interface{}{aiRecognitionTask}) + reviewAudioVideoTask := make(map[string]interface{}) + if template.ReviewAudioVideoTask != nil { + if template.ReviewAudioVideoTask.Definition != nil { + reviewAudioVideoTask["definition"] = template.ReviewAudioVideoTask.Definition + } + if template.ReviewAudioVideoTask.ReviewContents != nil { + reviewContentList := make([]string, 0, len(template.ReviewAudioVideoTask.ReviewContents)) + for _, revireviewContent := range template.ReviewAudioVideoTask.ReviewContents { + reviewContentList = append(reviewContentList, *revireviewContent) + } + reviewAudioVideoTask["review_contents"] = reviewContentList + } + } + _ = d.Set("review_audio_video_task", []interface{}{reviewAudioVideoTask}) return nil } @@ -819,6 +1176,14 @@ func resourceTencentCloudVodProcedureTemplateUpdate(d *schema.ResourceData, meta } } + immutableArgs := []string{"sub_app_id"} + + for _, v := range immutableArgs { + if d.HasChange(v) { + return fmt.Errorf("argument `%s` cannot be changed", v) + } + } + if d.HasChange("comment") { changeFlag = true request.Comment = helper.String(d.Get("comment").(string)) @@ -830,6 +1195,51 @@ func resourceTencentCloudVodProcedureTemplateUpdate(d *schema.ResourceData, meta request.MediaProcessTask = mediaReq } + if d.HasChange("ai_analysis_task") { + changeFlag = true + if aiAnalysisTask, ok := d.GetOk("ai_analysis_task"); ok { + aiAnalysisTaskList := aiAnalysisTask.([]interface{}) + aiAnalysisTaskItem := aiAnalysisTaskList[0].(map[string]interface{}) + + request.AiAnalysisTask = &vod.AiAnalysisTaskInput{ + Definition: helper.StrToUint64Point(aiAnalysisTaskItem["definition"].(string)), + } + } + } + + if d.HasChange("ai_recognition_task") { + changeFlag = true + if aiRecognitionTask, ok := d.GetOk("ai_recognition_task"); ok { + aiRecognitionTaskList := aiRecognitionTask.([]interface{}) + aiRecognitionTaskItem := aiRecognitionTaskList[0].(map[string]interface{}) + + request.AiRecognitionTask = &vod.AiRecognitionTaskInput{ + Definition: helper.StrToUint64Point(aiRecognitionTaskItem["definition"].(string)), + } + } + } + if d.HasChange("review_audio_video_task") { + changeFlag = true + if reviewAudioVideoTask, ok := d.GetOk("review_audio_video_task"); ok { + reviewAudioVideoTaskList := reviewAudioVideoTask.([]interface{}) + reviewAudioVideoTaskItem := reviewAudioVideoTaskList[0].(map[string]interface{}) + request.ReviewAudioVideoTask = &vod.ProcedureReviewAudioVideoTaskInput{ + Definition: helper.StrToUint64Point(reviewAudioVideoTaskItem["definition"].(string)), + ReviewContents: func() (list []*string) { + if _, ok := reviewAudioVideoTaskItem["review_contents"]; !ok { + return + } + reviewContentList := reviewAudioVideoTaskItem["review_contents"].([]interface{}) + list = make([]*string, 0, len(reviewContentList)) + for _, reviewContent := range reviewContentList { + list = append(list, helper.String(reviewContent.(string))) + } + return + }(), + } + } + } + if changeFlag { var err error err = resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { diff --git a/tencentcloud/services/vod/resource_tc_vod_procedure_template.md b/tencentcloud/services/vod/resource_tc_vod_procedure_template.md index 8ba2f1a452..0cff89e197 100644 --- a/tencentcloud/services/vod/resource_tc_vod_procedure_template.md +++ b/tencentcloud/services/vod/resource_tc_vod_procedure_template.md @@ -3,9 +3,16 @@ Provide a resource to create a VOD procedure template. Example Usage ```hcl +resource "tencentcloud_vod_sub_application" "sub_application" { + name = "procedure-subapplication" + status = "On" + description = "this is sub application" +} + resource "tencentcloud_vod_adaptive_dynamic_streaming_template" "foo" { format = "HLS" name = "tf-adaptive" + sub_app_id = tonumber(split("#", tencentcloud_vod_sub_application.sub_application.id)[1]) drm_type = "SimpleAES" disable_higher_video_bitrate = false disable_higher_video_resolution = false @@ -13,21 +20,16 @@ resource "tencentcloud_vod_adaptive_dynamic_streaming_template" "foo" { stream_info { video { - codec = "libx265" - fps = 4 - bitrate = 129 - resolution_adaptive = false - width = 128 - height = 128 - fill_type = "stretch" + codec = "libx264" + fps = 3 + bitrate = 128 } audio { - codec = "libmp3lame" - bitrate = 129 - sample_rate = 44100 - audio_channel = "dual" + codec = "libfdk_aac" + bitrate = 128 + sample_rate = 32000 } - remove_audio = false + remove_audio = true } stream_info { video { @@ -41,12 +43,16 @@ resource "tencentcloud_vod_adaptive_dynamic_streaming_template" "foo" { sample_rate = 44100 } remove_audio = true + tehd_config { + type = "TEHD-100" + } } } resource "tencentcloud_vod_snapshot_by_time_offset_template" "foo" { name = "tf-snapshot" - width = 130 + sub_app_id = tonumber(split("#", tencentcloud_vod_sub_application.sub_application.id)[1]) + width = 128 height = 128 resolution_adaptive = false format = "png" @@ -56,6 +62,7 @@ resource "tencentcloud_vod_snapshot_by_time_offset_template" "foo" { resource "tencentcloud_vod_image_sprite_template" "foo" { sample_type = "Percent" + sub_app_id = tonumber(split("#", tencentcloud_vod_sub_application.sub_application.id)[1]) sample_interval = 10 row_count = 3 column_count = 3 @@ -67,28 +74,56 @@ resource "tencentcloud_vod_image_sprite_template" "foo" { resolution_adaptive = false } -resource "tencentcloud_vod_sub_application" "sub_application" { - name = "subapplication" - status = "On" - description = "this is sub application" +resource "tencentcloud_vod_transcode_template" "transcode_template" { + container = "mp4" + sub_app_id = tonumber(split("#", tencentcloud_vod_sub_application.sub_application.id)[1]) + name = "720pTranscodeTemplate" + comment = "test transcode mp4 720p update" + remove_video = 0 + remove_audio = 0 + video_template { + codec = "libx264" + fps = 26 + bitrate = 1000 + resolution_adaptive = "open" + width = 0 + height = 720 + fill_type = "stretch" + vcrf = 1 + gop = 250 + preserve_hdr_switch = "OFF" + codec_tag = "hvc1" + + } + audio_template { + codec = "libfdk_aac" + bitrate = 128 + sample_rate = 44100 + audio_channel = 2 + + } + segment_type = "ts" } resource "tencentcloud_vod_procedure_template" "foo" { - name = "tf-procedure" + name = "tf-procedure0" comment = "test" sub_app_id = tonumber(split("#", tencentcloud_vod_sub_application.sub_application.id)[1]) media_process_task { adaptive_dynamic_streaming_task_list { - definition = tencentcloud_vod_adaptive_dynamic_streaming_template.foo.id + definition = tonumber(split("#", tencentcloud_vod_adaptive_dynamic_streaming_template.foo.id)[1]) } snapshot_by_time_offset_task_list { - definition = tencentcloud_vod_snapshot_by_time_offset_template.foo.id + definition = tonumber(split("#", tencentcloud_vod_snapshot_by_time_offset_template.foo.id)[1]) ext_time_offset_list = [ "3.5s" ] } image_sprite_task_list { - definition = tencentcloud_vod_image_sprite_template.foo.id + definition = tonumber(split("#", tencentcloud_vod_image_sprite_template.foo.id)[1]) + } + transcode_task_list { + definition = tonumber(split("#", tencentcloud_vod_transcode_template.transcode_template.id)[1]) } } } diff --git a/tencentcloud/services/vod/resource_tc_vod_procedure_template_test.go b/tencentcloud/services/vod/resource_tc_vod_procedure_template_test.go index df8385cc41..282b7340bf 100644 --- a/tencentcloud/services/vod/resource_tc_vod_procedure_template_test.go +++ b/tencentcloud/services/vod/resource_tc_vod_procedure_template_test.go @@ -48,14 +48,12 @@ func init() { func TestAccTencentCloudVodProcedureTemplateResource(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ - PreCheck: func() { tcacctest.AccPreCheck(t) }, - Providers: tcacctest.AccProviders, - CheckDestroy: testAccCheckVodProcedureTemplateDestroy, + PreCheck: func() { tcacctest.AccPreCheck(t) }, + Providers: tcacctest.AccProviders, Steps: []resource.TestStep{ { Config: testAccVodProcedureTemplate, Check: resource.ComposeTestCheckFunc( - testAccCheckVodProcedureTemplateExists("tencentcloud_vod_procedure_template.foo"), resource.TestCheckResourceAttr("tencentcloud_vod_procedure_template.foo", "name", "tf-procedure0"), resource.TestCheckResourceAttr("tencentcloud_vod_procedure_template.foo", "comment", "test"), resource.TestCheckResourceAttr("tencentcloud_vod_procedure_template.foo", "media_process_task.#", "1"), @@ -67,6 +65,7 @@ func TestAccTencentCloudVodProcedureTemplateResource(t *testing.T) { resource.TestCheckResourceAttrSet("tencentcloud_vod_procedure_template.foo", "media_process_task.0.adaptive_dynamic_streaming_task_list.0.definition"), resource.TestCheckResourceAttrSet("tencentcloud_vod_procedure_template.foo", "media_process_task.0.snapshot_by_time_offset_task_list.0.definition"), resource.TestCheckResourceAttrSet("tencentcloud_vod_procedure_template.foo", "media_process_task.0.image_sprite_task_list.0.definition"), + resource.TestCheckResourceAttrSet("tencentcloud_vod_procedure_template.foo", "media_process_task.0.transcode_task_list.0.definition"), resource.TestCheckResourceAttrSet("tencentcloud_vod_procedure_template.foo", "create_time"), resource.TestCheckResourceAttrSet("tencentcloud_vod_procedure_template.foo", "update_time"), ), @@ -160,56 +159,254 @@ func testAccCheckVodProcedureTemplateExists(n string) resource.TestCheckFunc { } } -const testAccVodProcedureTemplate = testAccVodAdaptiveDynamicStreamingTemplate + testAccVodSnapshotByTimeOffsetTemplate + testAccVodImageSpriteTemplate + ` +const testAccVodProcedureTemplate = ` resource "tencentcloud_vod_sub_application" "sub_application" { - name = "subapplication" + name = "procedure-subapplication" status = "On" description = "this is sub application" } +resource "tencentcloud_vod_adaptive_dynamic_streaming_template" "foo" { + format = "HLS" + name = "tf-adaptive" + sub_app_id = tonumber(split("#", tencentcloud_vod_sub_application.sub_application.id)[1]) + drm_type = "SimpleAES" + disable_higher_video_bitrate = false + disable_higher_video_resolution = false + comment = "test" + + stream_info { + video { + codec = "libx264" + fps = 3 + bitrate = 128 + } + audio { + codec = "libfdk_aac" + bitrate = 128 + sample_rate = 32000 + } + remove_audio = true + } + stream_info { + video { + codec = "libx264" + fps = 4 + bitrate = 256 + } + audio { + codec = "libfdk_aac" + bitrate = 256 + sample_rate = 44100 + } + remove_audio = true + tehd_config { + type = "TEHD-100" + } + } +} + +resource "tencentcloud_vod_snapshot_by_time_offset_template" "foo" { + name = "tf-snapshot" + sub_app_id = tonumber(split("#", tencentcloud_vod_sub_application.sub_application.id)[1]) + width = 128 + height = 128 + resolution_adaptive = false + format = "png" + comment = "test" + fill_type = "white" +} + +resource "tencentcloud_vod_image_sprite_template" "foo" { + sample_type = "Percent" + sub_app_id = tonumber(split("#", tencentcloud_vod_sub_application.sub_application.id)[1]) + sample_interval = 10 + row_count = 3 + column_count = 3 + name = "tf-sprite" + comment = "test" + fill_type = "stretch" + width = 128 + height = 128 + resolution_adaptive = false +} + +resource "tencentcloud_vod_transcode_template" "transcode_template" { + container = "mp4" + sub_app_id = tonumber(split("#", tencentcloud_vod_sub_application.sub_application.id)[1]) + name = "720pTranscodeTemplate" + comment = "test transcode mp4 720p update" + remove_video = 0 + remove_audio = 0 + video_template { + codec = "libx264" + fps = 26 + bitrate = 1000 + resolution_adaptive = "open" + width = 0 + height = 720 + fill_type = "stretch" + vcrf = 1 + gop = 250 + preserve_hdr_switch = "OFF" + codec_tag = "hvc1" + + } + audio_template { + codec = "libfdk_aac" + bitrate = 128 + sample_rate = 44100 + audio_channel = 2 + + } + segment_type = "ts" +} + resource "tencentcloud_vod_procedure_template" "foo" { name = "tf-procedure0" comment = "test" sub_app_id = tonumber(split("#", tencentcloud_vod_sub_application.sub_application.id)[1]) media_process_task { adaptive_dynamic_streaming_task_list { - definition = tencentcloud_vod_adaptive_dynamic_streaming_template.foo.id + definition = tonumber(split("#", tencentcloud_vod_adaptive_dynamic_streaming_template.foo.id)[1]) } snapshot_by_time_offset_task_list { - definition = tencentcloud_vod_snapshot_by_time_offset_template.foo.id + definition = tonumber(split("#", tencentcloud_vod_snapshot_by_time_offset_template.foo.id)[1]) ext_time_offset_list = [ "3.5s" ] } image_sprite_task_list { - definition = tencentcloud_vod_image_sprite_template.foo.id + definition = tonumber(split("#", tencentcloud_vod_image_sprite_template.foo.id)[1]) + } + transcode_task_list { + definition = tonumber(split("#", tencentcloud_vod_transcode_template.transcode_template.id)[1]) } } } ` -const testAccVodProcedureTemplateUpdate = testAccVodAdaptiveDynamicStreamingTemplate + testAccVodSnapshotByTimeOffsetTemplate + testAccVodImageSpriteTemplate + ` +const testAccVodProcedureTemplateUpdate = ` resource "tencentcloud_vod_sub_application" "sub_application" { - name = "subapplication" + name = "procedure-subapplication" status = "On" description = "this is sub application" } +resource "tencentcloud_vod_adaptive_dynamic_streaming_template" "foo" { + format = "HLS" + name = "tf-adaptive" + sub_app_id = tonumber(split("#", tencentcloud_vod_sub_application.sub_application.id)[1]) + drm_type = "SimpleAES" + disable_higher_video_bitrate = false + disable_higher_video_resolution = false + comment = "test" + + stream_info { + video { + codec = "libx264" + fps = 3 + bitrate = 128 + } + audio { + codec = "libfdk_aac" + bitrate = 128 + sample_rate = 32000 + } + remove_audio = true + } + stream_info { + video { + codec = "libx264" + fps = 4 + bitrate = 256 + } + audio { + codec = "libfdk_aac" + bitrate = 256 + sample_rate = 44100 + } + remove_audio = true + tehd_config { + type = "TEHD-100" + } + } +} + +resource "tencentcloud_vod_snapshot_by_time_offset_template" "foo" { + name = "tf-snapshot" + sub_app_id = tonumber(split("#", tencentcloud_vod_sub_application.sub_application.id)[1]) + width = 128 + height = 128 + resolution_adaptive = false + format = "png" + comment = "test" + fill_type = "white" +} + +resource "tencentcloud_vod_image_sprite_template" "foo" { + sample_type = "Percent" + sub_app_id = tonumber(split("#", tencentcloud_vod_sub_application.sub_application.id)[1]) + sample_interval = 10 + row_count = 3 + column_count = 3 + name = "tf-sprite" + comment = "test" + fill_type = "stretch" + width = 128 + height = 128 + resolution_adaptive = false +} + +resource "tencentcloud_vod_transcode_template" "transcode_template" { + container = "mp4" + sub_app_id = tonumber(split("#", tencentcloud_vod_sub_application.sub_application.id)[1]) + name = "720pTranscodeTemplate" + comment = "test transcode mp4 720p update" + remove_video = 0 + remove_audio = 0 + video_template { + codec = "libx264" + fps = 26 + bitrate = 1000 + resolution_adaptive = "open" + width = 0 + height = 720 + fill_type = "stretch" + vcrf = 1 + gop = 250 + preserve_hdr_switch = "OFF" + codec_tag = "hvc1" + + } + audio_template { + codec = "libfdk_aac" + bitrate = 128 + sample_rate = 44100 + audio_channel = 2 + + } + segment_type = "ts" +} + resource "tencentcloud_vod_procedure_template" "foo" { name = "tf-procedure0" comment = "test-update" sub_app_id = tonumber(split("#", tencentcloud_vod_sub_application.sub_application.id)[1]) media_process_task { adaptive_dynamic_streaming_task_list { - definition = tencentcloud_vod_adaptive_dynamic_streaming_template.foo.id + definition = tonumber(split("#", tencentcloud_vod_adaptive_dynamic_streaming_template.foo.id)[1]) } snapshot_by_time_offset_task_list { - definition = tencentcloud_vod_snapshot_by_time_offset_template.foo.id + definition = tonumber(split("#", tencentcloud_vod_snapshot_by_time_offset_template.foo.id)[1]) ext_time_offset_list = [ "3.5s", "4.0s" ] } + transcode_task_list { + definition = tonumber(split("#", tencentcloud_vod_transcode_template.transcode_template.id)[1]) + } } } ` diff --git a/tencentcloud/services/vod/resource_tc_vod_sample_snapshot_template.go b/tencentcloud/services/vod/resource_tc_vod_sample_snapshot_template.go index 37ba5cae40..4b86cead3f 100644 --- a/tencentcloud/services/vod/resource_tc_vod_sample_snapshot_template.go +++ b/tencentcloud/services/vod/resource_tc_vod_sample_snapshot_template.go @@ -178,13 +178,18 @@ func resourceTencentCloudVodSampleSnapshotTemplateRead(d *schema.ResourceData, m service := VodService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + var ( + subAppId int + definition string + ) idSplit := strings.Split(d.Id(), tccommon.FILED_SP) - if len(idSplit) != 2 { - return fmt.Errorf("sample snapshot id is borken, id is %s", d.Id()) + if len(idSplit) == 2 { + subAppId = helper.StrToInt(idSplit[0]) + definition = idSplit[1] + } else { + definition = d.Id() } - subAppId := idSplit[0] - definition := idSplit[1] - sampleSnapshotTemplate, err := service.DescribeVodSampleSnapshotTemplateById(ctx, helper.StrToUInt64(subAppId), helper.StrToUInt64(definition)) + sampleSnapshotTemplate, err := service.DescribeVodSampleSnapshotTemplateById(ctx, uint64(subAppId), helper.StrToUInt64(definition)) if err != nil { return err } @@ -195,7 +200,9 @@ func resourceTencentCloudVodSampleSnapshotTemplateRead(d *schema.ResourceData, m return nil } - _ = d.Set("sub_app_id", helper.StrToInt(subAppId)) + if subAppId != 0 { + _ = d.Set("sub_app_id", subAppId) + } if sampleSnapshotTemplate.SampleType != nil { _ = d.Set("sample_type", sampleSnapshotTemplate.SampleType) } @@ -294,7 +301,13 @@ func resourceTencentCloudVodSampleSnapshotTemplateUpdate(d *schema.ResourceData, err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseVodClient().ModifySampleSnapshotTemplate(request) if e != nil { - return tccommon.RetryError(e) + if sdkError, ok := e.(*sdkErrors.TencentCloudSDKError); ok { + if sdkError.Code == "FailedOperation" && sdkError.Message == "invalid vod user" { + return resource.RetryableError(e) + } + } + log.Printf("[CRITAL]%s api[%s] fail, reason:%s", logId, request.GetAction(), e.Error()) + return resource.NonRetryableError(e) } else { log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) } diff --git a/tencentcloud/services/vod/resource_tc_vod_sample_snapshot_template.md b/tencentcloud/services/vod/resource_tc_vod_sample_snapshot_template.md index 5cbe6d0485..661ef74d64 100644 --- a/tencentcloud/services/vod/resource_tc_vod_sample_snapshot_template.md +++ b/tencentcloud/services/vod/resource_tc_vod_sample_snapshot_template.md @@ -25,7 +25,7 @@ resource "tencentcloud_vod_sample_snapshot_template" "sample_snapshot_template" Import -vod snapshot template can be imported using the id, e.g. +vod snapshot template can be imported using the id($subAppId#$templateId), e.g. ``` terraform import tencentcloud_vod_sample_snapshot_template.sample_snapshot_template $subAppId#$templateId diff --git a/tencentcloud/services/vod/resource_tc_vod_snapshot_by_time_offset_template.go b/tencentcloud/services/vod/resource_tc_vod_snapshot_by_time_offset_template.go index 233d984d07..1824bad154 100644 --- a/tencentcloud/services/vod/resource_tc_vod_snapshot_by_time_offset_template.go +++ b/tencentcloud/services/vod/resource_tc_vod_snapshot_by_time_offset_template.go @@ -5,12 +5,14 @@ import ( "fmt" "log" "strconv" + "strings" "time" tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + sdkErrors "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors" vod "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vod/v20180717" "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" @@ -66,7 +68,7 @@ func ResourceTencentCloudVodSnapshotByTimeOffsetTemplate() *schema.Resource { "sub_app_id": { Type: schema.TypeInt, Optional: true, - Description: "Subapplication ID in VOD. If you need to access a resource in a subapplication, enter the subapplication ID in this field; otherwise, leave it empty.", + Description: "The VOD [application](https://intl.cloud.tencent.com/document/product/266/14574) ID. For customers who activate VOD service from December 25, 2023, if they want to access resources in a VOD application (whether it's the default application or a newly created one), they must fill in this field with the application ID.", }, "fill_type": { Type: schema.TypeString, @@ -85,6 +87,13 @@ func ResourceTencentCloudVodSnapshotByTimeOffsetTemplate() *schema.Resource { Computed: true, Description: "Last modified time of template in ISO date format.", }, + "type": { + Type: schema.TypeString, + Computed: true, + Description: "Template type, value range:\n" + + "- Preset: system preset template;\n" + + "- Custom: user-defined templates.", + }, }, } } @@ -107,8 +116,12 @@ func resourceTencentCloudVodSnapshotByTimeOffsetTemplateCreate(d *schema.Resourc if v, ok := d.GetOk("comment"); ok { request.Comment = helper.String(v.(string)) } + var resourceId string if v, ok := d.GetOk("sub_app_id"); ok { - request.SubAppId = helper.IntUint64(v.(int)) + subAppId := v.(int) + resourceId += helper.IntToStr(subAppId) + resourceId += tccommon.FILED_SP + request.SubAppId = helper.IntUint64(subAppId) } request.FillType = helper.String(d.Get("fill_type").(string)) @@ -118,8 +131,13 @@ func resourceTencentCloudVodSnapshotByTimeOffsetTemplateCreate(d *schema.Resourc ratelimit.Check(request.GetAction()) response, err = meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseVodClient().CreateSnapshotByTimeOffsetTemplate(request) if err != nil { + if sdkError, ok := err.(*sdkErrors.TencentCloudSDKError); ok { + if sdkError.Code == "FailedOperation" && sdkError.Message == "invalid vod user" { + return resource.RetryableError(err) + } + } log.Printf("[CRITAL]%s api[%s] fail, reason:%s", logId, request.GetAction(), err.Error()) - return tccommon.RetryError(err) + return resource.NonRetryableError(err) } return nil }) @@ -129,7 +147,8 @@ func resourceTencentCloudVodSnapshotByTimeOffsetTemplateCreate(d *schema.Resourc if response == nil || response.Response == nil { return fmt.Errorf("for vod snapshot by time offset template creation, response is nil") } - d.SetId(strconv.FormatUint(*response.Response.Definition, 10)) + resourceId += strconv.FormatUint(*response.Response.Definition, 10) + d.SetId(resourceId) return resourceTencentCloudVodSnapshotByTimeOffsetTemplateRead(d, meta) } @@ -141,14 +160,21 @@ func resourceTencentCloudVodSnapshotByTimeOffsetTemplateRead(d *schema.ResourceD var ( logId = tccommon.GetLogId(tccommon.ContextNil) ctx = context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - id = d.Id() - subAppId = d.Get("sub_app_id").(int) + subAppId int + definition string client = meta.(tccommon.ProviderMeta).GetAPIV3Conn() vodService = VodService{client: client} ) + idSplit := strings.Split(d.Id(), tccommon.FILED_SP) + if len(idSplit) == 2 { + subAppId = helper.StrToInt(idSplit[0]) + definition = idSplit[1] + } else { + definition = d.Id() + } // waiting for refreshing cache time.Sleep(30 * time.Second) - template, has, err := vodService.DescribeSnapshotByTimeOffsetTemplatesById(ctx, id, subAppId) + template, has, err := vodService.DescribeSnapshotByTimeOffsetTemplatesById(ctx, definition, subAppId) if err != nil { return err } @@ -158,6 +184,7 @@ func resourceTencentCloudVodSnapshotByTimeOffsetTemplateRead(d *schema.ResourceD } _ = d.Set("name", template.Name) + _ = d.Set("type", template.Type) _ = d.Set("width", template.Width) _ = d.Set("height", template.Height) _ = d.Set("resolution_adaptive", *template.ResolutionAdaptive == "open") @@ -166,6 +193,9 @@ func resourceTencentCloudVodSnapshotByTimeOffsetTemplateRead(d *schema.ResourceD _ = d.Set("fill_type", template.FillType) _ = d.Set("create_time", template.CreateTime) _ = d.Set("update_time", template.UpdateTime) + if subAppId != 0 { + _ = d.Set("sub_app_id", subAppId) + } return nil } @@ -176,12 +206,33 @@ func resourceTencentCloudVodSnapshotByTimeOffsetTemplateUpdate(d *schema.Resourc var ( logId = tccommon.GetLogId(tccommon.ContextNil) request = vod.NewModifySnapshotByTimeOffsetTemplateRequest() - id = d.Id() + subAppId int + definition string changeFlag = false ) - idUint, _ := strconv.ParseUint(id, 0, 64) - request.Definition = &idUint + idSplit := strings.Split(d.Id(), tccommon.FILED_SP) + if len(idSplit) == 2 { + subAppId = helper.StrToInt(idSplit[0]) + definition = idSplit[1] + request.SubAppId = helper.IntUint64(subAppId) + } else { + definition = d.Id() + if v, ok := d.GetOk("sub_app_id"); ok { + request.SubAppId = helper.IntUint64(v.(int)) + } + } + + request.Definition = helper.StrToUint64Point(definition) + + immutableArgs := []string{"sub_app_id"} + + for _, v := range immutableArgs { + if d.HasChange(v) { + return fmt.Errorf("argument `%s` cannot be changed", v) + } + } + if d.HasChange("name") { changeFlag = true request.Name = helper.String(d.Get("name").(string)) @@ -200,10 +251,6 @@ func resourceTencentCloudVodSnapshotByTimeOffsetTemplateUpdate(d *schema.Resourc changeFlag = true request.Comment = helper.String(d.Get("comment").(string)) } - if d.HasChange("sub_app_id") { - changeFlag = true - request.SubAppId = helper.IntUint64(d.Get("sub_app_id").(int)) - } if d.HasChange("fill_type") { changeFlag = true request.FillType = helper.String(d.Get("fill_type").(string)) @@ -236,12 +283,25 @@ func resourceTencentCloudVodSnapshotByTimeOffsetTemplateDelete(d *schema.Resourc logId := tccommon.GetLogId(tccommon.ContextNil) ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) - id := d.Id() + var ( + subAppId int + definition string + ) + idSplit := strings.Split(d.Id(), tccommon.FILED_SP) + if len(idSplit) == 2 { + subAppId = helper.StrToInt(idSplit[0]) + definition = idSplit[1] + } else { + definition = d.Id() + if v, ok := d.GetOk("sub_app_id"); ok { + subAppId = v.(int) + } + } vodService := VodService{ client: meta.(tccommon.ProviderMeta).GetAPIV3Conn(), } - if err := vodService.DeleteSnapshotByTimeOffsetTemplate(ctx, id, uint64(d.Get("sub_app_id").(int))); err != nil { + if err := vodService.DeleteSnapshotByTimeOffsetTemplate(ctx, definition, uint64(subAppId)); err != nil { return err } diff --git a/tencentcloud/services/vod/resource_tc_vod_snapshot_by_time_offset_template.md b/tencentcloud/services/vod/resource_tc_vod_snapshot_by_time_offset_template.md index 8b6dc8d6f5..aac4300751 100644 --- a/tencentcloud/services/vod/resource_tc_vod_snapshot_by_time_offset_template.md +++ b/tencentcloud/services/vod/resource_tc_vod_snapshot_by_time_offset_template.md @@ -16,8 +16,8 @@ resource "tencentcloud_vod_snapshot_by_time_offset_template" "foo" { Import -VOD snapshot by time offset template can be imported using the id, e.g. +VOD snapshot by time offset template can be imported using the id($subAppId#$templateId), e.g. ``` -$ terraform import tencentcloud_vod_snapshot_by_time_offset_template.foo 46906 +$ terraform import tencentcloud_vod_snapshot_by_time_offset_template.foo $subAppId#$templateId ``` \ No newline at end of file diff --git a/tencentcloud/services/vod/resource_tc_vod_snapshot_by_time_offset_template_test.go b/tencentcloud/services/vod/resource_tc_vod_snapshot_by_time_offset_template_test.go index 9fda33d5b2..e70bce0f54 100644 --- a/tencentcloud/services/vod/resource_tc_vod_snapshot_by_time_offset_template_test.go +++ b/tencentcloud/services/vod/resource_tc_vod_snapshot_by_time_offset_template_test.go @@ -4,10 +4,12 @@ import ( "context" "fmt" "strconv" + "strings" "testing" tcacctest "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/acctest" tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" svcvod "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/services/vod" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" @@ -74,6 +76,7 @@ func TestAccTencentCloudVodSnapshotByTimeOffsetTemplateResource(t *testing.T) { resource.TestCheckResourceAttr("tencentcloud_vod_snapshot_by_time_offset_template.foo", "fill_type", "white"), resource.TestCheckResourceAttrSet("tencentcloud_vod_snapshot_by_time_offset_template.foo", "create_time"), resource.TestCheckResourceAttrSet("tencentcloud_vod_snapshot_by_time_offset_template.foo", "update_time"), + resource.TestCheckResourceAttrSet("tencentcloud_vod_snapshot_by_time_offset_template.foo", "type"), ), }, { @@ -89,10 +92,9 @@ func TestAccTencentCloudVodSnapshotByTimeOffsetTemplateResource(t *testing.T) { ), }, { - ResourceName: "tencentcloud_vod_snapshot_by_time_offset_template.foo", - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"sub_app_id"}, + ResourceName: "tencentcloud_vod_snapshot_by_time_offset_template.foo", + ImportState: true, + ImportStateVerify: true, }, }, }) @@ -107,11 +109,13 @@ func testAccCheckVodSnapshotByTimeOffsetTemplateDestroy(s *terraform.State) erro if rs.Type != "tencentcloud_vod_snapshot_by_time_offset_template" { continue } - var ( - filter = map[string]interface{}{ - "definitions": []string{rs.Primary.ID}, - } - ) + idSplit := strings.Split(rs.Primary.ID, tccommon.FILED_SP) + subAppId := helper.StrToInt(idSplit[0]) + definition := idSplit[1] + filter := map[string]interface{}{ + "definitions": []string{definition}, + "sub_appid": subAppId, + } templates, err := vodService.DescribeSnapshotByTimeOffsetTemplatesByFilter(ctx, filter) if err != nil { @@ -139,11 +143,13 @@ func testAccCheckVodSnapshotByTimeOffsetTemplateExists(n string) resource.TestCh } vodService := svcvod.NewVodService(tcacctest.AccProvider.Meta().(tccommon.ProviderMeta).GetAPIV3Conn()) - var ( - filter = map[string]interface{}{ - "definitions": []string{rs.Primary.ID}, - } - ) + idSplit := strings.Split(rs.Primary.ID, tccommon.FILED_SP) + subAppId := helper.StrToInt(idSplit[0]) + definition := idSplit[1] + filter := map[string]interface{}{ + "definitions": []string{definition}, + "sub_appid": subAppId, + } templates, err := vodService.DescribeSnapshotByTimeOffsetTemplatesByFilter(ctx, filter) if err != nil { return err @@ -156,8 +162,15 @@ func testAccCheckVodSnapshotByTimeOffsetTemplateExists(n string) resource.TestCh } const testAccVodSnapshotByTimeOffsetTemplate = ` +resource "tencentcloud_vod_sub_application" "sub_application" { + name = "sbtot-subapplication" + status = "On" + description = "this is sub application" +} + resource "tencentcloud_vod_snapshot_by_time_offset_template" "foo" { name = "tf-snapshot" + sub_app_id = tonumber(split("#", tencentcloud_vod_sub_application.sub_application.id)[1]) width = 128 height = 128 resolution_adaptive = false @@ -168,8 +181,15 @@ resource "tencentcloud_vod_snapshot_by_time_offset_template" "foo" { ` const testAccVodSnapshotByTimeOffsetTemplateUpdate = ` +resource "tencentcloud_vod_sub_application" "sub_application" { + name = "sbtot-subapplication" + status = "On" + description = "this is sub application" +} + resource "tencentcloud_vod_snapshot_by_time_offset_template" "foo" { name = "tf-snapshot-update" + sub_app_id = tonumber(split("#", tencentcloud_vod_sub_application.sub_application.id)[1]) width = 129 height = 129 resolution_adaptive = true diff --git a/tencentcloud/services/vod/service_tencentcloud_vod.go b/tencentcloud/services/vod/service_tencentcloud_vod.go index 2a1ad15ceb..faf1fce062 100644 --- a/tencentcloud/services/vod/service_tencentcloud_vod.go +++ b/tencentcloud/services/vod/service_tencentcloud_vod.go @@ -75,10 +75,13 @@ func (me *VodService) DescribeAdaptiveDynamicStreamingTemplatesById(ctx context. var ( filter = map[string]interface{}{ "definitions": []string{templateId}, - "sub_appid": subAppId, } ) + if subAppId != 0 { + filter["sub_appid"] = subAppId + } + templates, errRet := me.DescribeAdaptiveDynamicStreamingTemplatesByFilter(ctx, filter) if errRet != nil { return @@ -369,10 +372,12 @@ func (me *VodService) DescribeImageSpriteTemplatesById(ctx context.Context, temp var ( filter = map[string]interface{}{ "definitions": []string{templateId}, - "sub_appid": subAppId, } ) + if subAppId != 0 { + filter["sub_appid"] = subAppId + } templates, errRet := me.DescribeImageSpriteTemplatesByFilter(ctx, filter) if errRet != nil { return @@ -515,7 +520,9 @@ func (me *VodService) DescribeVodSampleSnapshotTemplateById(ctx context.Context, logId := tccommon.GetLogId(ctx) request := vod.NewDescribeSampleSnapshotTemplatesRequest() - request.SubAppId = helper.Uint64(subAppId) + if subAppId != 0 { + request.SubAppId = helper.Uint64(subAppId) + } request.Definitions = []*uint64{helper.Uint64(definition)} defer func() { @@ -675,3 +682,28 @@ func (me *VodService) DeleteVodWatermarkTemplateById(ctx context.Context, subApp return } + +func (me *VodService) DescribeVodEventConfig(ctx context.Context, subAppId uint64) (eventConfig *vod.DescribeEventConfigResponseParams, errRet error) { + logId := tccommon.GetLogId(tccommon.ContextNil) + + request := vod.NewDescribeEventConfigRequest() + request.SubAppId = &subAppId + + defer func() { + if errRet != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", logId, request.GetAction(), request.ToJsonString(), errRet.Error()) + } + }() + + ratelimit.Check(request.GetAction()) + + response, err := me.client.UseVodClient().DescribeEventConfig(request) + if err != nil { + errRet = err + return + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + + eventConfig = response.Response + return +} diff --git a/tencentcloud/services/vpc/resource_tc_eni_ipv4_address.go b/tencentcloud/services/vpc/resource_tc_eni_ipv4_address.go new file mode 100644 index 0000000000..983a50ff6b --- /dev/null +++ b/tencentcloud/services/vpc/resource_tc_eni_ipv4_address.go @@ -0,0 +1,284 @@ +package vpc + +import ( + "context" + "log" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" +) + +func ResourceTencentCloudEniIpv4Address() *schema.Resource { + return &schema.Resource{ + Create: resourceTencentCloudEniIpv4AddressCreate, + Read: resourceTencentCloudEniIpv4AddressRead, + Delete: resourceTencentCloudEniIpv4AddressDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Schema: map[string]*schema.Schema{ + "network_interface_id": { + Required: true, + ForceNew: true, + Type: schema.TypeString, + Description: "The ID of the ENI instance, such as `eni-m6dyj72l`.", + }, + + "private_ip_addresses": { + Optional: true, + Type: schema.TypeSet, + Computed: true, + ForceNew: true, + ConflictsWith: []string{"secondary_private_ip_address_count", "qos_level"}, + Description: "The information on private IP addresses, of which you can specify a maximum of 10 at a time. You should provide either this parameter or SecondaryPrivateIpAddressCount, or both.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "private_ip_address": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "Private IP address.", + }, + "primary": { + Type: schema.TypeBool, + Optional: true, + ForceNew: true, + Computed: true, + Description: "Whether it is a primary IP.", + }, + "public_ip_address": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Computed: true, + Description: "Public IP address.", + }, + "address_id": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Computed: true, + Description: "EIP instance ID, such as `eip-11112222`.", + }, + "description": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Computed: true, + Description: "Private IP description.", + }, + "is_wan_ip_blocked": { + Type: schema.TypeBool, + Optional: true, + ForceNew: true, + Computed: true, + Description: "Whether the public IP is blocked.", + }, + "state": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Computed: true, + Description: "IP status: `PENDING`: Creating, `MIGRATING`: Migrating, `DELETING`: Deleting, `AVAILABLE`: Available.", + }, + "qos_level": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Computed: true, + Description: "IP service level. Values: PT` (Gold), `AU` (Silver), `AG `(Bronze) and DEFAULT` (Default).", + }, + }, + }, + }, + + "secondary_private_ip_address_count": { + Optional: true, + Type: schema.TypeInt, + Computed: true, + ForceNew: true, + ConflictsWith: []string{"private_ip_addresses"}, + Description: "The number of newly-applied private IP addresses. You should provide either this parameter or PrivateIpAddresses, or both. The total number of private IP addresses cannot exceed the quota.", + }, + + "qos_level": { + Optional: true, + Computed: true, + ForceNew: true, + ConflictsWith: []string{"private_ip_addresses"}, + Type: schema.TypeString, + Description: "IP service level. It is used together with `SecondaryPrivateIpAddressCount`. Values: PT`(Gold), `AU`(Silver), `AG `(Bronze) and DEFAULT (Default).", + }, + }, + } +} + +func resourceTencentCloudEniIpv4AddressCreate(d *schema.ResourceData, meta interface{}) error { + defer tccommon.LogElapsed("resource.tencentcloud_eni_ipv4_address.create")() + defer tccommon.InconsistentCheck(d, meta)() + + logId := tccommon.GetLogId(tccommon.ContextNil) + + var ( + request = vpc.NewAssignPrivateIpAddressesRequest() + networkInterfaceId string + ) + if v, ok := d.GetOk("network_interface_id"); ok { + networkInterfaceId = v.(string) + request.NetworkInterfaceId = helper.String(v.(string)) + } + + if v, ok := d.GetOk("private_ip_addresses"); ok { + for _, item := range v.(*schema.Set).List() { + dMap := item.(map[string]interface{}) + privateIpAddressSpecification := vpc.PrivateIpAddressSpecification{} + if v, ok := dMap["private_ip_address"]; ok { + privateIpAddressSpecification.PrivateIpAddress = helper.String(v.(string)) + } + if v, ok := dMap["primary"]; ok { + privateIpAddressSpecification.Primary = helper.Bool(v.(bool)) + } + if v, ok := dMap["public_ip_address"]; ok && v != "" { + privateIpAddressSpecification.PublicIpAddress = helper.String(v.(string)) + } + if v, ok := dMap["address_id"]; ok && v != "" { + privateIpAddressSpecification.AddressId = helper.String(v.(string)) + } + if v, ok := dMap["description"]; ok && v != "" { + privateIpAddressSpecification.Description = helper.String(v.(string)) + } + if v, ok := dMap["is_wan_ip_blocked"]; ok { + privateIpAddressSpecification.IsWanIpBlocked = helper.Bool(v.(bool)) + } + if v, ok := dMap["state"]; ok && v != "" { + privateIpAddressSpecification.State = helper.String(v.(string)) + } + if v, ok := dMap["qos_level"]; ok && v != "" { + privateIpAddressSpecification.QosLevel = helper.String(v.(string)) + } + request.PrivateIpAddresses = append(request.PrivateIpAddresses, &privateIpAddressSpecification) + } + } + + if v, ok := d.GetOkExists("secondary_private_ip_address_count"); ok { + request.SecondaryPrivateIpAddressCount = helper.IntUint64(v.(int)) + } + + if v, ok := d.GetOk("qos_level"); ok { + request.QosLevel = helper.String(v.(string)) + } + + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseVpcClient().AssignPrivateIpAddresses(request) + if e != nil { + return tccommon.RetryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) + } + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s create vpc eniIpv4Address failed, reason:%+v", logId, err) + return err + } + + d.SetId(networkInterfaceId) + + return resourceTencentCloudEniIpv4AddressRead(d, meta) +} + +func resourceTencentCloudEniIpv4AddressRead(d *schema.ResourceData, meta interface{}) error { + defer tccommon.LogElapsed("resource.tencentcloud_eni_ipv4_address.read")() + defer tccommon.InconsistentCheck(d, meta)() + + logId := tccommon.GetLogId(tccommon.ContextNil) + + ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + + service := VpcService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + + networkInterfaceId := d.Id() + + enis, err := service.DescribeEniById(ctx, []string{networkInterfaceId}) + + if err != nil { + return err + } + + if len(enis) < 1 { + d.SetId("") + log.Printf("[WARN]%s resource `VpcIpv6EniAddress` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) + return nil + } + + eni := enis[0] + + if eni.NetworkInterfaceId != nil { + _ = d.Set("network_interface_id", eni.NetworkInterfaceId) + } + + ipv4s := make([]map[string]interface{}, 0, len(eni.PrivateIpAddressSet)) + for _, ipv4 := range eni.PrivateIpAddressSet { + if !*ipv4.Primary { + ipv4s = append(ipv4s, map[string]interface{}{ + "private_ip_address": ipv4.PrivateIpAddress, + "primary": ipv4.Primary, + "public_ip_address": ipv4.AddressId, + "address_id": ipv4.AddressId, + "description": ipv4.Description, + "is_wan_ip_blocked": ipv4.IsWanIpBlocked, + "state": ipv4.State, + "qos_level": ipv4.QosLevel, + }) + } + } + + _ = d.Set("network_interface_id", networkInterfaceId) + _ = d.Set("private_ip_addresses", ipv4s) + _ = d.Set("secondary_private_ip_address_count", len(ipv4s)) + if len(eni.PrivateIpAddressSet) > 0 { + _ = d.Set("qos_level", eni.PrivateIpAddressSet[0].QosLevel) + } + + return nil +} + +func resourceTencentCloudEniIpv4AddressDelete(d *schema.ResourceData, meta interface{}) error { + defer tccommon.LogElapsed("resource.tencentcloud_eni_ipv6_address.delete")() + defer tccommon.InconsistentCheck(d, meta)() + + logId := tccommon.GetLogId(tccommon.ContextNil) + ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + + service := VpcService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + networkInterfaceId := d.Id() + + enis, err := service.DescribeEniById(ctx, []string{networkInterfaceId}) + + if err != nil { + return err + } + + if len(enis) < 1 { + d.SetId("") + log.Printf("[WARN]%s resource `EniIpv4Address` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) + return nil + } + + eni := enis[0] + ipv4s := make([]*string, 0, len(eni.PrivateIpAddressSet)) + for _, ipv4 := range eni.PrivateIpAddressSet { + if !*ipv4.Primary { + ipv4s = append(ipv4s, ipv4.PrivateIpAddress) + } + } + + if err := service.DeleteEniIpv4AddressById(ctx, networkInterfaceId, ipv4s); err != nil { + return err + } + + return nil +} diff --git a/tencentcloud/services/vpc/resource_tc_eni_ipv4_address.md b/tencentcloud/services/vpc/resource_tc_eni_ipv4_address.md new file mode 100644 index 0000000000..bcb0082328 --- /dev/null +++ b/tencentcloud/services/vpc/resource_tc_eni_ipv4_address.md @@ -0,0 +1,22 @@ +Provides a resource to create a vpc eni_ipv4_address + +Example Usage + +```hcl +data "tencentcloud_enis" "eni" { + name = "Primary ENI" +} + +resource "tencentcloud_eni_ipv4_address" "eni_ipv4_address" { + network_interface_id = data.tencentcloud_enis.eni.enis.0.id + secondary_private_ip_address_count = 3 +} +``` + +Import + +vpc eni_ipv4_address can be imported using the id, e.g. + +``` +terraform import tencentcloud_eni_ipv4_address.eni_ipv4_address eni_id +``` \ No newline at end of file diff --git a/tencentcloud/services/vpc/resource_tc_eni_ipv4_address_test.go b/tencentcloud/services/vpc/resource_tc_eni_ipv4_address_test.go new file mode 100644 index 0000000000..90da450132 --- /dev/null +++ b/tencentcloud/services/vpc/resource_tc_eni_ipv4_address_test.go @@ -0,0 +1,53 @@ +package vpc_test + +import ( + "testing" + + tcacctest "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/acctest" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccTencentCloudNeedFixEniIpv4AddressResource_basic(t *testing.T) { + t.Parallel() + resource.Test(t, resource.TestCase{ + PreCheck: func() { + tcacctest.AccPreCheck(t) + }, + + Providers: tcacctest.AccProviders, + Steps: []resource.TestStep{ + { + Config: testAccEniIpv4Address, + Check: resource.ComposeTestCheckFunc( + //testAccCheckBandwidthPackageAttachmentExists("tencentcloud_vpc_ipv6_eni_address"), + resource.TestCheckResourceAttrSet("tencentcloud_eni_ipv4_address.eni_ipv4_address", "network_interface_id"), + resource.TestCheckResourceAttrSet("tencentcloud_eni_ipv4_address.eni_ipv4_address", "private_ip_addresses.0.private_ip_address"), + resource.TestCheckResourceAttrSet("tencentcloud_eni_ipv4_address.eni_ipv4_address", "private_ip_addresses.0.primary"), + resource.TestCheckResourceAttrSet("tencentcloud_eni_ipv4_address.eni_ipv4_address", "private_ip_addresses.0.address_id"), + resource.TestCheckResourceAttrSet("tencentcloud_eni_ipv4_address.eni_ipv4_address", "private_ip_addresses.0.description"), + resource.TestCheckResourceAttrSet("tencentcloud_eni_ipv4_address.eni_ipv4_address", "private_ip_addresses.0.is_wan_ip_blocked"), + resource.TestCheckResourceAttrSet("tencentcloud_eni_ipv4_address.eni_ipv4_address", "private_ip_addresses.0.state"), + ), + }, + { + ResourceName: "tencentcloud_eni_ipv4_address.eni_ipv4_address", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +const testAccEniIpv4Address = ` + +data "tencentcloud_enis" "eni" { + name = "Primary ENI" +} + +resource "tencentcloud_eni_ipv4_address" "eni_ipv4_address" { + network_interface_id = data.tencentcloud_enis.eni.enis.0.id + secondary_private_ip_address_count = 3 +} + +` diff --git a/tencentcloud/services/vpc/resource_tc_eni_ipv6_address.go b/tencentcloud/services/vpc/resource_tc_eni_ipv6_address.go new file mode 100644 index 0000000000..08429373d8 --- /dev/null +++ b/tencentcloud/services/vpc/resource_tc_eni_ipv6_address.go @@ -0,0 +1,251 @@ +package vpc + +import ( + "context" + "fmt" + "log" + "time" + + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" + + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper" +) + +func ResourceTencentCloudEniIpv6Address() *schema.Resource { + return &schema.Resource{ + Create: resourceTencentCloudEniIpv6AddressCreate, + Read: resourceTencentCloudEniIpv6AddressRead, + Delete: resourceTencentCloudEniIpv6AddressDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Schema: map[string]*schema.Schema{ + "network_interface_id": { + Required: true, + Type: schema.TypeString, + ForceNew: true, + Description: "ENI instance `ID`, in the form of `eni-m6dyj72l`.", + }, + + "ipv6_addresses": { + Optional: true, + Type: schema.TypeSet, + Computed: true, + ForceNew: true, + ConflictsWith: []string{"ipv6_address_count"}, + Description: "The specified `IPv6` address list, up to 10 can be specified at a time. Combined with the input parameter `Ipv6AddressCount` to calculate the quota. Mandatory one with Ipv6AddressCount.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "address": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "`IPv6` address, in the form of: `3402:4e00:20:100:0:8cd9:2a67:71f3`.", + }, + "description": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Description: "Description.", + }, + "primary": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + ForceNew: true, + Description: "Whether to master `IP`.", + }, + "address_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + Description: "`EIP` instance `ID`, such as:`eip-hxlqja90`.", + }, + "is_wan_ip_blocked": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + ForceNew: true, + Description: "Whether the public network IP is blocked.", + }, + "state": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + Description: "`IPv6` address status: `PENDING`: pending, `MIGRATING`: migrating, `DELETING`: deleting, `AVAILABLE`: available.", + }, + }, + }, + }, + + "ipv6_address_count": { + Optional: true, + Computed: true, + ForceNew: true, + Type: schema.TypeInt, + ConflictsWith: []string{"ipv6_addresses"}, + Description: "The number of automatically assigned IPv6 addresses and the total number of private IP addresses cannot exceed the quota. This should be combined with the input parameter `ipv6_addresses` for quota calculation. At least one of them, either this or 'Ipv6Addresses', must be provided.", + }, + }, + } +} + +func resourceTencentCloudEniIpv6AddressCreate(d *schema.ResourceData, meta interface{}) error { + defer tccommon.LogElapsed("resource.tencentcloud_eni_ipv6_address.create")() + defer tccommon.InconsistentCheck(d, meta)() + + logId := tccommon.GetLogId(tccommon.ContextNil) + + var ( + request = vpc.NewAssignIpv6AddressesRequest() + response = vpc.NewAssignIpv6AddressesResponse() + networkInterfaceId string + ) + + if v, ok := d.GetOk("network_interface_id"); ok { + networkInterfaceId = v.(string) + request.NetworkInterfaceId = helper.String(v.(string)) + } + + if v, ok := d.GetOk("ipv6_addresses"); ok { + for _, item := range v.(*schema.Set).List() { + dMap := item.(map[string]interface{}) + ipv6Address := vpc.Ipv6Address{} + if v, ok := dMap["address"]; ok { + ipv6Address.Address = helper.String(v.(string)) + } + if v, ok := dMap["primary"]; ok { + ipv6Address.Primary = helper.Bool(v.(bool)) + } + if v, ok := dMap["address_id"]; ok { + ipv6Address.AddressId = helper.String(v.(string)) + } + if v, ok := dMap["description"]; ok { + ipv6Address.Description = helper.String(v.(string)) + } + if v, ok := dMap["is_wan_ip_blocked"]; ok { + ipv6Address.IsWanIpBlocked = helper.Bool(v.(bool)) + } + if v, ok := dMap["state"]; ok { + ipv6Address.State = helper.String(v.(string)) + } + request.Ipv6Addresses = append(request.Ipv6Addresses, &ipv6Address) + } + } + + if v, ok := d.GetOkExists("ipv6_address_count"); ok { + request.Ipv6AddressCount = helper.IntUint64(v.(int)) + } + + err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError { + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseVpcClient().AssignIpv6Addresses(request) + if e != nil { + return tccommon.RetryError(e) + } else { + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), result.ToJsonString()) + } + response = result + return nil + }) + if err != nil { + log.Printf("[CRITAL]%s create vpc ipv6EniAddress failed, reason:%+v", logId, err) + return err + } + + addressSet := response.Response.Ipv6AddressSet + if len(addressSet) < 1 { + return fmt.Errorf("assign ipv6 addresses failed.") + } + + time.Sleep(5 * time.Second) + + d.SetId(networkInterfaceId) + + return resourceTencentCloudEniIpv6AddressRead(d, meta) +} + +func resourceTencentCloudEniIpv6AddressRead(d *schema.ResourceData, meta interface{}) error { + defer tccommon.LogElapsed("resource.tencentcloud_eni_ipv6_address.read")() + defer tccommon.InconsistentCheck(d, meta)() + + logId := tccommon.GetLogId(tccommon.ContextNil) + + ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + + service := VpcService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + + networkInterfaceId := d.Id() + + enis, err := service.DescribeEniById(ctx, []string{networkInterfaceId}) + + if err != nil { + return err + } + + if len(enis) < 1 { + d.SetId("") + log.Printf("[WARN]%s resource `VpcIpv6EniAddress` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) + return nil + } + + eni := enis[0] + + ipv6s := make([]map[string]interface{}, 0, len(eni.Ipv6AddressSet)) + for _, ipv6 := range eni.Ipv6AddressSet { + ipv6s = append(ipv6s, map[string]interface{}{ + "address": ipv6.Address, + "primary": ipv6.Primary, + "address_id": ipv6.AddressId, + "description": ipv6.Description, + "is_wan_ip_blocked": ipv6.IsWanIpBlocked, + "state": ipv6.State, + }) + } + + _ = d.Set("network_interface_id", networkInterfaceId) + _ = d.Set("ipv6_addresses", ipv6s) + _ = d.Set("ipv6_address_count", len(eni.Ipv6AddressSet)) + + return nil +} + +func resourceTencentCloudEniIpv6AddressDelete(d *schema.ResourceData, meta interface{}) error { + defer tccommon.LogElapsed("resource.tencentcloud_eni_ipv6_address.delete")() + defer tccommon.InconsistentCheck(d, meta)() + + logId := tccommon.GetLogId(tccommon.ContextNil) + ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId) + + service := VpcService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()} + networkInterfaceId := d.Id() + + enis, err := service.DescribeEniById(ctx, []string{networkInterfaceId}) + + if err != nil { + return err + } + + if len(enis) < 1 { + d.SetId("") + log.Printf("[WARN]%s resource `VpcIpv6EniAddress` [%s] not found, please check if it has been deleted.\n", logId, d.Id()) + return nil + } + + eni := enis[0] + ipv6s := make([]*string, 0, len(eni.Ipv6AddressSet)) + for _, ipv6 := range eni.Ipv6AddressSet { + ipv6s = append(ipv6s, ipv6.Address) + } + + if err := service.DeleteEniIpv6AddressById(ctx, networkInterfaceId, ipv6s); err != nil { + return err + } + + return nil +} diff --git a/tencentcloud/services/vpc/resource_tc_eni_ipv6_address.md b/tencentcloud/services/vpc/resource_tc_eni_ipv6_address.md new file mode 100644 index 0000000000..1e0d38021e --- /dev/null +++ b/tencentcloud/services/vpc/resource_tc_eni_ipv6_address.md @@ -0,0 +1,53 @@ +Provides a resource to create a vpc eni_ipv6_address + +Example Usage + +```hcl +data "tencentcloud_availability_zones" "zones" {} + +resource "tencentcloud_vpc" "vpc" { + name = "vpc-example" + cidr_block = "10.0.0.0/16" +} + +resource "tencentcloud_subnet" "subnet" { + availability_zone = data.tencentcloud_availability_zones.zones.zones.0.name + name = "subnet-example" + vpc_id = tencentcloud_vpc.vpc.id + cidr_block = "10.0.0.0/16" + is_multicast = false +} + +resource "tencentcloud_eni" "eni" { + name = "eni-example" + vpc_id = tencentcloud_vpc.vpc.id + subnet_id = tencentcloud_subnet.subnet.id + description = "eni desc." + ipv4_count = 1 +} + +resource "tencentcloud_vpc_ipv6_cidr_block" "example" { + vpc_id = tencentcloud_vpc.vpc.id +} + +resource "tencentcloud_vpc_ipv6_subnet_cidr_block" "example" { + vpc_id = tencentcloud_vpc.vpc.id + ipv6_subnet_cidr_blocks { + subnet_id = tencentcloud_subnet.subnet.id + ipv6_cidr_block = "2402:4e00:1018:6700::/64" + } +} + +resource "tencentcloud_eni_ipv6_address" "ipv6_eni_address" { + network_interface_id = tencentcloud_eni.eni.id + ipv6_address_count = 1 +} +``` + +Import + +vpc eni_ipv6_address can be imported using the id, e.g. + +``` +terraform import tencentcloud_eni_ipv6_address.ipv6_eni_address eni_id +``` \ No newline at end of file diff --git a/tencentcloud/services/vpc/resource_tc_eni_ipv6_address_test.go b/tencentcloud/services/vpc/resource_tc_eni_ipv6_address_test.go new file mode 100644 index 0000000000..ba55b7e568 --- /dev/null +++ b/tencentcloud/services/vpc/resource_tc_eni_ipv6_address_test.go @@ -0,0 +1,84 @@ +package vpc_test + +import ( + "testing" + + tcacctest "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/acctest" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccTencentCloudNeedFixEniIpv6AddressResource_basic(t *testing.T) { + t.Parallel() + resource.Test(t, resource.TestCase{ + PreCheck: func() { + tcacctest.AccPreCheck(t) + }, + + Providers: tcacctest.AccProviders, + Steps: []resource.TestStep{ + { + Config: testAccEniIpv6Address, + Check: resource.ComposeTestCheckFunc( + //testAccCheckBandwidthPackageAttachmentExists("tencentcloud_vpc_ipv6_eni_address"), + resource.TestCheckResourceAttrSet("tencentcloud_eni_ipv6_address.ipv6_eni_address", "network_interface_id"), + resource.TestCheckResourceAttrSet("tencentcloud_eni_ipv6_address.ipv6_eni_address", "ipv6_addresses.0.address"), + resource.TestCheckResourceAttrSet("tencentcloud_eni_ipv6_address.ipv6_eni_address", "ipv6_addresses.0.primary"), + resource.TestCheckResourceAttrSet("tencentcloud_eni_ipv6_address.ipv6_eni_address", "ipv6_addresses.0.address_id"), + resource.TestCheckResourceAttrSet("tencentcloud_eni_ipv6_address.ipv6_eni_address", "ipv6_addresses.0.description"), + resource.TestCheckResourceAttrSet("tencentcloud_eni_ipv6_address.ipv6_eni_address", "ipv6_addresses.0.is_wan_ip_blocked"), + resource.TestCheckResourceAttrSet("tencentcloud_eni_ipv6_address.ipv6_eni_address", "ipv6_addresses.0.state"), + ), + }, + { + ResourceName: "tencentcloud_eni_ipv6_address.ipv6_eni_address", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +const testAccEniIpv6Address = ` + +data "tencentcloud_availability_zones" "zones" {} + +resource "tencentcloud_vpc" "vpc" { + name = "vpc-example-ipv6" + cidr_block = "10.0.0.0/16" +} + +resource "tencentcloud_subnet" "subnet" { + availability_zone = data.tencentcloud_availability_zones.zones.zones.0.name + name = "subnet-example-ipv6" + vpc_id = tencentcloud_vpc.vpc.id + cidr_block = "10.0.0.0/16" + is_multicast = false +} + +resource "tencentcloud_eni" "eni" { + name = "eni-example-ipv6" + vpc_id = tencentcloud_vpc.vpc.id + subnet_id = tencentcloud_subnet.subnet.id + description = "eni desc." + ipv4_count = 1 +} + +resource "tencentcloud_vpc_ipv6_cidr_block" "example" { + vpc_id = tencentcloud_vpc.vpc.id +} + +resource "tencentcloud_vpc_ipv6_subnet_cidr_block" "example" { + vpc_id = tencentcloud_vpc.vpc.id + ipv6_subnet_cidr_blocks { + subnet_id = tencentcloud_subnet.subnet.id + ipv6_cidr_block = "2402:4e00:1018:6700::/64" + } +} + +resource "tencentcloud_eni_ipv6_address" "ipv6_eni_address" { + network_interface_id = tencentcloud_eni.eni.id + ipv6_address_count = 1 +} + +` diff --git a/tencentcloud/services/vpc/resource_tc_nat_gateway.go b/tencentcloud/services/vpc/resource_tc_nat_gateway.go index f0f3a4ba5f..bcf3cdbc47 100644 --- a/tencentcloud/services/vpc/resource_tc_nat_gateway.go +++ b/tencentcloud/services/vpc/resource_tc_nat_gateway.go @@ -1,14 +1,15 @@ package vpc import ( - tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" - svctag "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/services/tag" - "context" "fmt" "log" "time" + tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/connectivity" + svctag "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/services/tag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" @@ -217,8 +218,10 @@ func resourceTencentCloudNatGatewayRead(d *schema.ResourceData, meta interface{} request := vpc.NewDescribeNatGatewaysRequest() request.NatGatewayIds = []*string{&natGatewayId} var response *vpc.DescribeNatGatewaysResponse + var iacExtInfo connectivity.IacExtInfo + iacExtInfo.InstanceId = natGatewayId err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseVpcClient().DescribeNatGateways(request) + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseVpcClient(iacExtInfo).DescribeNatGateways(request) if e != nil { log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", logId, request.GetAction(), request.ToJsonString(), e.Error()) diff --git a/tencentcloud/services/vpc/resource_tc_security_group_rule.go b/tencentcloud/services/vpc/resource_tc_security_group_rule.go index 290d9d2196..98f0451670 100644 --- a/tencentcloud/services/vpc/resource_tc_security_group_rule.go +++ b/tencentcloud/services/vpc/resource_tc_security_group_rule.go @@ -18,7 +18,7 @@ import ( func ResourceTencentCloudSecurityGroupRule() *schema.Resource { return &schema.Resource{ - DeprecationMessage: "This resource will be offline and no longer supported, beacause single security rule is hardly ordered. Please use 'tencentcloud_security_group_lite_rule' instead.", + DeprecationMessage: "This resource will be offline and no longer supported, because single security rule is hardly ordered. Please use 'tencentcloud_security_group_rule_set' instead.", Create: resourceTencentCloudSecurityGroupRuleCreate, Read: resourceTencentCloudSecurityGroupRuleRead, Delete: resourceTencentCloudSecurityGroupRuleDelete, diff --git a/tencentcloud/services/vpc/resource_tc_vpc_ipv6_eni_address.go b/tencentcloud/services/vpc/resource_tc_vpc_ipv6_eni_address.go index 3b79d2dc02..8f72d5c5fe 100644 --- a/tencentcloud/services/vpc/resource_tc_vpc_ipv6_eni_address.go +++ b/tencentcloud/services/vpc/resource_tc_vpc_ipv6_eni_address.go @@ -18,10 +18,11 @@ import ( func ResourceTencentCloudVpcIpv6EniAddress() *schema.Resource { return &schema.Resource{ - Create: resourceTencentCloudVpcIpv6EniAddressCreate, - Read: resourceTencentCloudVpcIpv6EniAddressRead, - Update: resourceTencentCloudVpcIpv6EniAddressUpdate, - Delete: resourceTencentCloudVpcIpv6EniAddressDelete, + Create: resourceTencentCloudVpcIpv6EniAddressCreate, + Read: resourceTencentCloudVpcIpv6EniAddressRead, + Update: resourceTencentCloudVpcIpv6EniAddressUpdate, + Delete: resourceTencentCloudVpcIpv6EniAddressDelete, + DeprecationMessage: "This resource has been deprecated in Terraform TencentCloud provider version 1.81.85. Please use 'tencentcloud_eni_ipv6_address' instead.", Schema: map[string]*schema.Schema{ "vpc_id": { Required: true, diff --git a/tencentcloud/services/vpc/resource_tc_vpc_ipv6_eni_address.md b/tencentcloud/services/vpc/resource_tc_vpc_ipv6_eni_address.md index e5bc8335f4..6f7abd38ce 100644 --- a/tencentcloud/services/vpc/resource_tc_vpc_ipv6_eni_address.md +++ b/tencentcloud/services/vpc/resource_tc_vpc_ipv6_eni_address.md @@ -1,5 +1,7 @@ Provides a resource to create a vpc ipv6_eni_address +~> **NOTE:** It has been deprecated and replaced by `tencentcloud_eni_ipv6_address`. + Example Usage ```hcl @@ -34,7 +36,7 @@ resource "tencentcloud_vpc_ipv6_eni_address" "ipv6_eni_address" { vpc_id = tencentcloud_vpc.vpc.id network_interface_id = tencentcloud_eni.eni.id ipv6_addresses { - address = tencentcloud_vpc_ipv6_cidr_block.example.ipv6_cidr_block + address = "xxxxxxxxxxxxxx" description = "desc." } } diff --git a/tencentcloud/services/vpc/resource_tc_vpc_ipv6_subnet_cidr_block.md b/tencentcloud/services/vpc/resource_tc_vpc_ipv6_subnet_cidr_block.md index 9a0b514886..7077765a39 100644 --- a/tencentcloud/services/vpc/resource_tc_vpc_ipv6_subnet_cidr_block.md +++ b/tencentcloud/services/vpc/resource_tc_vpc_ipv6_subnet_cidr_block.md @@ -26,7 +26,7 @@ resource "tencentcloud_vpc_ipv6_subnet_cidr_block" "example" { vpc_id = tencentcloud_vpc.vpc.id ipv6_subnet_cidr_blocks { subnet_id = tencentcloud_subnet.subnet.id - ipv6_cidr_block = tencentcloud_vpc_ipv6_cidr_block.example.ipv6_cidr_block + ipv6_cidr_block = "xxxxxxxxx" } } ``` diff --git a/tencentcloud/services/vpc/service_tencentcloud_vpc.go b/tencentcloud/services/vpc/service_tencentcloud_vpc.go index ef85602600..5f3b86b332 100644 --- a/tencentcloud/services/vpc/service_tencentcloud_vpc.go +++ b/tencentcloud/services/vpc/service_tencentcloud_vpc.go @@ -405,9 +405,18 @@ getMoreData: var strOffset = fmt.Sprintf("%d", offset) request.Offset = &strOffset var response *vpc.DescribeVpcsResponse + var iacExtInfo connectivity.IacExtInfo + iacExtInfo.InstanceId = vpcId if err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { ratelimit.Check(request.GetAction()) - result, err := me.client.UseVpcClient().DescribeVpcs(request) + var result *vpc.DescribeVpcsResponse + var err error + if vpcId != "" { + result, err = me.client.UseVpcClient(iacExtInfo).DescribeVpcs(request) + } else { + result, err = me.client.UseVpcClient().DescribeVpcs(request) + } + if err != nil { return tccommon.RetryError(err, tccommon.InternalError) } @@ -2357,9 +2366,12 @@ func (me *VpcService) DescribeEipById(ctx context.Context, eipId string) (eip *v logId := tccommon.GetLogId(ctx) request := vpc.NewDescribeAddressesRequest() request.AddressIds = []*string{&eipId} - ratelimit.Check(request.GetAction()) - response, err := me.client.UseVpcClient().DescribeAddresses(request) + + var specArgs connectivity.IacExtInfo + specArgs.InstanceId = eipId + + response, err := me.client.UseVpcClient(specArgs).DescribeAddresses(request) if err != nil { log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", logId, request.GetAction(), request.ToJsonString(), err.Error()) @@ -2899,6 +2911,7 @@ func (me *VpcService) describeEnis( logId := tccommon.GetLogId(ctx) request := vpc.NewDescribeNetworkInterfacesRequest() + response := vpc.NewDescribeNetworkInterfacesResponse() if len(ids) > 0 { request.NetworkInterfaceIds = common.StringPtrs(ids) @@ -2975,8 +2988,14 @@ func (me *VpcService) describeEnis( for count == ENI_DESCRIBE_LIMIT { if err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { ratelimit.Check(request.GetAction()) - - response, err := me.client.UseVpcClient().DescribeNetworkInterfaces(request) + if len(ids) > 0 { + var specArgs connectivity.IacExtInfo + tmpIds := strings.Join(ids, tccommon.FILED_SP) + specArgs.InstanceId = tmpIds + response, err = me.client.UseVpcClient(specArgs).DescribeNetworkInterfaces(request) + } else { + response, err = me.client.UseVpcClient().DescribeNetworkInterfaces(request) + } if err != nil { count = 0 @@ -4167,7 +4186,9 @@ func (me *VpcService) DescribeVpngwById(ctx context.Context, vpngwId string) (ha ) request.VpnGatewayIds = []*string{&vpngwId} err = resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - response, err = me.client.UseVpcClient().DescribeVpnGateways(request) + var specArgs connectivity.IacExtInfo + specArgs.InstanceId = vpngwId + response, err = me.client.UseVpcClient(specArgs).DescribeVpnGateways(request) if err != nil { ee, ok := err.(*sdkErrors.TencentCloudSDKError) if !ok { @@ -6849,6 +6870,66 @@ func (me *VpcService) DeleteVpcIpv6EniAddressById(ctx context.Context, networkIn return } +func (me *VpcService) DeleteEniIpv6AddressById(ctx context.Context, networkInterfaceId string, ipv6Addresses []*string) (errRet error) { + logId := tccommon.GetLogId(ctx) + + request := vpc.NewUnassignIpv6AddressesRequest() + request.NetworkInterfaceId = &networkInterfaceId + + for _, ipv6Address := range ipv6Addresses { + address := vpc.Ipv6Address{} + address.Address = ipv6Address + request.Ipv6Addresses = append(request.Ipv6Addresses, &address) + } + + defer func() { + if errRet != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", logId, request.GetAction(), request.ToJsonString(), errRet.Error()) + } + }() + + ratelimit.Check(request.GetAction()) + + response, err := me.client.UseVpcClient().UnassignIpv6Addresses(request) + if err != nil { + errRet = err + return + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + + return +} + +func (me *VpcService) DeleteEniIpv4AddressById(ctx context.Context, networkInterfaceId string, ipv4Addresses []*string) (errRet error) { + logId := tccommon.GetLogId(ctx) + + request := vpc.NewUnassignPrivateIpAddressesRequest() + request.NetworkInterfaceId = &networkInterfaceId + + for _, ipv4Address := range ipv4Addresses { + address := vpc.PrivateIpAddressSpecification{} + address.PrivateIpAddress = ipv4Address + request.PrivateIpAddresses = append(request.PrivateIpAddresses, &address) + } + + defer func() { + if errRet != nil { + log.Printf("[CRITAL]%s api[%s] fail, request body [%s], reason[%s]\n", logId, request.GetAction(), request.ToJsonString(), errRet.Error()) + } + }() + + ratelimit.Check(request.GetAction()) + + response, err := me.client.UseVpcClient().UnassignPrivateIpAddresses(request) + if err != nil { + errRet = err + return + } + log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), response.ToJsonString()) + + return +} + func (me *VpcService) DescribeVpcLocalGatewayById(ctx context.Context, localGatewayId string) (localGateway *vpc.LocalGateway, errRet error) { logId := tccommon.GetLogId(ctx) diff --git a/tencentcloud/services/vpn/resource_tc_vpn_customer_gateway.go b/tencentcloud/services/vpn/resource_tc_vpn_customer_gateway.go index 4c40e9e095..58090d2b2c 100644 --- a/tencentcloud/services/vpn/resource_tc_vpn_customer_gateway.go +++ b/tencentcloud/services/vpn/resource_tc_vpn_customer_gateway.go @@ -2,6 +2,7 @@ package vpn import ( tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common" + "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/connectivity" svctag "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/services/tag" svcvpc "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/services/vpc" @@ -134,8 +135,10 @@ func resourceTencentCloudVpnCustomerGatewayRead(d *schema.ResourceData, meta int request := vpc.NewDescribeCustomerGatewaysRequest() request.CustomerGatewayIds = []*string{&customerGatewayId} var response *vpc.DescribeCustomerGatewaysResponse + var iacExtInfo connectivity.IacExtInfo + iacExtInfo.InstanceId = customerGatewayId err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError { - result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseVpcClient().DescribeCustomerGateways(request) + result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UseVpcClient(iacExtInfo).DescribeCustomerGateways(request) if e != nil { ee, ok := e.(*errors.TencentCloudSDKError) if !ok { diff --git a/tencentcloud/services/waf/service_tencentcloud_waf.go b/tencentcloud/services/waf/service_tencentcloud_waf.go index f4f8113ffb..7f3aa8ad9e 100644 --- a/tencentcloud/services/waf/service_tencentcloud_waf.go +++ b/tencentcloud/services/waf/service_tencentcloud_waf.go @@ -625,8 +625,9 @@ func (me *WafService) DescribeWafInstanceById(ctx context.Context, instanceId st }() ratelimit.Check(request.GetAction()) - - response, err := me.client.UseWafClient().DescribeInstances(request) + var iacExtInfo connectivity.IacExtInfo + iacExtInfo.InstanceId = instanceId + response, err := me.client.UseWafClient(iacExtInfo).DescribeInstances(request) if err != nil { errRet = err return diff --git a/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http/request.go b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http/request.go index 80caf9eb3a..5494a0ac72 100644 --- a/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http/request.go +++ b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http/request.go @@ -265,7 +265,7 @@ func CompleteCommonParams(request Request, region string, requestClient string) params["Action"] = request.GetAction() params["Timestamp"] = strconv.FormatInt(time.Now().Unix(), 10) params["Nonce"] = strconv.Itoa(rand.Int()) - params["RequestClient"] = "SDK_GO_1.0.860" + params["RequestClient"] = "SDK_GO_1.0.888" if requestClient != "" { params["RequestClient"] += ": " + requestClient } diff --git a/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/json/encode.go b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/json/encode.go index c9850b63c0..eecf128774 100644 --- a/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/json/encode.go +++ b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/json/encode.go @@ -635,15 +635,27 @@ type structEncoder struct { fieldEncs []encoderFunc } +const ( + OmitNil = 0 + iota + OmitEmpty +) + +var OmitBehaviour = OmitNil + +func shouldOmit(f field, fv reflect.Value) bool { + if OmitBehaviour == OmitNil { + return !fv.IsValid() || (f.omitNil || f.omitEmpty) && isNilValue(fv) + } else { + return !fv.IsValid() || (f.omitNil || f.omitEmpty) && isEmptyValue(fv) + } +} + func (se *structEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { e.WriteByte('{') first := true for i, f := range se.fields { fv := fieldByIndex(v, f.index) - if !fv.IsValid() || f.omitEmpty && isEmptyValue(fv) { - continue - } - if !fv.IsValid() || f.omitNil && isNilValue(fv) { + if shouldOmit(f, fv) { continue } if first { diff --git a/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/oidc_role_arn_provider.go b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/oidc_role_arn_provider.go index bde372bc70..0522bc08fa 100644 --- a/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/oidc_role_arn_provider.go +++ b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/oidc_role_arn_provider.go @@ -21,6 +21,7 @@ type OIDCRoleArnProvider struct { roleSessionName string durationSeconds int64 Endpoint string + beforeRefresh func(provider *OIDCRoleArnProvider) error } type oidcStsRsp struct { @@ -54,33 +55,46 @@ func NewOIDCRoleArnProvider(region, providerId, webIdentityToken, roleArn, roleS // 4. roleSessionName will be "tencentcloud-go-sdk-" + timestamp // 5. durationSeconds will be 7200s func DefaultTkeOIDCRoleArnProvider() (*OIDCRoleArnProvider, error) { - reg := os.Getenv("TKE_REGION") - if reg == "" { - return nil, errors.New("env TKE_REGION not exist") + beforeRefresh := func(provider *OIDCRoleArnProvider) error { + reg := os.Getenv("TKE_REGION") + if reg == "" { + return errors.New("env TKE_REGION not exist") + } + + providerId := os.Getenv("TKE_PROVIDER_ID") + if providerId == "" { + return errors.New("env TKE_PROVIDER_ID not exist") + } + + tokenFile := os.Getenv("TKE_WEB_IDENTITY_TOKEN_FILE") + if tokenFile == "" { + return errors.New("env TKE_WEB_IDENTITY_TOKEN_FILE not exist") + } + tokenBytes, err := ioutil.ReadFile(tokenFile) + if err != nil { + return err + } + + roleArn := os.Getenv("TKE_ROLE_ARN") + if roleArn == "" { + return errors.New("env TKE_ROLE_ARN not exist") + } + + sessionName := defaultSessionName + strconv.FormatInt(time.Now().UnixNano()/1000, 10) + + provider.region = region + provider.providerId = providerId + provider.webIdentityToken = string(tokenBytes) + provider.roleArn = roleArn + provider.roleSessionName = sessionName + return nil } - providerId := os.Getenv("TKE_PROVIDER_ID") - if providerId == "" { - return nil, errors.New("env TKE_PROVIDER_ID not exist") + provider := &OIDCRoleArnProvider{ + beforeRefresh: beforeRefresh, + durationSeconds: defaultDurationSeconds, } - - tokenFile := os.Getenv("TKE_WEB_IDENTITY_TOKEN_FILE") - if tokenFile == "" { - return nil, errors.New("env TKE_WEB_IDENTITY_TOKEN_FILE not exist") - } - tokenBytes, err := ioutil.ReadFile(tokenFile) - if err != nil { - return nil, err - } - - roleArn := os.Getenv("TKE_ROLE_ARN") - if roleArn == "" { - return nil, errors.New("env TKE_ROLE_ARN not exist") - } - - sessionName := defaultSessionName + strconv.FormatInt(time.Now().UnixNano()/1000, 10) - - return NewOIDCRoleArnProvider(reg, providerId, string(tokenBytes), roleArn, sessionName, defaultDurationSeconds), nil + return provider, provider.beforeRefresh(provider) } func (r *OIDCRoleArnProvider) GetCredential() (CredentialIface, error) { @@ -89,6 +103,14 @@ func (r *OIDCRoleArnProvider) GetCredential() (CredentialIface, error) { version = "2018-08-13" action = "AssumeRoleWithWebIdentity" ) + + if r.beforeRefresh != nil { + err := r.beforeRefresh(r) + if err != nil { + return nil, err + } + } + if r.durationSeconds > 43200 || r.durationSeconds <= 0 { return nil, tcerr.NewTencentCloudSDKError(creErr, "AssumeRoleWithWebIdentity durationSeconds should be in the range of 0~43200s", "") } @@ -131,7 +153,7 @@ func (r *OIDCRoleArnProvider) GetCredential() (CredentialIface, error) { roleArn: r.roleArn, roleSessionName: r.roleSessionName, durationSeconds: r.durationSeconds, - expiredTime: int64(rspSt.Response.ExpiredTime), + expiredTime: int64(rspSt.Response.ExpiredTime) - r.durationSeconds/10, token: rspSt.Response.Credentials.Token, tmpSecretId: rspSt.Response.Credentials.TmpSecretId, tmpSecretKey: rspSt.Response.Credentials.TmpSecretKey, diff --git a/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/role_arn_credential.go b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/role_arn_credential.go index ad5917304c..e668c3d19d 100644 --- a/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/role_arn_credential.go +++ b/vendor/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/role_arn_credential.go @@ -56,6 +56,7 @@ func (c *RoleArnCredential) refresh() { newCre, err := c.source.GetCredential() if err != nil { log.Println(err) + return } *c = *newCre.(*RoleArnCredential) } diff --git a/vendor/modules.txt b/vendor/modules.txt index d6f1737f10..2c91857f23 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1160,7 +1160,7 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cloudaudit/v20190319 # github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cls v1.0.860 ## explicit; go 1.14 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cls/v20201016 -# github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.860 +# github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.888 ## explicit; go 1.11 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors diff --git a/website/docs/d/ckafka_topics.html.markdown b/website/docs/d/ckafka_topics.html.markdown index a1aac5fedc..0e593ca176 100644 --- a/website/docs/d/ckafka_topics.html.markdown +++ b/website/docs/d/ckafka_topics.html.markdown @@ -14,20 +14,9 @@ Use this data source to query detailed information of ckafka topic. ## Example Usage ```hcl -resource "tencentcloud_ckafka_topic" "foo" { - instance_id = "ckafka-f9ife4zz" - topic_name = "example" - note = "topic note" - replica_num = 2 - partition_num = 1 - enable_white_list = true - ip_white_list = ["ip1", "ip2"] - clean_up_policy = "delete" - sync_replica_min_num = 1 - unclean_leader_election_enable = false - segment = 3600000 - retention = 60000 - max_message_bytes = 1024 +data "tencentcloud_ckafka_topics" "example" { + instance_id = "ckafka-vv7wp5nx" + topic_name = "tf_example" } ``` diff --git a/website/docs/d/mariadb_db_instances.html.markdown b/website/docs/d/mariadb_db_instances.html.markdown index b68a482821..0a8263d49d 100644 --- a/website/docs/d/mariadb_db_instances.html.markdown +++ b/website/docs/d/mariadb_db_instances.html.markdown @@ -41,6 +41,9 @@ In addition to all arguments above, the following attributes are exported: * `db_version_id` - db version id. * `instance_id` - instance id. * `instance_name` - instance name. + * `internet_domain` - Public network access domain name. + * `internet_ip` - Public IP address. + * `internet_port` - Public network port. * `memory` - meory of instance. * `project_id` - project id. * `region` - region. @@ -49,7 +52,9 @@ In addition to all arguments above, the following attributes are exported: * `tag_value` - tag value. * `storage` - storage of instance. * `subnet_id` - subnet id. + * `vip` - Intranet IP address. * `vpc_id` - vpc id. + * `vport` - Intranet port. * `zone` - available zone. diff --git a/website/docs/r/dasb_acl.html.markdown b/website/docs/r/dasb_acl.html.markdown index 26702347bd..e250a012c1 100644 --- a/website/docs/r/dasb_acl.html.markdown +++ b/website/docs/r/dasb_acl.html.markdown @@ -14,6 +14,39 @@ Provides a resource to create a dasb acl ## Example Usage ```hcl +resource "tencentcloud_dasb_user" "example" { + user_name = "tf_example" + real_name = "terraform" + phone = "+86|18345678782" + email = "demo@tencent.com" + auth_type = 0 +} + +resource "tencentcloud_dasb_user_group" "example" { + name = "tf_example" +} + +resource "tencentcloud_dasb_device" "example" { + os_name = "Linux" + ip = "192.168.0.1" + port = 80 + name = "tf_example" +} + +resource "tencentcloud_dasb_device_group" "example" { + name = "tf_example" +} + +resource "tencentcloud_dasb_device_account" "example" { + device_id = tencentcloud_dasb_device.example.id + account = "root" +} + +resource "tencentcloud_dasb_cmd_template" "example" { + name = "tf_example" + cmd_list = "rm -rf*" +} + resource "tencentcloud_dasb_acl" "example" { name = "tf_example" allow_disk_redirect = true @@ -26,12 +59,12 @@ resource "tencentcloud_dasb_acl" "example" { allow_file_down = true max_file_up_size = 0 max_file_down_size = 0 - user_id_set = ["6", "2"] - user_group_id_set = ["6", "36"] - device_id_set = ["39", "81"] - device_group_id_set = ["2", "3"] - account_set = ["root"] - cmd_template_id_set = ["1", "7"] + user_id_set = [tencentcloud_dasb_user.example.id] + user_group_id_set = [tencentcloud_dasb_user_group.example.id] + device_id_set = [tencentcloud_dasb_device.example.id] + device_group_id_set = [tencentcloud_dasb_device_group.example.id] + account_set = [tencentcloud_dasb_device_account.example.id] + cmd_template_id_set = [tencentcloud_dasb_cmd_template.example.id] ac_template_id_set = [] allow_disk_file_up = true allow_disk_file_down = true @@ -39,9 +72,6 @@ resource "tencentcloud_dasb_acl" "example" { allow_shell_file_down = true allow_file_del = true allow_access_credential = true - department_id = "1.2" - validate_from = "2023-09-22T00:00:00+08:00" - validate_to = "2024-09-23T00:00:00+08:00" } ``` diff --git a/website/docs/r/dasb_bind_device_account_password.html.markdown b/website/docs/r/dasb_bind_device_account_password.html.markdown index 70b97716e1..82d4c407eb 100644 --- a/website/docs/r/dasb_bind_device_account_password.html.markdown +++ b/website/docs/r/dasb_bind_device_account_password.html.markdown @@ -14,8 +14,20 @@ Provides a resource to create a dasb bind_device_account_password ## Example Usage ```hcl +resource "tencentcloud_dasb_device" "example" { + os_name = "Linux" + ip = "192.168.0.1" + port = 80 + name = "tf_example" +} + +resource "tencentcloud_dasb_device_account" "example" { + device_id = tencentcloud_dasb_device.example.id + account = "root" +} + resource "tencentcloud_dasb_bind_device_account_password" "example" { - device_account_id = 16 + device_account_id = tencentcloud_dasb_device_account.example.id password = "TerraformPassword" } ``` diff --git a/website/docs/r/dasb_bind_device_account_private_key.html.markdown b/website/docs/r/dasb_bind_device_account_private_key.html.markdown index 4a5141bd6e..8d04c3339a 100644 --- a/website/docs/r/dasb_bind_device_account_private_key.html.markdown +++ b/website/docs/r/dasb_bind_device_account_private_key.html.markdown @@ -14,8 +14,20 @@ Provides a resource to create a dasb bind_device_account_private_key ## Example Usage ```hcl +resource "tencentcloud_dasb_device" "example" { + os_name = "Linux" + ip = "192.168.0.1" + port = 80 + name = "tf_example" +} + +resource "tencentcloud_dasb_device_account" "example" { + device_id = tencentcloud_dasb_device.example.id + account = "root" +} + resource "tencentcloud_dasb_bind_device_account_private_key" "example" { - device_account_id = 16 + device_account_id = tencentcloud_dasb_device_account.example.id private_key = "MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUpwmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ51s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh" private_key_password = "TerraformPassword" } diff --git a/website/docs/r/dasb_bind_device_resource.html.markdown b/website/docs/r/dasb_bind_device_resource.html.markdown index 3cb966b6be..850b59a2c2 100644 --- a/website/docs/r/dasb_bind_device_resource.html.markdown +++ b/website/docs/r/dasb_bind_device_resource.html.markdown @@ -15,7 +15,7 @@ Provides a resource to create a dasb bind_device_resource ```hcl resource "tencentcloud_dasb_bind_device_resource" "example" { - resource_id = "bh-saas-ocmzo6lgxiv" + resource_id = "bh-saas-weyosfym" device_id_set = [17, 18] } ``` diff --git a/website/docs/r/dasb_device_account.html.markdown b/website/docs/r/dasb_device_account.html.markdown index eb66ae3158..9063f29f8e 100644 --- a/website/docs/r/dasb_device_account.html.markdown +++ b/website/docs/r/dasb_device_account.html.markdown @@ -14,8 +14,15 @@ Provides a resource to create a dasb device_account ## Example Usage ```hcl +resource "tencentcloud_dasb_device" "example" { + os_name = "Linux" + ip = "192.168.0.1" + port = 80 + name = "tf_example" +} + resource "tencentcloud_dasb_device_account" "example" { - device_id = 100 + device_id = tencentcloud_dasb_device.example.id account = "root" } ``` diff --git a/website/docs/r/dasb_device_group_members.html.markdown b/website/docs/r/dasb_device_group_members.html.markdown index 026a7cd220..9798db1039 100644 --- a/website/docs/r/dasb_device_group_members.html.markdown +++ b/website/docs/r/dasb_device_group_members.html.markdown @@ -14,9 +14,20 @@ Provides a resource to create a dasb device_group_members ## Example Usage ```hcl +resource "tencentcloud_dasb_device" "example" { + os_name = "Linux" + ip = "192.168.0.1" + port = 80 + name = "tf_example" +} + +resource "tencentcloud_dasb_device_group" "example" { + name = "tf_example" +} + resource "tencentcloud_dasb_device_group_members" "example" { - device_group_id = 3 - member_id_set = [1, 2, 3] + device_group_id = tencentcloud_dasb_device_group.example.id + member_id_set = [tencentcloud_dasb_device.example.id] } ``` @@ -40,6 +51,6 @@ In addition to all arguments above, the following attributes are exported: dasb device_group_members can be imported using the id, e.g. ``` -terraform import tencentcloud_dasb_device_group_members.example 3#1,2,3 +terraform import tencentcloud_dasb_device_group_members.example 53#102 ``` diff --git a/website/docs/r/dasb_resource.html.markdown b/website/docs/r/dasb_resource.html.markdown index 25f59980a1..e40f660cbb 100644 --- a/website/docs/r/dasb_resource.html.markdown +++ b/website/docs/r/dasb_resource.html.markdown @@ -13,19 +13,41 @@ Provides a resource to create a dasb resource ## Example Usage +### Create a standard version instance + ```hcl resource "tencentcloud_dasb_resource" "example" { deploy_region = "ap-guangzhou" - vpc_id = "vpc-q1of50wz" - subnet_id = "subnet-7uhvm46o" + deploy_zone = "ap-guangzhou-6" + vpc_id = "vpc-fmz6l9nz" + subnet_id = "subnet-g7jhwhi2" + vpc_cidr_block = "10.35.0.0/16" + cidr_block = "10.35.20.0/24" resource_edition = "standard" - resource_node = 2 + resource_node = 50 time_unit = "m" time_span = 1 auto_renew_flag = 1 + package_bandwidth = 1 +} +``` + +### Create a professional instance + +```hcl +resource "tencentcloud_dasb_resource" "example" { + deploy_region = "ap-guangzhou" deploy_zone = "ap-guangzhou-6" - package_bandwidth = 10 - package_node = 50 + vpc_id = "vpc-fmz6l9nz" + subnet_id = "subnet-g7jhwhi2" + vpc_cidr_block = "10.35.0.0/16" + cidr_block = "10.35.20.0/24" + resource_edition = "pro" + resource_node = 50 + time_unit = "m" + time_span = 1 + auto_renew_flag = 1 + package_bandwidth = 1 } ``` @@ -34,16 +56,17 @@ resource "tencentcloud_dasb_resource" "example" { The following arguments are supported: * `auto_renew_flag` - (Required, Int) Automatic renewal. 1 is auto renew flag, 0 is not. +* `cidr_block` - (Required, String) Subnet segments that require service activation. * `deploy_region` - (Required, String) Deploy region. +* `deploy_zone` - (Required, String) Deploy zone. * `resource_edition` - (Required, String) Resource type.Value:standard/pro. * `resource_node` - (Required, Int) Number of resource nodes. * `subnet_id` - (Required, String) Deploy resource subnetId. -* `time_span` - (Required, Int) Billing time. -* `time_unit` - (Required, String) Billing cycle, only support m: month. +* `vpc_cidr_block` - (Required, String) The network segment corresponding to the VPC that requires service activation. * `vpc_id` - (Required, String) Deploy resource vpcId. -* `deploy_zone` - (Optional, String) Deploy zone. -* `package_bandwidth` - (Optional, Int) Number of bandwidth expansion packets (4M). -* `package_node` - (Optional, Int) Number of authorized point extension packages (50 points). +* `package_bandwidth` - (Optional, Int) Number of bandwidth expansion packets (4M), The set value is an integer multiple of 4. +* `time_span` - (Optional, Int) Billing time. This field is mandatory, with a minimum value of 1. +* `time_unit` - (Optional, String) Billing cycle, only support m: month. This field is mandatory, fill in m. ## Attributes Reference @@ -58,6 +81,6 @@ In addition to all arguments above, the following attributes are exported: dasb resource can be imported using the id, e.g. ``` -terraform import tencentcloud_dasb_resource.example bh-saas-kk5rabk0 +terraform import tencentcloud_dasb_resource.example bh-saas-kgckynrt ``` diff --git a/website/docs/r/dasb_user_group.html.markdown b/website/docs/r/dasb_user_group.html.markdown index d5c5b37db9..1cb5e0dc38 100644 --- a/website/docs/r/dasb_user_group.html.markdown +++ b/website/docs/r/dasb_user_group.html.markdown @@ -15,7 +15,7 @@ Provides a resource to create a dasb user_group ```hcl resource "tencentcloud_dasb_user_group" "example" { - name = "tf_example_update" + name = "tf_example" } ``` @@ -23,7 +23,7 @@ resource "tencentcloud_dasb_user_group" "example" { ```hcl resource "tencentcloud_dasb_user_group" "example" { - name = "tf_example_update" + name = "tf_example" department_id = "1.2" } ``` diff --git a/website/docs/r/dasb_user_group_members.html.markdown b/website/docs/r/dasb_user_group_members.html.markdown index bbdaf1d195..5e571e71be 100644 --- a/website/docs/r/dasb_user_group_members.html.markdown +++ b/website/docs/r/dasb_user_group_members.html.markdown @@ -14,9 +14,21 @@ Provides a resource to create a dasb user_group_members ## Example Usage ```hcl +resource "tencentcloud_dasb_user" "example" { + user_name = "tf_example" + real_name = "terraform" + phone = "+86|18345678782" + email = "demo@tencent.com" + auth_type = 0 +} + +resource "tencentcloud_dasb_user_group" "example" { + name = "tf_example" +} + resource "tencentcloud_dasb_user_group_members" "example" { - user_group_id = 3 - member_id_set = [1, 2, 3] + user_group_id = tencentcloud_dasb_user_group.example.id + member_id_set = [tencentcloud_dasb_user.example.id] } ``` @@ -40,6 +52,6 @@ In addition to all arguments above, the following attributes are exported: dasb user_group_members can be imported using the id, e.g. ``` -terraform import tencentcloud_dasb_user_group_members.example 3#1,2,3 +terraform import tencentcloud_dasb_user_group_members.example 3#14 ``` diff --git a/website/docs/r/eni_ipv4_address.html.markdown b/website/docs/r/eni_ipv4_address.html.markdown new file mode 100644 index 0000000000..12c90b8eb2 --- /dev/null +++ b/website/docs/r/eni_ipv4_address.html.markdown @@ -0,0 +1,62 @@ +--- +subcategory: "Virtual Private Cloud(VPC)" +layout: "tencentcloud" +page_title: "TencentCloud: tencentcloud_eni_ipv4_address" +sidebar_current: "docs-tencentcloud-resource-eni_ipv4_address" +description: |- + Provides a resource to create a vpc eni_ipv4_address +--- + +# tencentcloud_eni_ipv4_address + +Provides a resource to create a vpc eni_ipv4_address + +## Example Usage + +```hcl +data "tencentcloud_enis" "eni" { + name = "Primary ENI" +} + +resource "tencentcloud_eni_ipv4_address" "eni_ipv4_address" { + network_interface_id = data.tencentcloud_enis.eni.enis.0.id + secondary_private_ip_address_count = 3 +} +``` + +## Argument Reference + +The following arguments are supported: + +* `network_interface_id` - (Required, String, ForceNew) The ID of the ENI instance, such as `eni-m6dyj72l`. +* `private_ip_addresses` - (Optional, Set, ForceNew) The information on private IP addresses, of which you can specify a maximum of 10 at a time. You should provide either this parameter or SecondaryPrivateIpAddressCount, or both. +* `qos_level` - (Optional, String, ForceNew) IP service level. It is used together with `SecondaryPrivateIpAddressCount`. Values: PT`(Gold), `AU`(Silver), `AG `(Bronze) and DEFAULT (Default). +* `secondary_private_ip_address_count` - (Optional, Int, ForceNew) The number of newly-applied private IP addresses. You should provide either this parameter or PrivateIpAddresses, or both. The total number of private IP addresses cannot exceed the quota. + +The `private_ip_addresses` object supports the following: + +* `private_ip_address` - (Required, String, ForceNew) Private IP address. +* `address_id` - (Optional, String, ForceNew) EIP instance ID, such as `eip-11112222`. +* `description` - (Optional, String, ForceNew) Private IP description. +* `is_wan_ip_blocked` - (Optional, Bool, ForceNew) Whether the public IP is blocked. +* `primary` - (Optional, Bool, ForceNew) Whether it is a primary IP. +* `public_ip_address` - (Optional, String, ForceNew) Public IP address. +* `qos_level` - (Optional, String, ForceNew) IP service level. Values: PT` (Gold), `AU` (Silver), `AG `(Bronze) and DEFAULT` (Default). +* `state` - (Optional, String, ForceNew) IP status: `PENDING`: Creating, `MIGRATING`: Migrating, `DELETING`: Deleting, `AVAILABLE`: Available. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - ID of the resource. + + + +## Import + +vpc eni_ipv4_address can be imported using the id, e.g. + +``` +terraform import tencentcloud_eni_ipv4_address.eni_ipv4_address eni_id +``` + diff --git a/website/docs/r/eni_ipv6_address.html.markdown b/website/docs/r/eni_ipv6_address.html.markdown new file mode 100644 index 0000000000..b83e7b8bdc --- /dev/null +++ b/website/docs/r/eni_ipv6_address.html.markdown @@ -0,0 +1,90 @@ +--- +subcategory: "Virtual Private Cloud(VPC)" +layout: "tencentcloud" +page_title: "TencentCloud: tencentcloud_eni_ipv6_address" +sidebar_current: "docs-tencentcloud-resource-eni_ipv6_address" +description: |- + Provides a resource to create a vpc eni_ipv6_address +--- + +# tencentcloud_eni_ipv6_address + +Provides a resource to create a vpc eni_ipv6_address + +## Example Usage + +```hcl +data "tencentcloud_availability_zones" "zones" {} + +resource "tencentcloud_vpc" "vpc" { + name = "vpc-example" + cidr_block = "10.0.0.0/16" +} + +resource "tencentcloud_subnet" "subnet" { + availability_zone = data.tencentcloud_availability_zones.zones.zones.0.name + name = "subnet-example" + vpc_id = tencentcloud_vpc.vpc.id + cidr_block = "10.0.0.0/16" + is_multicast = false +} + +resource "tencentcloud_eni" "eni" { + name = "eni-example" + vpc_id = tencentcloud_vpc.vpc.id + subnet_id = tencentcloud_subnet.subnet.id + description = "eni desc." + ipv4_count = 1 +} + +resource "tencentcloud_vpc_ipv6_cidr_block" "example" { + vpc_id = tencentcloud_vpc.vpc.id +} + +resource "tencentcloud_vpc_ipv6_subnet_cidr_block" "example" { + vpc_id = tencentcloud_vpc.vpc.id + ipv6_subnet_cidr_blocks { + subnet_id = tencentcloud_subnet.subnet.id + ipv6_cidr_block = "2402:4e00:1018:6700::/64" + } +} + +resource "tencentcloud_eni_ipv6_address" "ipv6_eni_address" { + network_interface_id = tencentcloud_eni.eni.id + ipv6_address_count = 1 +} +``` + +## Argument Reference + +The following arguments are supported: + +* `network_interface_id` - (Required, String, ForceNew) ENI instance `ID`, in the form of `eni-m6dyj72l`. +* `ipv6_address_count` - (Optional, Int, ForceNew) The number of automatically assigned IPv6 addresses and the total number of private IP addresses cannot exceed the quota. This should be combined with the input parameter `ipv6_addresses` for quota calculation. At least one of them, either this or 'Ipv6Addresses', must be provided. +* `ipv6_addresses` - (Optional, Set, ForceNew) The specified `IPv6` address list, up to 10 can be specified at a time. Combined with the input parameter `Ipv6AddressCount` to calculate the quota. Mandatory one with Ipv6AddressCount. + +The `ipv6_addresses` object supports the following: + +* `address` - (Required, String, ForceNew) `IPv6` address, in the form of: `3402:4e00:20:100:0:8cd9:2a67:71f3`. +* `address_id` - (Optional, String, ForceNew) `EIP` instance `ID`, such as:`eip-hxlqja90`. +* `description` - (Optional, String, ForceNew) Description. +* `is_wan_ip_blocked` - (Optional, Bool, ForceNew) Whether the public network IP is blocked. +* `primary` - (Optional, Bool, ForceNew) Whether to master `IP`. +* `state` - (Optional, String, ForceNew) `IPv6` address status: `PENDING`: pending, `MIGRATING`: migrating, `DELETING`: deleting, `AVAILABLE`: available. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - ID of the resource. + + + +## Import + +vpc eni_ipv6_address can be imported using the id, e.g. + +``` +terraform import tencentcloud_eni_ipv6_address.ipv6_eni_address eni_id +``` + diff --git a/website/docs/r/instance.html.markdown b/website/docs/r/instance.html.markdown index e48019fbff..8ab3514f74 100644 --- a/website/docs/r/instance.html.markdown +++ b/website/docs/r/instance.html.markdown @@ -169,6 +169,7 @@ In addition to all arguments above, the following attributes are exported: * `expired_time` - Expired time of the instance. * `instance_status` - Current status of the instance. * `public_ip` - Public IP of the instance. +* `uuid` - Globally unique ID of the instance. ## Import diff --git a/website/docs/r/kubernetes_cluster.html.markdown b/website/docs/r/kubernetes_cluster.html.markdown index 6079ac7990..4ade5b8748 100644 --- a/website/docs/r/kubernetes_cluster.html.markdown +++ b/website/docs/r/kubernetes_cluster.html.markdown @@ -817,7 +817,7 @@ The following arguments are supported: * `cluster_name` - (Optional, String) Name of the cluster. * `cluster_os_type` - (Optional, String, ForceNew) Image type of the cluster os, the available values include: 'GENERAL'. Default is 'GENERAL'. * `cluster_os` - (Optional, String, ForceNew) Operating system of the cluster, the available values include: 'centos7.6.0_x64','ubuntu18.04.1x86_64','tlinux2.4x86_64'. Default is 'tlinux2.4x86_64'. -* `cluster_subnet_id` - (Optional, String) Subnet ID of the cluster, such as: subnet-b3p7d7q5. +* `cluster_subnet_id` - (Optional, String, ForceNew) Subnet ID of the cluster, such as: subnet-b3p7d7q5. * `cluster_version` - (Optional, String) Version of the cluster. Use `tencentcloud_kubernetes_available_cluster_versions` to get the upgradable cluster version. * `container_runtime` - (Optional, String, ForceNew) Runtime type of the cluster, the available values include: 'docker' and 'containerd'.The Kubernetes v1.24 has removed dockershim, so please use containerd in v1.24 or higher.Default is 'docker'. * `deletion_protection` - (Optional, Bool) Indicates whether cluster deletion protection is enabled. Default is false. diff --git a/website/docs/r/kubernetes_node_pool.html.markdown b/website/docs/r/kubernetes_node_pool.html.markdown index f9f05f9a35..1e4c1c1710 100644 --- a/website/docs/r/kubernetes_node_pool.html.markdown +++ b/website/docs/r/kubernetes_node_pool.html.markdown @@ -268,3 +268,11 @@ In addition to all arguments above, the following attributes are exported: * `status` - Status of the node pool. +## Import + +tke node pool can be imported, e.g. + +``` +$ terraform import tencentcloud_kubernetes_node_pool.test cls-xxx#np-xxx +``` + diff --git a/website/docs/r/private_dns_record.html.markdown b/website/docs/r/private_dns_record.html.markdown index f7e5adddb0..709c4cbefc 100644 --- a/website/docs/r/private_dns_record.html.markdown +++ b/website/docs/r/private_dns_record.html.markdown @@ -14,8 +14,30 @@ Provide a resource to create a Private Dns Record. ## Example Usage ```hcl -resource "tencentcloud_private_dns_record" "foo" { - zone_id = "zone-rqndjnki" +resource "tencentcloud_vpc" "vpc" { + name = "vpc-example" + cidr_block = "10.0.0.0/16" +} + +resource "tencentcloud_private_dns_zone" "example" { + domain = "domain.com" + remark = "remark." + + vpc_set { + region = "ap-guangzhou" + uniq_vpc_id = tencentcloud_vpc.vpc.id + } + + dns_forward_status = "DISABLED" + cname_speedup_status = "ENABLED" + + tags = { + createdBy : "terraform" + } +} + +resource "tencentcloud_private_dns_record" "example" { + zone_id = tencentcloud_private_dns_zone.example.id record_type = "A" record_value = "192.168.1.2" sub_domain = "www" @@ -30,9 +52,9 @@ resource "tencentcloud_private_dns_record" "foo" { The following arguments are supported: * `record_type` - (Required, String) Record type. Valid values: "A", "AAAA", "CNAME", "MX", "TXT", "PTR". -* `record_value` - (Required, String) Record value, such as IP: 192.168.10.2, CNAME: cname.qcloud.com, and MX: mail.qcloud.com.. +* `record_value` - (Required, String) Record value, such as IP: 192.168.10.2, CNAME: cname.qcloud.com, and MX: mail.qcloud.com. * `sub_domain` - (Required, String) Subdomain, such as "www", "m", and "@". -* `zone_id` - (Required, String) Private domain ID. +* `zone_id` - (Required, String, ForceNew) Private domain ID. * `mx` - (Optional, Int) MX priority, which is required when the record type is MX. Valid values: 5, 10, 15, 20, 30, 40, 50. * `ttl` - (Optional, Int) Record cache time. The smaller the value, the faster the record will take effect. Value range: 1~86400s. * `weight` - (Optional, Int) Record weight. Value range: 1~100. @@ -50,6 +72,6 @@ In addition to all arguments above, the following attributes are exported: Private Dns Record can be imported, e.g. ``` -$ terraform import tencentcloud_private_dns_zone.foo zone_id#record_id +$ terraform import tencentcloud_private_dns_record.example zone-iza3a33s#1983030 ``` diff --git a/website/docs/r/private_dns_zone.html.markdown b/website/docs/r/private_dns_zone.html.markdown index 7c9b89f7bf..ddc231f322 100644 --- a/website/docs/r/private_dns_zone.html.markdown +++ b/website/docs/r/private_dns_zone.html.markdown @@ -110,6 +110,6 @@ In addition to all arguments above, the following attributes are exported: Private Dns Zone can be imported, e.g. ``` -$ terraform import tencentcloud_private_dns_zone.foo zone_id +$ terraform import tencentcloud_private_dns_zone.example zone-6xg5xgky ``` diff --git a/website/docs/r/tse_cngw_network_access_control.html.markdown b/website/docs/r/tse_cngw_network_access_control.html.markdown new file mode 100644 index 0000000000..bdf84b4e7d --- /dev/null +++ b/website/docs/r/tse_cngw_network_access_control.html.markdown @@ -0,0 +1,58 @@ +--- +subcategory: "Tencent Cloud Service Engine(TSE)" +layout: "tencentcloud" +page_title: "TencentCloud: tencentcloud_tse_cngw_network_access_control" +sidebar_current: "docs-tencentcloud-resource-tse_cngw_network_access_control" +description: |- + Provides a resource to create a tse cngw_network_access_control +--- + +# tencentcloud_tse_cngw_network_access_control + +Provides a resource to create a tse cngw_network_access_control + +## Example Usage + +```hcl +resource "tencentcloud_tse_cngw_network_access_control" "cngw_network_access_control" { + gateway_id = "gateway-cf8c99c3" + group_id = "group-a160d123" + network_id = "network-372b1e84" + access_control { + mode = "Whitelist" + cidr_white_list = ["1.1.1.0"] + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `gateway_id` - (Required, String, ForceNew) gateway ID. +* `group_id` - (Required, String, ForceNew) gateway group ID. +* `network_id` - (Required, String, ForceNew) network id. +* `access_control` - (Optional, List) access control policy. + +The `access_control` object supports the following: + +* `cidr_black_list` - (Optional, List) Black list. +* `cidr_white_list` - (Optional, List) White list. +* `mode` - (Optional, String) Access mode: `Whitelist`, `Blacklist`. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - ID of the resource. + + + +## Import + +tse cngw_route_rate_limit can be imported using the id, e.g. + +``` +terraform import tencentcloud_tse_cngw_network_access_control.cngw_network_access_control gatewayId#groupId#networkId +``` + diff --git a/website/docs/r/vod_adaptive_dynamic_streaming_template.html.markdown b/website/docs/r/vod_adaptive_dynamic_streaming_template.html.markdown index 55fefeba0e..faa5735271 100644 --- a/website/docs/r/vod_adaptive_dynamic_streaming_template.html.markdown +++ b/website/docs/r/vod_adaptive_dynamic_streaming_template.html.markdown @@ -14,44 +14,36 @@ Provide a resource to create a VOD adaptive dynamic streaming template. ## Example Usage ```hcl +resource "tencentcloud_vod_sub_application" "sub_application" { + name = "adaptive-subapplication" + status = "On" + description = "this is sub application" +} + resource "tencentcloud_vod_adaptive_dynamic_streaming_template" "foo" { format = "HLS" name = "tf-adaptive" + sub_app_id = tonumber(split("#", tencentcloud_vod_sub_application.sub_application.id)[1]) drm_type = "SimpleAES" disable_higher_video_bitrate = false disable_higher_video_resolution = false comment = "test" - stream_info { - video { - codec = "libx265" - fps = 4 - bitrate = 129 - resolution_adaptive = false - width = 128 - height = 128 - fill_type = "stretch" - } - audio { - codec = "libmp3lame" - bitrate = 129 - sample_rate = 44100 - audio_channel = "dual" - } - remove_audio = false - } stream_info { video { codec = "libx264" - fps = 4 - bitrate = 256 + fps = 3 + bitrate = 128 } audio { codec = "libfdk_aac" - bitrate = 256 - sample_rate = 44100 + bitrate = 128 + sample_rate = 32000 } remove_audio = true + tehd_config { + type = "TEHD-100" + } } } ``` @@ -67,7 +59,11 @@ The following arguments are supported: * `disable_higher_video_bitrate` - (Optional, Bool) Whether to prohibit transcoding video from low bitrate to high bitrate. Valid values: `false`,`true`. `false`: no, `true`: yes. Default value: `false`. * `disable_higher_video_resolution` - (Optional, Bool) Whether to prohibit transcoding from low resolution to high resolution. Valid values: `false`,`true`. `false`: no, `true`: yes. Default value: `false`. * `drm_type` - (Optional, String, ForceNew) DRM scheme type. Valid values: `SimpleAES`. If this field is an empty string, DRM will not be performed on the video. -* `sub_app_id` - (Optional, Int) Subapplication ID in VOD. If you need to access a resource in a subapplication, enter the subapplication ID in this field; otherwise, leave it empty. +* `segment_type` - (Optional, String) Segment type, valid when Format is HLS, optional values: +- ts: ts segment; +- fmp4: fmp4 segment; +Default value: ts. +* `sub_app_id` - (Optional, Int) The VOD [application](https://intl.cloud.tencent.com/document/product/266/14574) ID. For customers who activate VOD service from December 25, 2023, if they want to access resources in a VOD application (whether it's the default application or a newly created one), they must fill in this field with the application ID. The `audio` object of `stream_info` supports the following: @@ -81,15 +77,38 @@ The `stream_info` object supports the following: * `audio` - (Required, List) Audio parameter information. * `video` - (Required, List) Video parameter information. * `remove_audio` - (Optional, Bool) Whether to remove audio stream. Valid values: `false`: no, `true`: yes. `false` by default. +* `remove_video` - (Optional, Bool) Whether to remove video stream. Valid values: `false`: no, `true`: yes. `false` by default. +* `tehd_config` - (Optional, List) Extremely fast HD transcoding parameters. + +The `tehd_config` object of `stream_info` supports the following: + +* `type` - (Required, String) Extreme high-speed HD type, available values: +- TEHD-100: super high definition-100th; +- OFF: turn off Ultra High definition. +* `max_video_bitrate` - (Optional, Int) Video bitrate limit, which is valid when Type specifies extreme speed HD type. If you leave it empty or enter 0, there is no video bitrate limit. The `video` object of `stream_info` supports the following: * `bitrate` - (Required, Int) Bitrate of video stream in Kbps. Value range: `0` and `[128, 35000]`. If the value is `0`, the bitrate of the video will be the same as that of the source video. * `codec` - (Required, String) Video stream encoder. Valid values: `libx264`,`libx265`,`av1`. `libx264`: H.264, `libx265`: H.265, `av1`: AOMedia Video 1. Currently, a resolution within 640x480 must be specified for `H.265`. and the `av1` container only supports mp4. * `fps` - (Required, Int) Video frame rate in Hz. Value range: `[0, 60]`. If the value is `0`, the frame rate will be the same as that of the source video. +* `codec_tag` - (Optional, String) Encoding label, valid only if the encoding format of the video stream is H.265 encoding. Available values: +- hvc1: stands for hvc1 tag; +- hev1: stands for the hev1 tag; +Default value: hvc1. * `fill_type` - (Optional, String) Fill type. Fill refers to the way of processing a screenshot when its aspect ratio is different from that of the source video. The following fill types are supported: `stretch`: stretch. The screenshot will be stretched frame by frame to match the aspect ratio of the source video, which may make the screenshot shorter or longer; `black`: fill with black. This option retains the aspect ratio of the source video for the screenshot and fills the unmatched area with black color blocks. Default value: black. Note: this field may return null, indicating that no valid values can be obtained. +* `gop` - (Optional, Int) Interval between Keyframe I frames, value range: 0 and [1, 100000], unit: number of frames. When you fill in 0 or leave it empty, the gop length is automatically set. * `height` - (Optional, Int) Maximum value of the height (or short side) of a video stream in px. Value range: `0` and `[128, 4096]`. If both `width` and `height` are `0`, the resolution will be the same as that of the source video; If `width` is `0`, but `height` is not `0`, `width` will be proportionally scaled; If `width` is not `0`, but `height` is `0`, `height` will be proportionally scaled; If both `width` and `height` are not `0`, the custom resolution will be used. Default value: `0`. Note: this field may return null, indicating that no valid values can be obtained. +* `preserve_hdr_switch` - (Optional, String) Whether the transcoding output still maintains HDR when the original video is HDR (High Dynamic Range). Value range: +- ON: if the original file is HDR, the transcoding output remains HDR;, otherwise the transcoding output is SDR (Standard Dynamic Range); +- OFF: regardless of whether the original file is HDR or SDR, the transcoding output is SDR; +Default value: OFF. * `resolution_adaptive` - (Optional, Bool) Resolution adaption. Valid values: `true`,`false`. `true`: enabled. In this case, `width` represents the long side of a video, while `height` the short side; `false`: disabled. In this case, `width` represents the width of a video, while `height` the height. Default value: `true`. Note: this field may return null, indicating that no valid values can be obtained. +* `vcrf` - (Optional, Int) Video constant bit rate control factor, value range is [1,51]. +Note: +- If this parameter is specified, the bitrate control method of CRF will be used for transcoding (the video bitrate will no longer take effect); +- This field is required when the video stream encoding format is H.266. The recommended value is 28; +- If there are no special requirements, it is not recommended to specify this parameter. * `width` - (Optional, Int) Maximum value of the width (or long side) of a video stream in px. Value range: `0` and `[128, 4096]`. If both `width` and `height` are `0`, the resolution will be the same as that of the source video; If `width` is `0`, but `height` is not `0`, `width` will be proportionally scaled; If `width` is not `0`, but `height` is `0`, `height` will be proportionally scaled; If both `width` and `height` are not `0`, the custom resolution will be used. Default value: `0`. Note: this field may return null, indicating that no valid values can be obtained. ## Attributes Reference @@ -103,9 +122,9 @@ In addition to all arguments above, the following attributes are exported: ## Import -VOD adaptive dynamic streaming template can be imported using the id, e.g. +VOD adaptive dynamic streaming template can be imported using the id($subAppId#$templateId), e.g. ``` -$ terraform import tencentcloud_vod_adaptive_dynamic_streaming_template.foo 169141 +$ terraform import tencentcloud_vod_adaptive_dynamic_streaming_template.foo $subAppId#$templateId ``` diff --git a/website/docs/r/vod_event_config.html.markdown b/website/docs/r/vod_event_config.html.markdown new file mode 100644 index 0000000000..f230f9c607 --- /dev/null +++ b/website/docs/r/vod_event_config.html.markdown @@ -0,0 +1,59 @@ +--- +subcategory: "Video on Demand(VOD)" +layout: "tencentcloud" +page_title: "TencentCloud: tencentcloud_vod_event_config" +sidebar_current: "docs-tencentcloud-resource-vod_event_config" +description: |- + Provide a resource to create a vod event config. +--- + +# tencentcloud_vod_event_config + +Provide a resource to create a vod event config. + +## Example Usage + +```hcl +resource "tencentcloud_vod_sub_application" "sub_application" { + name = "eventconfig-subapplication" + status = "On" + description = "this is sub application" +} + +resource "tencentcloud_vod_event_config" "event_config" { + mode = "PUSH" + notification_url = "http://mydemo.com/receiveevent" + upload_media_complete_event_switch = "ON" + delete_media_complete_event_switch = "ON" + sub_app_id = tonumber(split("#", tencentcloud_vod_sub_application.sub_application.id)[1]) +} +``` + +## Argument Reference + +The following arguments are supported: + +* `sub_app_id` - (Required, Int) Sub app id. +* `delete_media_complete_event_switch` - (Optional, String) Whether to receive video deletion completion event notification, default `OFF` is to ignore the event notification, `ON` is to receive event notification. +* `mode` - (Optional, String) How to receive event notifications. Valid values: +- Push: HTTP callback notification; +- PULL: Reliable notification based on message queuing. +* `notification_url` - (Optional, String) The address used to receive 3.0 format callbacks when receiving HTTP callback notifications. Note: If you take the NotificationUrl parameter and the value is an empty string, the 3.0 format callback address is cleared. +* `upload_media_complete_event_switch` - (Optional, String) Whether to receive video upload completion event notification, default `OFF` means to ignore the event notification, `ON` means to receive event notification. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - ID of the resource. + + + +## Import + +VOD event config can be imported using the subAppId, e.g. + +``` +$ terraform import tencentcloud_vod_event_config.foo $subAppId +``` + diff --git a/website/docs/r/vod_image_sprite_template.html.markdown b/website/docs/r/vod_image_sprite_template.html.markdown index 9c4244100b..345783bd05 100644 --- a/website/docs/r/vod_image_sprite_template.html.markdown +++ b/website/docs/r/vod_image_sprite_template.html.markdown @@ -14,8 +14,15 @@ Provide a resource to create a VOD image sprite template. ## Example Usage ```hcl +resource "tencentcloud_vod_sub_application" "sub_application" { + name = "image-sprite-subapplication" + status = "On" + description = "this is sub application" +} + resource "tencentcloud_vod_image_sprite_template" "foo" { sample_type = "Percent" + sub_app_id = tonumber(split("#", tencentcloud_vod_sub_application.sub_application.id)[1]) sample_interval = 10 row_count = 3 column_count = 3 @@ -39,9 +46,14 @@ The following arguments are supported: * `sample_type` - (Required, String) Sampling type. Valid values: `Percent`, `Time`. `Percent`: by percent. `Time`: by time interval. * `comment` - (Optional, String) Template description. Length limit: 256 characters. * `fill_type` - (Optional, String) Fill refers to the way of processing a screenshot when its aspect ratio is different from that of the source video. The following fill types are supported: `stretch`: stretch. The screenshot will be stretched frame by frame to match the aspect ratio of the source video, which may make the screenshot shorter or longer; `black`: fill with black. This option retains the aspect ratio of the source video for the screenshot and fills the unmatched area with black color blocks. Default value: `black`. +* `format` - (Optional, String) Image format, Valid values: +- jpg: jpg format; +- png: png format; +- webp: webp format; +Default value: jpg. * `height` - (Optional, Int) Maximum value of the `height` (or short side) of a screenshot in px. Value range: 0 and [128, 4,096]. If both `width` and `height` are `0`, the resolution will be the same as that of the source video; If `width` is `0`, but `height` is not `0`, `width` will be proportionally scaled; If `width` is not `0`, but `height` is `0`, `height` will be proportionally scaled; If both `width` and `height` are not `0`, the custom resolution will be used. Default value: `0`. * `resolution_adaptive` - (Optional, Bool) Resolution adaption. Valid values: `true`,`false`. `true`: enabled. In this case, `width` represents the long side of a video, while `height` the short side; `false`: disabled. In this case, `width` represents the width of a video, while `height` the height. Default value: `true`. -* `sub_app_id` - (Optional, Int) Subapplication ID in VOD. If you need to access a resource in a subapplication, enter the subapplication ID in this field; otherwise, leave it empty. +* `sub_app_id` - (Optional, Int) The VOD [application](https://intl.cloud.tencent.com/document/product/266/14574) ID. For customers who activate VOD service from December 25, 2023, if they want to access resources in a VOD application (whether it's the default application or a newly created one), they must fill in this field with the application ID. * `width` - (Optional, Int) Maximum value of the `width` (or long side) of a screenshot in px. Value range: 0 and [128, 4,096]. If both `width` and `height` are `0`, the resolution will be the same as that of the source video; If `width` is `0`, but `height` is not `0`, width will be proportionally scaled; If `width` is not `0`, but `height` is `0`, `height` will be proportionally scaled; If both `width` and `height` are not `0`, the custom resolution will be used. Default value: `0`. ## Attributes Reference @@ -50,14 +62,17 @@ In addition to all arguments above, the following attributes are exported: * `id` - ID of the resource. * `create_time` - Creation time of template in ISO date format. +* `type` - Template type, value range: +- Preset: system preset template; +- Custom: user-defined templates. * `update_time` - Last modified time of template in ISO date format. ## Import -VOD image sprite template can be imported using the id, e.g. +VOD image sprite template can be imported using the id($subAppId#$templateId), e.g. ``` -$ terraform import tencentcloud_vod_image_sprite_template.foo 51156 +$ terraform import tencentcloud_vod_image_sprite_template.foo $subAppId#$templateId ``` diff --git a/website/docs/r/vod_procedure_template.html.markdown b/website/docs/r/vod_procedure_template.html.markdown index e5d885f57f..4ae5da1441 100644 --- a/website/docs/r/vod_procedure_template.html.markdown +++ b/website/docs/r/vod_procedure_template.html.markdown @@ -14,9 +14,16 @@ Provide a resource to create a VOD procedure template. ## Example Usage ```hcl +resource "tencentcloud_vod_sub_application" "sub_application" { + name = "procedure-subapplication" + status = "On" + description = "this is sub application" +} + resource "tencentcloud_vod_adaptive_dynamic_streaming_template" "foo" { format = "HLS" name = "tf-adaptive" + sub_app_id = tonumber(split("#", tencentcloud_vod_sub_application.sub_application.id)[1]) drm_type = "SimpleAES" disable_higher_video_bitrate = false disable_higher_video_resolution = false @@ -24,21 +31,16 @@ resource "tencentcloud_vod_adaptive_dynamic_streaming_template" "foo" { stream_info { video { - codec = "libx265" - fps = 4 - bitrate = 129 - resolution_adaptive = false - width = 128 - height = 128 - fill_type = "stretch" + codec = "libx264" + fps = 3 + bitrate = 128 } audio { - codec = "libmp3lame" - bitrate = 129 - sample_rate = 44100 - audio_channel = "dual" + codec = "libfdk_aac" + bitrate = 128 + sample_rate = 32000 } - remove_audio = false + remove_audio = true } stream_info { video { @@ -52,12 +54,16 @@ resource "tencentcloud_vod_adaptive_dynamic_streaming_template" "foo" { sample_rate = 44100 } remove_audio = true + tehd_config { + type = "TEHD-100" + } } } resource "tencentcloud_vod_snapshot_by_time_offset_template" "foo" { name = "tf-snapshot" - width = 130 + sub_app_id = tonumber(split("#", tencentcloud_vod_sub_application.sub_application.id)[1]) + width = 128 height = 128 resolution_adaptive = false format = "png" @@ -67,6 +73,7 @@ resource "tencentcloud_vod_snapshot_by_time_offset_template" "foo" { resource "tencentcloud_vod_image_sprite_template" "foo" { sample_type = "Percent" + sub_app_id = tonumber(split("#", tencentcloud_vod_sub_application.sub_application.id)[1]) sample_interval = 10 row_count = 3 column_count = 3 @@ -78,28 +85,56 @@ resource "tencentcloud_vod_image_sprite_template" "foo" { resolution_adaptive = false } -resource "tencentcloud_vod_sub_application" "sub_application" { - name = "subapplication" - status = "On" - description = "this is sub application" +resource "tencentcloud_vod_transcode_template" "transcode_template" { + container = "mp4" + sub_app_id = tonumber(split("#", tencentcloud_vod_sub_application.sub_application.id)[1]) + name = "720pTranscodeTemplate" + comment = "test transcode mp4 720p update" + remove_video = 0 + remove_audio = 0 + video_template { + codec = "libx264" + fps = 26 + bitrate = 1000 + resolution_adaptive = "open" + width = 0 + height = 720 + fill_type = "stretch" + vcrf = 1 + gop = 250 + preserve_hdr_switch = "OFF" + codec_tag = "hvc1" + + } + audio_template { + codec = "libfdk_aac" + bitrate = 128 + sample_rate = 44100 + audio_channel = 2 + + } + segment_type = "ts" } resource "tencentcloud_vod_procedure_template" "foo" { - name = "tf-procedure" + name = "tf-procedure0" comment = "test" sub_app_id = tonumber(split("#", tencentcloud_vod_sub_application.sub_application.id)[1]) media_process_task { adaptive_dynamic_streaming_task_list { - definition = tencentcloud_vod_adaptive_dynamic_streaming_template.foo.id + definition = tonumber(split("#", tencentcloud_vod_adaptive_dynamic_streaming_template.foo.id)[1]) } snapshot_by_time_offset_task_list { - definition = tencentcloud_vod_snapshot_by_time_offset_template.foo.id + definition = tonumber(split("#", tencentcloud_vod_snapshot_by_time_offset_template.foo.id)[1]) ext_time_offset_list = [ "3.5s" ] } image_sprite_task_list { - definition = tencentcloud_vod_image_sprite_template.foo.id + definition = tonumber(split("#", tencentcloud_vod_image_sprite_template.foo.id)[1]) + } + transcode_task_list { + definition = tonumber(split("#", tencentcloud_vod_transcode_template.transcode_template.id)[1]) } } } @@ -110,21 +145,37 @@ resource "tencentcloud_vod_procedure_template" "foo" { The following arguments are supported: * `name` - (Required, String, ForceNew) Task flow name (up to 20 characters). +* `ai_analysis_task` - (Optional, List) Parameter of AI-based content analysis task. +* `ai_recognition_task` - (Optional, List) Type parameter of AI-based content recognition task. * `comment` - (Optional, String) Template description. Length limit: 256 characters. * `media_process_task` - (Optional, List) Parameter of video processing task. -* `sub_app_id` - (Optional, Int) Subapplication ID in VOD. For customers who activate VOD from December 25, 2023, if they access the resources in the VOD application (whether it is the default application or the newly created application), you must fill in this field as Application ID. +* `review_audio_video_task` - (Optional, List) Type parameter of AI-based content recognition task. +* `sub_app_id` - (Optional, Int) The VOD [application](https://intl.cloud.tencent.com/document/product/266/14574) ID. For customers who activate VOD service from December 25, 2023, if they want to access resources in a VOD application (whether it's the default application or a newly created one), they must fill in this field with the application ID. The `adaptive_dynamic_streaming_task_list` object of `media_process_task` supports the following: * `definition` - (Required, String) Adaptive bitrate streaming template ID. +* `subtitle_list` - (Optional, List) Subtitle list, element is subtitle ID, support multiple subtitles, up to 16. * `watermark_list` - (Optional, List) List of up to `10` image or text watermarks. Note: this field may return null, indicating that no valid values can be obtained. +The `ai_analysis_task` object supports the following: + +* `definition` - (Optional, String) Video content analysis template ID. + +The `ai_recognition_task` object supports the following: + +* `definition` - (Optional, String) Intelligent video recognition template ID. + The `animated_graphic_task_list` object of `media_process_task` supports the following: * `definition` - (Required, String) Animated image generating template ID. * `end_time_offset` - (Required, Float64) End time of animated image in video in seconds. * `start_time_offset` - (Required, Float64) Start time of animated image in video in seconds. +The `copy_right_watermark` object of `transcode_task_list` supports the following: + +* `text` - (Optional, String) Copyright information, maximum length is 200 characters. + The `cover_by_snapshot_task_list` object of `media_process_task` supports the following: * `definition` - (Required, String) Time point screen capturing template ID. @@ -132,6 +183,10 @@ The `cover_by_snapshot_task_list` object of `media_process_task` supports the fo * `position_value` - (Required, Float64) Screenshot position: For time point screen capturing, this means to take a screenshot at a specified time point (in seconds) and use it as the cover. For percentage screen capturing, this value means to take a screenshot at a specified percentage of the video duration and use it as the cover. * `watermark_list` - (Optional, List) List of up to `10` image or text watermarks. Note: this field may return null, indicating that no valid values can be obtained. +The `head_tail_list` object of `transcode_task_list` supports the following: + +* `definition` - (Optional, String) Video opening/closing credits configuration template ID. + The `image_sprite_task_list` object of `media_process_task` supports the following: * `definition` - (Required, String) Image sprite generating template ID. @@ -156,6 +211,13 @@ The `mosaic_list` object of `transcode_task_list` supports the following: * `x_pos` - (Optional, String) The horizontal position of the origin of the blur relative to the origin of coordinates of the video. `%` and `px` formats are supported: If the string ends in `%`, the XPos of the blur will be the specified percentage of the video width; for example, 10% means that XPos is 10% of the video width; If the string ends in `px`, the XPos of the blur will be the specified px; for example, 100px means that XPos is 100 px. Default value: `0px`. * `y_pos` - (Optional, String) Vertical position of the origin of blur relative to the origin of coordinates of video. `%` and `px` formats are supported: If the string ends in `%`, the YPos of the blur will be the specified percentage of the video height; for example, 10% means that YPos is 10% of the video height; If the string ends in `px`, the YPos of the blur will be the specified px; for example, 100px means that YPos is 100 px. Default value: `0px`. +The `review_audio_video_task` object supports the following: + +* `definition` - (Optional, String) Review template. +* `review_contents` - (Optional, List) The type of moderated content. Valid values: +- `Media`: The original audio/video; +- `Cover`: Thumbnails. + The `sample_snapshot_task_list` object of `media_process_task` supports the following: * `definition` - (Required, String) Sampled screen capturing template ID. @@ -165,12 +227,22 @@ The `snapshot_by_time_offset_task_list` object of `media_process_task` supports * `definition` - (Required, String) Time point screen capturing template ID. * `ext_time_offset_list` - (Optional, List) The list of screenshot time points. `s` and `%` formats are supported: When a time point string ends with `s`, its unit is second. For example, `3.5s` means the 3.5th second of the video; When a time point string ends with `%`, it is marked with corresponding percentage of the video duration. For example, `10%` means that the time point is at the 10% of the video entire duration. +* `time_offset_list` - (Optional, List) List of time points for screencapturing in milliseconds. Note: this field may return null, indicating that no valid values can be obtained. * `watermark_list` - (Optional, List) List of up to `10` image or text watermarks. Note: this field may return null, indicating that no valid values can be obtained. +The `trace_watermark` object of `transcode_task_list` supports the following: + +* `switch` - (Optional, String) Whether to use digital watermarks. This parameter is required. Valid values: ON, OFF. + The `transcode_task_list` object of `media_process_task` supports the following: * `definition` - (Required, String) Video transcoding template ID. +* `copy_right_watermark` - (Optional, List) opyright watermark. +* `end_time_offset` - (Optional, Float64) End time offset of blur in seconds. If this parameter is left empty or `0` is entered, the blur will exist till the last video frame; If this value is greater than `0` (e.g., n), the blur will exist till second n; If this value is smaller than `0` (e.g., -n), the blur will exist till second n before the last video frame. +* `head_tail_list` - (Optional, List) List of video opening/closing credits configuration template IDs. You can enter up to 10 IDs. * `mosaic_list` - (Optional, List) List of blurs. Up to 10 ones can be supported. +* `start_time_offset` - (Optional, Float64) Start time offset of blur in seconds. If this parameter is left empty or `0` is entered, the blur will appear upon the first video frame. If this parameter is left empty or `0` is entered, the blur will appear upon the first video frame; If this value is greater than `0` (e.g., n), the blur will appear at second n after the first video frame; If this value is smaller than `0` (e.g., -n), the blur will appear at second n before the last video frame. +* `trace_watermark` - (Optional, List) Digital watermark. * `watermark_list` - (Optional, List) List of up to `10` image or text watermarks. Note: this field may return null, indicating that no valid values can be obtained. The `watermark_list` object of `adaptive_dynamic_streaming_task_list` supports the following: @@ -219,6 +291,9 @@ In addition to all arguments above, the following attributes are exported: * `id` - ID of the resource. * `create_time` - Creation time of template in ISO date format. +* `type` - Template type, value range: +- Preset: system preset template; +- Custom: user-defined templates. * `update_time` - Last modified time of template in ISO date format. diff --git a/website/docs/r/vod_sample_snapshot_template.html.markdown b/website/docs/r/vod_sample_snapshot_template.html.markdown index e4a9b6833c..ed66435aba 100644 --- a/website/docs/r/vod_sample_snapshot_template.html.markdown +++ b/website/docs/r/vod_sample_snapshot_template.html.markdown @@ -59,7 +59,7 @@ In addition to all arguments above, the following attributes are exported: ## Import -vod snapshot template can be imported using the id, e.g. +vod snapshot template can be imported using the id($subAppId#$templateId), e.g. ``` terraform import tencentcloud_vod_sample_snapshot_template.sample_snapshot_template $subAppId#$templateId diff --git a/website/docs/r/vod_snapshot_by_time_offset_template.html.markdown b/website/docs/r/vod_snapshot_by_time_offset_template.html.markdown index 2613d659c0..c18837bc2f 100644 --- a/website/docs/r/vod_snapshot_by_time_offset_template.html.markdown +++ b/website/docs/r/vod_snapshot_by_time_offset_template.html.markdown @@ -35,7 +35,7 @@ The following arguments are supported: * `format` - (Optional, String) Image format. Valid values: `jpg`, `png`. Default value: `jpg`. * `height` - (Optional, Int) Maximum value of the `height` (or short side) of a screenshot in px. Value range: 0 and [128, 4,096]. If both `width` and `height` are `0`, the resolution will be the same as that of the source video; If `width` is `0`, but `height` is not `0`, `width` will be proportionally scaled; If `width` is not `0`, but `height` is `0`, `height` will be proportionally scaled; If both `width` and `height` are not `0`, the custom resolution will be used. Default value: `0`. * `resolution_adaptive` - (Optional, Bool) Resolution adaption. Valid values: `true`,`false`. `true`: enabled. In this case, `width` represents the long side of a video, while `height` the short side; `false`: disabled. In this case, `width` represents the width of a video, while `height` the height. Default value: `true`. -* `sub_app_id` - (Optional, Int) Subapplication ID in VOD. If you need to access a resource in a subapplication, enter the subapplication ID in this field; otherwise, leave it empty. +* `sub_app_id` - (Optional, Int) The VOD [application](https://intl.cloud.tencent.com/document/product/266/14574) ID. For customers who activate VOD service from December 25, 2023, if they want to access resources in a VOD application (whether it's the default application or a newly created one), they must fill in this field with the application ID. * `width` - (Optional, Int) Maximum value of the `width` (or long side) of a screenshot in px. Value range: 0 and [128, 4,096]. If both `width` and `height` are `0`, the resolution will be the same as that of the source video; If `width` is `0`, but `height` is not `0`, width will be proportionally scaled; If `width` is not `0`, but `height` is `0`, `height` will be proportionally scaled; If both `width` and `height` are not `0`, the custom resolution will be used. Default value: `0`. ## Attributes Reference @@ -44,14 +44,17 @@ In addition to all arguments above, the following attributes are exported: * `id` - ID of the resource. * `create_time` - Creation time of template in ISO date format. +* `type` - Template type, value range: +- Preset: system preset template; +- Custom: user-defined templates. * `update_time` - Last modified time of template in ISO date format. ## Import -VOD snapshot by time offset template can be imported using the id, e.g. +VOD snapshot by time offset template can be imported using the id($subAppId#$templateId), e.g. ``` -$ terraform import tencentcloud_vod_snapshot_by_time_offset_template.foo 46906 +$ terraform import tencentcloud_vod_snapshot_by_time_offset_template.foo $subAppId#$templateId ``` diff --git a/website/docs/r/vpc_ipv6_eni_address.html.markdown b/website/docs/r/vpc_ipv6_eni_address.html.markdown index 7c0584f858..a2c9f869e9 100644 --- a/website/docs/r/vpc_ipv6_eni_address.html.markdown +++ b/website/docs/r/vpc_ipv6_eni_address.html.markdown @@ -11,6 +11,8 @@ description: |- Provides a resource to create a vpc ipv6_eni_address +~> **NOTE:** It has been deprecated and replaced by `tencentcloud_eni_ipv6_address`. + ## Example Usage ```hcl @@ -45,7 +47,7 @@ resource "tencentcloud_vpc_ipv6_eni_address" "ipv6_eni_address" { vpc_id = tencentcloud_vpc.vpc.id network_interface_id = tencentcloud_eni.eni.id ipv6_addresses { - address = tencentcloud_vpc_ipv6_cidr_block.example.ipv6_cidr_block + address = "xxxxxxxxxxxxxx" description = "desc." } } diff --git a/website/docs/r/vpc_ipv6_subnet_cidr_block.html.markdown b/website/docs/r/vpc_ipv6_subnet_cidr_block.html.markdown index 5421fdeacf..9fc2dea1a6 100644 --- a/website/docs/r/vpc_ipv6_subnet_cidr_block.html.markdown +++ b/website/docs/r/vpc_ipv6_subnet_cidr_block.html.markdown @@ -37,7 +37,7 @@ resource "tencentcloud_vpc_ipv6_subnet_cidr_block" "example" { vpc_id = tencentcloud_vpc.vpc.id ipv6_subnet_cidr_blocks { subnet_id = tencentcloud_subnet.subnet.id - ipv6_cidr_block = tencentcloud_vpc_ipv6_cidr_block.example.ipv6_cidr_block + ipv6_cidr_block = "xxxxxxxxx" } } ``` diff --git a/website/tencentcloud.erb b/website/tencentcloud.erb index 989f098632..9544693b76 100644 --- a/website/tencentcloud.erb +++ b/website/tencentcloud.erb @@ -4397,6 +4397,9 @@