Skip to content

Commit 7165cc5

Browse files
committed
feat(postgresql): [xxx]support new resource.
1 parent f5881ef commit 7165cc5

4 files changed

+714
-1
lines changed
Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
package postgresql
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"log"
7+
"strings"
8+
"time"
9+
10+
tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common"
11+
svctag "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/services/tag"
12+
13+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
14+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
15+
postgresql "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/postgres/v20170312"
16+
"github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper"
17+
)
18+
19+
func resourceTencentCloudPostgresqlReadonlyGroupNetworkAccessAttachment() *schema.Resource {
20+
return &schema.Resource{
21+
Create: resourceTencentCloudPostgresqlReadonlyGroupNetworkAccessAttachmentCreate,
22+
Read: resourceTencentCloudPostgresqlReadonlyGroupNetworkAccessAttachmentRead,
23+
Delete: resourceTencentCloudPostgresqlReadonlyGroupNetworkAccessAttachmentDelete,
24+
Importer: &schema.ResourceImporter{
25+
State: schema.ImportStatePassthrough,
26+
},
27+
Schema: map[string]*schema.Schema{
28+
"db_instance_id": {
29+
Required: true,
30+
ForceNew: true,
31+
Type: schema.TypeString,
32+
Description: "Master database instance ID.",
33+
},
34+
35+
"read_only_group_id": {
36+
Required: true,
37+
ForceNew: true,
38+
Type: schema.TypeString,
39+
Description: "RO group identifier.",
40+
},
41+
42+
"vpc_id": {
43+
Required: true,
44+
ForceNew: true,
45+
Type: schema.TypeString,
46+
Description: "Unified VPC ID.",
47+
},
48+
49+
"subnet_id": {
50+
Required: true,
51+
ForceNew: true,
52+
Type: schema.TypeString,
53+
Description: "Subnet ID.",
54+
},
55+
56+
"is_assign_vip": {
57+
Required: true,
58+
ForceNew: true,
59+
Type: schema.TypeBool,
60+
Description: "Whether to manually assign the VIP. Valid values:true (manually assign), false (automatically assign).",
61+
},
62+
63+
"vip": {
64+
Optional: true,
65+
Computed: true,
66+
ForceNew: true,
67+
Type: schema.TypeString,
68+
Description: "Target VIP.",
69+
},
70+
71+
"tags": {
72+
Type: schema.TypeMap,
73+
Optional: true,
74+
Description: "Tag description list.",
75+
},
76+
},
77+
}
78+
}
79+
80+
func resourceTencentCloudPostgresqlReadonlyGroupNetworkAccessAttachmentCreate(d *schema.ResourceData, meta interface{}) error {
81+
defer tccommon.LogElapsed("resource.tencentcloud_postgresql_readonly_group_network_access_attachment.create")()
82+
83+
logId := tccommon.GetLogId(tccommon.ContextNil)
84+
85+
var (
86+
request = postgresql.NewCreateReadOnlyGroupNetworkAccessRequest()
87+
dbInstanceId string
88+
roGroupId string
89+
vpcId string
90+
vip string
91+
port string
92+
isUserAssign bool
93+
)
94+
if v, ok := d.GetOk("db_instance_id"); ok {
95+
dbInstanceId = v.(string)
96+
}
97+
98+
if v, ok := d.GetOk("readonly_group_id"); ok {
99+
request.ReadOnlyGroupId = helper.String(v.(string))
100+
roGroupId = v.(string)
101+
}
102+
103+
if v, ok := d.GetOk("vpc_id"); ok {
104+
request.VpcId = helper.String(v.(string))
105+
vpcId = v.(string)
106+
}
107+
108+
if v, ok := d.GetOk("subnet_id"); ok {
109+
request.SubnetId = helper.String(v.(string))
110+
}
111+
112+
if v, ok := d.GetOkExists("is_assign_vip"); ok {
113+
request.IsAssignVip = helper.Bool(v.(bool))
114+
isUserAssign = v.(bool)
115+
}
116+
117+
if v, ok := d.GetOk("vip"); ok {
118+
request.Vip = helper.String(v.(string))
119+
vip = v.(string)
120+
}
121+
122+
err := resource.Retry(tccommon.WriteRetryTimeout, func() *resource.RetryError {
123+
result, e := meta.(tccommon.ProviderMeta).GetAPIV3Conn().UsePostgresqlClient().CreateReadOnlyGroupNetworkAccess(request)
124+
if e != nil {
125+
return tccommon.RetryError(e)
126+
} else {
127+
log.Printf("[DEBUG]%s api[%s] success, request body [%s], response body [%s]\n", logId, request.GetAction(), request.ToJsonString(), result.ToJsonString())
128+
}
129+
return nil
130+
})
131+
if err != nil {
132+
log.Printf("[CRITAL]%s create postgresql ReadonlyGroupNetworkAccessAttachment failed, reason:%+v", logId, err)
133+
return err
134+
}
135+
136+
id := strings.Join([]string{dbInstanceId, roGroupId, vpcId, vip, port}, tccommon.FILED_SP)
137+
138+
service := PostgresqlService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()}
139+
conf := tccommon.BuildStateChangeConf([]string{}, []string{"opened"}, 180*tccommon.ReadRetryTimeout, time.Second, service.PostgresqlReadonlyGroupNetworkAccessAttachmentStateRefreshFunc(id, []string{}))
140+
141+
var ret interface{}
142+
var e error
143+
if ret, e = conf.WaitForState(); e != nil {
144+
return e
145+
} else {
146+
object := ret.(*postgresql.DBInstanceNetInfo)
147+
// fill out the port and vip
148+
if object != nil {
149+
if isUserAssign {
150+
// find the port
151+
if *object.VpcId == vpcId && *object.Ip == vip {
152+
port = helper.UInt64ToStr(*object.Port)
153+
}
154+
} else {
155+
// find the port and vip when is_assign_vip is false
156+
if *object.VpcId == vpcId {
157+
port = helper.UInt64ToStr(*object.Port)
158+
vip = *object.Ip
159+
}
160+
}
161+
}
162+
}
163+
164+
id = strings.Join([]string{dbInstanceId, roGroupId, vpcId, vip, port}, tccommon.FILED_SP)
165+
d.SetId(id)
166+
167+
ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId)
168+
if tags := helper.GetTags(d, "tags"); len(tags) > 0 {
169+
tagService := svctag.NewTagService(meta.(tccommon.ProviderMeta).GetAPIV3Conn())
170+
region := meta.(tccommon.ProviderMeta).GetAPIV3Conn().Region
171+
resourceName := fmt.Sprintf("qcs::postgres:%s:uin/:dbInstanceId/%s", region, d.Id())
172+
if err := tagService.ModifyTags(ctx, resourceName, tags, nil); err != nil {
173+
return err
174+
}
175+
}
176+
177+
return resourceTencentCloudPostgresqlReadonlyGroupNetworkAccessAttachmentRead(d, meta)
178+
}
179+
180+
func resourceTencentCloudPostgresqlReadonlyGroupNetworkAccessAttachmentRead(d *schema.ResourceData, meta interface{}) error {
181+
defer tccommon.LogElapsed("resource.tencentcloud_postgresql_readonly_group_network_access_attachment.read")()
182+
defer tccommon.InconsistentCheck(d, meta)()
183+
184+
logId := tccommon.GetLogId(tccommon.ContextNil)
185+
186+
ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId)
187+
188+
service := PostgresqlService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()}
189+
190+
idSplit := strings.Split(d.Id(), tccommon.FILED_SP)
191+
if len(idSplit) != 5 {
192+
return fmt.Errorf("id is broken,%s, location:%s", d.Id(), "resource.tencentcloud_postgresql_readonly_group_network_access_attachment.read")
193+
}
194+
195+
dbInstanceId := idSplit[0]
196+
roGroupId := idSplit[1]
197+
vpcId := idSplit[2]
198+
vip := idSplit[3]
199+
port := idSplit[4]
200+
201+
ReadonlyGroupNetworkAccessAttachment, err := service.DescribePostgresqlReadonlyGroupNetworkAccessAttachmentById(ctx, dbInstanceId, roGroupId)
202+
if err != nil {
203+
return err
204+
}
205+
206+
if ReadonlyGroupNetworkAccessAttachment == nil {
207+
d.SetId("")
208+
log.Printf("[WARN]%s resource `PostgresqlReadonlyGroupNetworkAccessAttachment` [%s] not found, please check if it has been deleted.\n", logId, d.Id())
209+
return nil
210+
}
211+
212+
if ReadonlyGroupNetworkAccessAttachment.MasterDBInstanceId != nil {
213+
_ = d.Set("db_instance_id", ReadonlyGroupNetworkAccessAttachment.MasterDBInstanceId)
214+
}
215+
216+
if ReadonlyGroupNetworkAccessAttachment.ReadOnlyGroupId != nil {
217+
_ = d.Set("readonly_group_id", ReadonlyGroupNetworkAccessAttachment.ReadOnlyGroupId)
218+
}
219+
220+
if ReadonlyGroupNetworkAccessAttachment.VpcId != nil {
221+
_ = d.Set("vpc_id", ReadonlyGroupNetworkAccessAttachment.VpcId)
222+
}
223+
224+
if ReadonlyGroupNetworkAccessAttachment.SubnetId != nil {
225+
_ = d.Set("subnet_id", ReadonlyGroupNetworkAccessAttachment.SubnetId)
226+
}
227+
228+
if vip == "" {
229+
// That's mean isUserAssign is false and need to set vip assigned by system
230+
if ReadonlyGroupNetworkAccessAttachment.DBInstanceNetInfo != nil {
231+
for _, info := range ReadonlyGroupNetworkAccessAttachment.DBInstanceNetInfo {
232+
if *info.VpcId == vpcId && helper.UInt64ToStr(*info.Port) == port {
233+
if info.Ip != nil {
234+
vip = *info.Ip
235+
log.Printf("[DEBUG]%s the id:[%s]'s filed vip[%s] updated successfully!\n", logId, d.Id(), vip)
236+
break
237+
}
238+
}
239+
}
240+
}
241+
// update the vip into unique id
242+
id := strings.Join([]string{dbInstanceId, roGroupId, vpcId, vip, port}, tccommon.FILED_SP)
243+
d.SetId(id)
244+
}
245+
_ = d.Set("vip", vip)
246+
247+
tcClient := meta.(tccommon.ProviderMeta).GetAPIV3Conn()
248+
tagService := svctag.NewTagService(tcClient)
249+
tags, err := tagService.DescribeResourceTags(ctx, "postgres", "dbInstanceId", tcClient.Region, d.Id())
250+
if err != nil {
251+
return err
252+
}
253+
_ = d.Set("tags", tags)
254+
255+
return nil
256+
}
257+
258+
func resourceTencentCloudPostgresqlReadonlyGroupNetworkAccessAttachmentDelete(d *schema.ResourceData, meta interface{}) error {
259+
defer tccommon.LogElapsed("resource.tencentcloud_postgresql_readonly_group_network_access_attachment.delete")()
260+
defer tccommon.InconsistentCheck(d, meta)()
261+
262+
logId := tccommon.GetLogId(tccommon.ContextNil)
263+
ctx := context.WithValue(context.TODO(), tccommon.LogIdKey, logId)
264+
265+
service := PostgresqlService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()}
266+
267+
idSplit := strings.Split(d.Id(), tccommon.FILED_SP)
268+
if len(idSplit) != 5 {
269+
return fmt.Errorf("id is broken,%s", d.Id())
270+
}
271+
272+
var subnetId string
273+
roGroupId := idSplit[1]
274+
vpcId := idSplit[2]
275+
vip := idSplit[3]
276+
if v, ok := d.GetOk("subnet_id"); ok {
277+
subnetId = v.(string)
278+
}
279+
280+
if err := service.DeletePostgresqlReadonlyGroupNetworkAccessAttachmentById(ctx, roGroupId, vpcId, subnetId, vip); err != nil {
281+
return err
282+
}
283+
284+
conf := tccommon.BuildStateChangeConf([]string{}, []string{"closed"}, 180*tccommon.ReadRetryTimeout, time.Second, service.PostgresqlReadonlyGroupNetworkAccessAttachmentStateRefreshFunc(d.Id(), []string{}))
285+
286+
if _, e := conf.WaitForState(); e != nil {
287+
return e
288+
}
289+
290+
return nil
291+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
Provides a resource to create a postgresql readonly_group_network_access_attachment
3+
4+
Example Usage
5+
6+
Vip assigned by system.
7+
8+
```hcl
9+
resource "tencentcloud_vpc" "vpc" {
10+
cidr_block = "172.18.111.0/24"
11+
name = "test-pg-network-vpc"
12+
}
13+
resource "tencentcloud_subnet" "subnet" {
14+
availability_zone = var.default_az
15+
cidr_block = "172.18.111.0/24"
16+
name = "test-pg-network-sub1"
17+
vpc_id = tencentcloud_vpc.vpc.id
18+
}
19+
locals {
20+
my_vpc_id = tencentcloud_subnet.subnet.vpc_id
21+
my_subnet_id = tencentcloud_subnet.subnet.id
22+
}
23+
resource "tencentcloud_postgresql_readonly_group" "group" {
24+
master_db_instance_id = local.pgsql_id
25+
name = "tf_test_postgresql_readonly_group"
26+
project_id = 0
27+
vpc_id = local.my_vpc_id
28+
subnet_id = local.my_subnet_id
29+
replay_lag_eliminate = 1
30+
replay_latency_eliminate = 1
31+
max_replay_lag = 100
32+
max_replay_latency = 512
33+
min_delay_eliminate_reserve = 1
34+
}
35+
resource "tencentcloud_postgresql_readonly_group_network_access_attachment" "readonly_group_network_access_attachment" {
36+
db_instance_id = local.pgsql_id
37+
readonly_group_id = tencentcloud_postgresql_readonly_group.group.id
38+
vpc_id = local.my_vpc_id
39+
subnet_id = local.my_subnet_id
40+
is_assign_vip = false
41+
tags = {
42+
"createdBy" = "terraform"
43+
}
44+
}
45+
```
46+
47+
Vip specified by user.
48+
49+
```hcl
50+
resource "tencentcloud_postgresql_readonly_group_network_access_attachment" "readonly_group_network_access_attachment" {
51+
db_instance_id = local.pgsql_id
52+
readonly_group_id = tencentcloud_postgresql_readonly_group.group.id
53+
vpc_id = local.my_vpc_id
54+
subnet_id = local.my_subnet_id
55+
is_assign_vip = true
56+
vip = "172.18.111.111"
57+
tags = {
58+
"createdBy" = "terraform"
59+
}
60+
}
61+
62+
Import
63+
64+
postgresql readonly_group_network_access_attachment can be imported using the id, e.g.
65+
66+
```
67+
terraform import tencentcloud_postgresql_readonly_group_network_access_attachment.readonly_group_network_access_attachment db_instance_id#readonly_group_id#vpc_id#vip#port
68+
```
69+
*/

0 commit comments

Comments
 (0)