Skip to content

Commit ee836a0

Browse files
authored
Feat/support tencentcloud_tcr_manage_replication_operation (#1700)
* support resource: tencentcloud_tcr_webhook_trigger * add changelog * adjust TCR e2e case name * adjust e2e case * support resource: tencentcloud_tcr_webhook_trigger_logs * support resource: tencentcloud_tcr_manage_replication_operation * add changelog
1 parent 8a15fca commit ee836a0

File tree

6 files changed

+481
-0
lines changed

6 files changed

+481
-0
lines changed

.changelog/1700.txt

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

tencentcloud/provider.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,7 @@ Tencent Container Registry(TCR)
634634
tencentcloud_tcr_vpc_attachment
635635
tencentcloud_tcr_tag_retention_rule
636636
tencentcloud_tcr_webhook_trigger
637+
tencentcloud_tcr_manage_replication_operation
637638
638639
Video on Demand(VOD)
639640
Data Source
@@ -1723,6 +1724,7 @@ func Provider() terraform.ResourceProvider {
17231724
"tencentcloud_tcr_vpc_attachment": resourceTencentCloudTcrVpcAttachment(),
17241725
"tencentcloud_tcr_tag_retention_rule": resourceTencentCloudTcrTagRetentionRule(),
17251726
"tencentcloud_tcr_webhook_trigger": resourceTencentCloudTcrWebhookTrigger(),
1727+
"tencentcloud_tcr_manage_replication_operation": resourceTencentCloudTcrManageReplicationOperation(),
17261728
"tencentcloud_tdmq_instance": resourceTencentCloudTdmqInstance(),
17271729
"tencentcloud_tdmq_namespace": resourceTencentCloudTdmqNamespace(),
17281730
"tencentcloud_tdmq_topic": resourceTencentCloudTdmqTopic(),
Lines changed: 284 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,284 @@
1+
/*
2+
Provides a resource to create a tcr manage_replication_operation
3+
4+
Example Usage
5+
6+
```hcl
7+
resource "tencentcloud_tcr_instance" "mytcr_dest" {
8+
name = "tf-test-tcr-%s"
9+
instance_type = "premium"
10+
delete_bucket = true
11+
}
12+
13+
resource "tencentcloud_tcr_namespace" "myns_dest" {
14+
instance_id = tencentcloud_tcr_instance.mytcr_dest.id
15+
name = "tf_test_ns_dest"
16+
is_public = true
17+
is_auto_scan = true
18+
is_prevent_vul = true
19+
severity = "medium"
20+
cve_whitelist_items {
21+
cve_id = "cve-xxxxx"
22+
}
23+
}
24+
25+
resource "tencentcloud_tcr_manage_replication_operation" "my_replica" {
26+
source_registry_id = local.tcr_id
27+
destination_registry_id = tencentcloud_tcr_instance.mytcr_dest.id
28+
rule {
29+
name = "test_sync_%d"
30+
dest_namespace = tencentcloud_tcr_namespace.myns_dest.name
31+
override = true
32+
filters {
33+
type = "name"
34+
value = join("/", [var.tcr_namespace, "**"])
35+
}
36+
filters {
37+
type = "tag"
38+
value = ""
39+
}
40+
filters {
41+
type = "resource"
42+
value = ""
43+
}
44+
}
45+
description = "this is the tcr sync operation"
46+
destination_region_id = 1 // "ap-guangzhou"
47+
peer_replication_option {
48+
peer_registry_uin = ""
49+
peer_registry_token = ""
50+
enable_peer_replication = false
51+
}
52+
}
53+
```
54+
55+
*/
56+
package tencentcloud
57+
58+
import (
59+
"log"
60+
"strings"
61+
62+
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
63+
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
64+
tcr "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tcr/v20190924"
65+
"github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper"
66+
)
67+
68+
func resourceTencentCloudTcrManageReplicationOperation() *schema.Resource {
69+
return &schema.Resource{
70+
Create: resourceTencentCloudTcrManageReplicationOperationCreate,
71+
Read: resourceTencentCloudTcrManageReplicationOperationRead,
72+
Delete: resourceTencentCloudTcrManageReplicationOperationDelete,
73+
Importer: &schema.ResourceImporter{
74+
State: schema.ImportStatePassthrough,
75+
},
76+
Schema: map[string]*schema.Schema{
77+
"source_registry_id": {
78+
Required: true,
79+
ForceNew: true,
80+
Type: schema.TypeString,
81+
Description: "copy source instance Id.",
82+
},
83+
84+
"destination_registry_id": {
85+
Required: true,
86+
ForceNew: true,
87+
Type: schema.TypeString,
88+
Description: "copy destination instance Id.",
89+
},
90+
91+
"rule": {
92+
Required: true,
93+
ForceNew: true,
94+
Type: schema.TypeList,
95+
MaxItems: 1,
96+
Description: "synchronization rules.",
97+
Elem: &schema.Resource{
98+
Schema: map[string]*schema.Schema{
99+
"name": {
100+
Type: schema.TypeString,
101+
Required: true,
102+
Description: "synchronization rule names.",
103+
},
104+
"dest_namespace": {
105+
Type: schema.TypeString,
106+
Required: true,
107+
Description: "target namespace.",
108+
},
109+
"override": {
110+
Type: schema.TypeBool,
111+
Required: true,
112+
Description: "whether to cover.",
113+
},
114+
"filters": {
115+
Type: schema.TypeList,
116+
Required: true,
117+
Description: "sync filters.",
118+
Elem: &schema.Resource{
119+
Schema: map[string]*schema.Schema{
120+
"type": {
121+
Type: schema.TypeString,
122+
Required: true,
123+
Description: "type (name, tag, and resource).",
124+
},
125+
"value": {
126+
Type: schema.TypeString,
127+
Optional: true,
128+
Description: "empty by default.",
129+
},
130+
},
131+
},
132+
},
133+
},
134+
},
135+
},
136+
137+
"description": {
138+
Optional: true,
139+
ForceNew: true,
140+
Type: schema.TypeString,
141+
Description: "rule description.",
142+
},
143+
144+
"destination_region_id": {
145+
Optional: true,
146+
ForceNew: true,
147+
Type: schema.TypeInt,
148+
Description: "the region ID of the target instance, such as Guangzhou is 1.",
149+
},
150+
151+
"peer_replication_option": {
152+
Optional: true,
153+
ForceNew: true,
154+
Type: schema.TypeList,
155+
MaxItems: 1,
156+
Description: "enable synchronization of configuration items across master account instances.",
157+
Elem: &schema.Resource{
158+
Schema: map[string]*schema.Schema{
159+
"peer_registry_uin": {
160+
Type: schema.TypeString,
161+
Required: true,
162+
Description: "uin of the instance to be synchronized.",
163+
},
164+
"peer_registry_token": {
165+
Type: schema.TypeString,
166+
Required: true,
167+
Description: "access permanent token of the instance to be synchronized.",
168+
},
169+
"enable_peer_replication": {
170+
Type: schema.TypeBool,
171+
Required: true,
172+
Description: "whether to enable cross-master account instance synchronization.",
173+
},
174+
},
175+
},
176+
},
177+
},
178+
}
179+
}
180+
181+
func resourceTencentCloudTcrManageReplicationOperationCreate(d *schema.ResourceData, meta interface{}) error {
182+
defer logElapsed("resource.tencentcloud_tcr_manage_replication_operation.create")()
183+
defer inconsistentCheck(d, meta)()
184+
185+
logId := getLogId(contextNil)
186+
187+
var (
188+
request = tcr.NewManageReplicationRequest()
189+
sourceRegistryId string
190+
destinationRegistryId string
191+
ruleName string
192+
)
193+
if v, ok := d.GetOk("source_registry_id"); ok {
194+
sourceRegistryId = v.(string)
195+
request.SourceRegistryId = helper.String(v.(string))
196+
}
197+
198+
if v, ok := d.GetOk("destination_registry_id"); ok {
199+
destinationRegistryId = v.(string)
200+
request.DestinationRegistryId = helper.String(v.(string))
201+
}
202+
203+
if dMap, ok := helper.InterfacesHeadMap(d, "rule"); ok {
204+
replicationRule := tcr.ReplicationRule{}
205+
if v, ok := dMap["name"]; ok {
206+
ruleName = v.(string)
207+
replicationRule.Name = helper.String(v.(string))
208+
}
209+
if v, ok := dMap["dest_namespace"]; ok {
210+
replicationRule.DestNamespace = helper.String(v.(string))
211+
}
212+
if v, ok := dMap["override"]; ok {
213+
replicationRule.Override = helper.Bool(v.(bool))
214+
}
215+
if v, ok := dMap["filters"]; ok {
216+
for _, item := range v.([]interface{}) {
217+
filtersMap := item.(map[string]interface{})
218+
replicationFilter := tcr.ReplicationFilter{}
219+
if v, ok := filtersMap["type"]; ok {
220+
replicationFilter.Type = helper.String(v.(string))
221+
}
222+
if v, ok := filtersMap["value"]; ok {
223+
replicationFilter.Value = helper.String(v.(string))
224+
}
225+
replicationRule.Filters = append(replicationRule.Filters, &replicationFilter)
226+
}
227+
}
228+
request.Rule = &replicationRule
229+
}
230+
231+
if v, ok := d.GetOk("description"); ok {
232+
request.Description = helper.String(v.(string))
233+
}
234+
235+
if v, _ := d.GetOk("destination_region_id"); v != nil {
236+
request.DestinationRegionId = helper.IntUint64(v.(int))
237+
}
238+
239+
if dMap, ok := helper.InterfacesHeadMap(d, "peer_replication_option"); ok {
240+
peerReplicationOption := tcr.PeerReplicationOption{}
241+
if v, ok := dMap["peer_registry_uin"]; ok {
242+
peerReplicationOption.PeerRegistryUin = helper.String(v.(string))
243+
}
244+
if v, ok := dMap["peer_registry_token"]; ok {
245+
peerReplicationOption.PeerRegistryToken = helper.String(v.(string))
246+
}
247+
if v, ok := dMap["enable_peer_replication"]; ok {
248+
peerReplicationOption.EnablePeerReplication = helper.Bool(v.(bool))
249+
}
250+
request.PeerReplicationOption = &peerReplicationOption
251+
}
252+
253+
err := resource.Retry(writeRetryTimeout, func() *resource.RetryError {
254+
result, e := meta.(*TencentCloudClient).apiV3Conn.UseTCRClient().ManageReplication(request)
255+
if e != nil {
256+
return retryError(e)
257+
} else {
258+
log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), result.ToJsonString())
259+
}
260+
return nil
261+
})
262+
if err != nil {
263+
log.Printf("[CRITAL]%s operate tcr ManageReplicationOperation failed, reason:%+v", logId, err)
264+
return err
265+
}
266+
267+
d.SetId(strings.Join([]string{sourceRegistryId, destinationRegistryId, ruleName}, FILED_SP))
268+
269+
return resourceTencentCloudTcrManageReplicationOperationRead(d, meta)
270+
}
271+
272+
func resourceTencentCloudTcrManageReplicationOperationRead(d *schema.ResourceData, meta interface{}) error {
273+
defer logElapsed("resource.tencentcloud_tcr_manage_replication_operation.read")()
274+
defer inconsistentCheck(d, meta)()
275+
276+
return nil
277+
}
278+
279+
func resourceTencentCloudTcrManageReplicationOperationDelete(d *schema.ResourceData, meta interface{}) error {
280+
defer logElapsed("resource.tencentcloud_tcr_manage_replication_operation.delete")()
281+
defer inconsistentCheck(d, meta)()
282+
283+
return nil
284+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package tencentcloud
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
"time"
7+
8+
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
9+
)
10+
11+
func TestAccTencentCloudTcrManageReplicationOperationResource_basic(t *testing.T) {
12+
t.Parallel()
13+
resource.Test(t, resource.TestCase{
14+
PreCheck: func() {
15+
testAccPreCheck(t)
16+
},
17+
Providers: testAccProviders,
18+
Steps: []resource.TestStep{
19+
{
20+
Config: fmt.Sprintf(testAccTcrManageReplicationOperation, "sync", time.Now().Nanosecond()),
21+
Check: resource.ComposeTestCheckFunc(
22+
resource.TestCheckResourceAttrSet("tencentcloud_tcr_manage_replication_operation.my_replica", "id"),
23+
resource.TestCheckResourceAttrSet("tencentcloud_tcr_manage_replication_operation.my_replica", "source_registry_id"),
24+
resource.TestCheckResourceAttrSet("tencentcloud_tcr_manage_replication_operation.my_replica", "destination_registry_id"),
25+
resource.TestCheckResourceAttrSet("tencentcloud_tcr_manage_replication_operation.my_replica", "rule.#"),
26+
resource.TestCheckResourceAttrSet("tencentcloud_tcr_manage_replication_operation.my_replica", "rule.0.name"),
27+
resource.TestCheckResourceAttr("tencentcloud_tcr_manage_replication_operation.my_replica", "rule.0.override", "true"),
28+
resource.TestCheckResourceAttr("tencentcloud_tcr_manage_replication_operation.my_replica", "rule.0.filters.#", "3"),
29+
resource.TestCheckResourceAttr("tencentcloud_tcr_manage_replication_operation.my_replica", "description", "this is the tcr sync operation"),
30+
resource.TestCheckResourceAttr("tencentcloud_tcr_manage_replication_operation.my_replica", "destination_region_id", "1"),
31+
resource.TestCheckResourceAttrSet("tencentcloud_tcr_manage_replication_operation.my_replica", "peer_replication_option.#"),
32+
resource.TestCheckResourceAttr("tencentcloud_tcr_manage_replication_operation.my_replica", "peer_replication_option.0.enable_peer_replication", "false"),
33+
),
34+
},
35+
},
36+
})
37+
}
38+
39+
const testAccTcrManageReplicationOperation = defaultTCRInstanceData + `
40+
41+
resource "tencentcloud_tcr_instance" "mytcr_dest" {
42+
name = "tf-test-tcr-%s"
43+
instance_type = "premium"
44+
delete_bucket = true
45+
}
46+
47+
resource "tencentcloud_tcr_namespace" "myns_dest" {
48+
instance_id = tencentcloud_tcr_instance.mytcr_dest.id
49+
name = "tf_test_ns_dest"
50+
is_public = true
51+
is_auto_scan = true
52+
is_prevent_vul = true
53+
severity = "medium"
54+
cve_whitelist_items {
55+
cve_id = "cve-xxxxx"
56+
}
57+
}
58+
59+
resource "tencentcloud_tcr_manage_replication_operation" "my_replica" {
60+
source_registry_id = local.tcr_id
61+
destination_registry_id = tencentcloud_tcr_instance.mytcr_dest.id
62+
rule {
63+
name = "test_sync_%d"
64+
dest_namespace = tencentcloud_tcr_namespace.myns_dest.name
65+
override = true
66+
filters {
67+
type = "name"
68+
value = join("/", [var.tcr_namespace, "**"])
69+
}
70+
filters {
71+
type = "tag"
72+
value = ""
73+
}
74+
filters {
75+
type = "resource"
76+
value = ""
77+
}
78+
}
79+
description = "this is the tcr sync operation"
80+
destination_region_id = 1 // "ap-guangzhou"
81+
peer_replication_option {
82+
peer_registry_uin = ""
83+
peer_registry_token = ""
84+
enable_peer_replication = false
85+
}
86+
}
87+
88+
`

0 commit comments

Comments
 (0)