@@ -27,18 +27,19 @@ package tencentcloud
27
27
import (
28
28
"context"
29
29
"fmt"
30
-
31
30
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
32
31
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
32
+ tcr "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tcr/v20190924"
33
33
"github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper"
34
+ "log"
34
35
)
35
36
36
37
func resourceTencentCloudTcrInstance () * schema.Resource {
37
38
return & schema.Resource {
38
39
Create : resourceTencentCloudTcrInstanceCreate ,
39
40
Read : resourceTencentCloudTcrInstanceRead ,
40
41
Update : resourceTencentCloudTcrInstanceUpdate ,
41
- Delete : resourceTencentCLoudTcrInstanceDelete ,
42
+ Delete : resourceTencentCloudTcrInstanceDelete ,
42
43
Importer : & schema.ResourceImporter {
43
44
State : schema .ImportStatePassthrough ,
44
45
},
@@ -67,6 +68,35 @@ func resourceTencentCloudTcrInstance() *schema.Resource {
67
68
Default : false ,
68
69
Description : "Control public network access." ,
69
70
},
71
+ "security_policy" : {
72
+ Type : schema .TypeSet ,
73
+ Optional : true ,
74
+ Description : "Public network access allowlist policies of the TCR instance." ,
75
+ Elem : & schema.Resource {
76
+ Schema : map [string ]* schema.Schema {
77
+ "cidr_block" : {
78
+ Type : schema .TypeString ,
79
+ Optional : true ,
80
+ Description : "The public network IP address of the access source." ,
81
+ },
82
+ "description" : {
83
+ Type : schema .TypeString ,
84
+ Optional : true ,
85
+ Description : "Remarks of policy." ,
86
+ },
87
+ "index" : {
88
+ Type : schema .TypeInt ,
89
+ Computed : true ,
90
+ Description : "Index of policy." ,
91
+ },
92
+ "version" : {
93
+ Type : schema .TypeString ,
94
+ Computed : true ,
95
+ Description : "Version of policy." ,
96
+ },
97
+ },
98
+ },
99
+ },
70
100
//Computed values
71
101
"status" : {
72
102
Type : schema .TypeString ,
@@ -104,17 +134,23 @@ func resourceTencentCloudTcrInstanceCreate(d *schema.ResourceData, meta interfac
104
134
logId := getLogId (contextNil )
105
135
ctx := context .WithValue (context .TODO (), logIdKey , logId )
106
136
107
- tcrService := TCRService {client : meta .(* TencentCloudClient ).apiV3Conn }
137
+ client := meta .(* TencentCloudClient ).apiV3Conn
138
+ tcrService := TCRService {client : client }
108
139
109
140
var (
110
141
name = d .Get ("name" ).(string )
111
142
insType = d .Get ("instance_type" ).(string )
112
143
outErr , inErr error
113
144
instanceId string
114
145
instanceStatus string
115
- operation bool
146
+ operation = d . Get ( "open_public_operation" ).( bool )
116
147
)
117
148
149
+ // Check if security_policy but open_public_operation is false
150
+ if _ , ok := d .GetOk ("security_policy" ); ok && ! operation {
151
+ return fmt .Errorf ("`open_public_operation` must be `true` if `security_policy` set" )
152
+ }
153
+
118
154
outErr = resource .Retry (writeRetryTimeout , func () * resource.RetryError {
119
155
instanceId , inErr = tcrService .CreateTCRInstance (ctx , name , insType , map [string ]string {})
120
156
if inErr != nil {
@@ -147,9 +183,11 @@ func resourceTencentCloudTcrInstanceCreate(d *schema.ResourceData, meta interfac
147
183
return err
148
184
}
149
185
if instanceStatus == "Running" {
186
+ openPublicOperation , ok := d .GetOk ("open_public_operation" )
187
+ operation = openPublicOperation .(bool )
188
+
150
189
outErr = resource .Retry (writeRetryTimeout , func () * resource.RetryError {
151
- if v , ok := d .GetOk ("open_public_operation" ); ok {
152
- operation = v .(bool )
190
+ if ok {
153
191
if operation {
154
192
inErr = tcrService .ManageTCRExternalEndpoint (ctx , instanceId , "Create" )
155
193
} else {
@@ -164,6 +202,38 @@ func resourceTencentCloudTcrInstanceCreate(d *schema.ResourceData, meta interfac
164
202
if outErr != nil {
165
203
return outErr
166
204
}
205
+
206
+ if raw , ok := d .GetOk ("security_policy" ); ok && operation {
207
+ // Waiting for External EndPoint opened
208
+ err = resource .Retry (5 * readRetryTimeout , func () * resource.RetryError {
209
+ var (
210
+ status string
211
+ )
212
+ status , _ , err = tcrService .DescribeExternalEndpointStatus (ctx , instanceId )
213
+ if err != nil {
214
+ return resource .NonRetryableError (fmt .Errorf ("an error occured during DescribeExternalEndpointStatus: %s" , err .Error ()))
215
+ }
216
+
217
+ if status == "Opened" {
218
+ return nil
219
+ }
220
+
221
+ if status == "Opening" {
222
+ return resource .RetryableError (fmt .Errorf ("external endpoint status is `%s`, retrying" , status ))
223
+ }
224
+
225
+ return resource .NonRetryableError (fmt .Errorf ("unexpected external endpoint status: `%s`" , status ))
226
+ })
227
+
228
+ if err != nil {
229
+ return err
230
+ }
231
+ if err := resourceTencentCloudTcrSecurityPolicyAdd (d , meta , raw .(* schema.Set ).List ()); err != nil {
232
+ return err
233
+ }
234
+ } else if ! operation {
235
+ log .Printf ("[WARN] `open_public_operation` was not opened, skip `security_policy` set." )
236
+ }
167
237
}
168
238
169
239
if tags := helper .GetTags (d , "tags" ); len (tags ) > 0 {
@@ -185,7 +255,8 @@ func resourceTencentCloudTcrInstanceRead(d *schema.ResourceData, meta interface{
185
255
ctx := context .WithValue (context .TODO (), logIdKey , logId )
186
256
187
257
var outErr , inErr error
188
- tcrService := TCRService {client : meta .(* TencentCloudClient ).apiV3Conn }
258
+ client := meta .(* TencentCloudClient ).apiV3Conn
259
+ tcrService := TCRService {client : client }
189
260
instance , has , outErr := tcrService .DescribeTCRInstanceById (ctx , d .Id ())
190
261
if outErr != nil {
191
262
outErr = resource .Retry (readRetryTimeout , func () * resource.RetryError {
@@ -234,6 +305,31 @@ func resourceTencentCloudTcrInstanceRead(d *schema.ResourceData, meta interface{
234
305
_ = d .Set ("internal_end_point" , instance .InternalEndpoint )
235
306
_ = d .Set ("public_status" , publicStatus )
236
307
308
+ request := tcr .NewDescribeSecurityPoliciesRequest ()
309
+ request .RegistryId = helper .String (d .Id ())
310
+ response , err := client .UseTCRClient ().DescribeSecurityPolicies (request )
311
+ if err == nil {
312
+ if response .Response .SecurityPolicySet != nil {
313
+ securityPolicySet := response .Response .SecurityPolicySet
314
+ policies := make ([]interface {}, 0 , len (securityPolicySet ))
315
+ for i := range securityPolicySet {
316
+ item := securityPolicySet [i ]
317
+ policy := make (map [string ]interface {})
318
+ policy ["cidr_block" ] = * item .CidrBlock
319
+ policy ["description" ] = * item .Description
320
+ policy ["index" ] = * item .PolicyIndex
321
+ policy ["version" ] = * item .PolicyVersion
322
+ policies = append (policies , policy )
323
+ }
324
+ if err := d .Set ("security_policy" , policies ); err != nil {
325
+ return err
326
+ }
327
+ }
328
+ } else {
329
+ _ = d .Set ("security_policy" , make ([]interface {}, 0 ))
330
+ log .Printf ("[WARN] %s error: %s" , request .GetAction (), err .Error ())
331
+ }
332
+
237
333
tags := make (map [string ]string , len (instance .TagSpecification .Tags ))
238
334
for _ , tag := range instance .TagSpecification .Tags {
239
335
tags [* tag .Key ] = * tag .Value
@@ -259,16 +355,13 @@ func resourceTencentCloudTcrInstanceUpdate(d *schema.ResourceData, meta interfac
259
355
if d .HasChange ("open_public_operation" ) {
260
356
operation = d .Get ("open_public_operation" ).(bool )
261
357
outErr = resource .Retry (writeRetryTimeout , func () * resource.RetryError {
262
- if v , ok := d .GetOk ("open_public_operation" ); ok {
263
- operation = v .(bool )
264
- if operation {
265
- inErr = tcrService .ManageTCRExternalEndpoint (ctx , instanceId , "Create" )
266
- } else {
267
- inErr = tcrService .ManageTCRExternalEndpoint (ctx , instanceId , "Delete" )
268
- }
269
- if inErr != nil {
270
- return retryError (inErr )
271
- }
358
+ if operation {
359
+ inErr = tcrService .ManageTCRExternalEndpoint (ctx , instanceId , "Create" )
360
+ } else {
361
+ inErr = tcrService .ManageTCRExternalEndpoint (ctx , instanceId , "Delete" )
362
+ }
363
+ if inErr != nil {
364
+ return retryError (inErr )
272
365
}
273
366
return nil
274
367
})
@@ -277,6 +370,53 @@ func resourceTencentCloudTcrInstanceUpdate(d *schema.ResourceData, meta interfac
277
370
}
278
371
}
279
372
373
+ if d .HasChange ("security_policy" ) {
374
+ var err error
375
+ // Waiting for External EndPoint opened
376
+ err = resource .Retry (5 * readRetryTimeout , func () * resource.RetryError {
377
+ var (
378
+ status string
379
+ )
380
+ status , _ , err = tcrService .DescribeExternalEndpointStatus (ctx , instanceId )
381
+ if err != nil {
382
+ return resource .NonRetryableError (fmt .Errorf ("an error occured during DescribeExternalEndpointStatus: %s" , err .Error ()))
383
+ }
384
+
385
+ if status == "Opened" {
386
+ return nil
387
+ }
388
+
389
+ if status == "Opening" {
390
+ return resource .RetryableError (fmt .Errorf ("external endpoint status is `%s`, retrying" , status ))
391
+ }
392
+
393
+ return resource .NonRetryableError (fmt .Errorf ("unexpected external endpoint status: `%s`" , status ))
394
+ })
395
+
396
+ if err != nil {
397
+ return err
398
+ }
399
+
400
+ o , n := d .GetChange ("security_policy" )
401
+ os := o .(* schema.Set )
402
+ ns := n .(* schema.Set )
403
+ add := ns .Difference (os ).List ()
404
+ remove := os .Difference (ns ).List ()
405
+ if len (remove ) > 0 {
406
+ err := resourceTencentCloudTcrSecurityPolicyRemove (d , meta , remove )
407
+ if err != nil {
408
+ return err
409
+ }
410
+ }
411
+ if len (add ) > 0 {
412
+ err := resourceTencentCloudTcrSecurityPolicyAdd (d , meta , add )
413
+ if err != nil {
414
+ return err
415
+ }
416
+ }
417
+ d .SetPartial ("security_policy" )
418
+ }
419
+
280
420
if d .HasChange ("tags" ) {
281
421
oldTags , newTags := d .GetChange ("tags" )
282
422
replaceTags , deleteTags := diffTags (oldTags .(map [string ]interface {}), newTags .(map [string ]interface {}))
@@ -292,7 +432,7 @@ func resourceTencentCloudTcrInstanceUpdate(d *schema.ResourceData, meta interfac
292
432
return resourceTencentCloudTcrInstanceRead (d , meta )
293
433
}
294
434
295
- func resourceTencentCLoudTcrInstanceDelete (d * schema.ResourceData , meta interface {}) error {
435
+ func resourceTencentCloudTcrInstanceDelete (d * schema.ResourceData , meta interface {}) error {
296
436
defer logElapsed ("resource.tencentcloud_tcr_instance.delete" )()
297
437
298
438
logId := getLogId (contextNil )
@@ -338,3 +478,63 @@ func resourceTencentCLoudTcrInstanceDelete(d *schema.ResourceData, meta interfac
338
478
339
479
return nil
340
480
}
481
+
482
+ func resourceTencentCloudTcrSecurityPolicyAdd (d * schema.ResourceData , meta interface {}, add []interface {}) error {
483
+ client := meta .(* TencentCloudClient ).apiV3Conn
484
+ request := tcr .NewCreateMultipleSecurityPolicyRequest ()
485
+ request .RegistryId = helper .String (d .Id ())
486
+
487
+ for _ , i := range add {
488
+ dMap := i .(map [string ]interface {})
489
+ policy := & tcr.SecurityPolicy {}
490
+ if cidr , ok := dMap ["cidr_block" ]; ok {
491
+ policy .CidrBlock = helper .String (cidr .(string ))
492
+ }
493
+ if desc , ok := dMap ["description" ]; ok {
494
+ policy .Description = helper .String (desc .(string ))
495
+ }
496
+ if index , ok := dMap ["index" ]; ok {
497
+ policy .PolicyIndex = helper .IntInt64 (index .(int ))
498
+ }
499
+ if version , ok := dMap ["version" ]; ok {
500
+ policy .PolicyVersion = helper .String (version .(string ))
501
+ }
502
+ request .SecurityGroupPolicySet = append (request .SecurityGroupPolicySet , policy )
503
+ }
504
+
505
+ _ , err := client .UseTCRClient ().CreateMultipleSecurityPolicy (request )
506
+ if err != nil {
507
+ return err
508
+ }
509
+ return nil
510
+ }
511
+
512
+ func resourceTencentCloudTcrSecurityPolicyRemove (d * schema.ResourceData , meta interface {}, remove []interface {}) error {
513
+ client := meta .(* TencentCloudClient ).apiV3Conn
514
+ request := tcr .NewDeleteMultipleSecurityPolicyRequest ()
515
+ request .RegistryId = helper .String (d .Id ())
516
+
517
+ for _ , i := range remove {
518
+ dMap := i .(map [string ]interface {})
519
+ policy := & tcr.SecurityPolicy {}
520
+ if cidr , ok := dMap ["cidr_block" ]; ok {
521
+ policy .CidrBlock = helper .String (cidr .(string ))
522
+ }
523
+ if desc , ok := dMap ["description" ]; ok {
524
+ policy .Description = helper .String (desc .(string ))
525
+ }
526
+ if index , ok := dMap ["index" ]; ok {
527
+ policy .PolicyIndex = helper .IntInt64 (index .(int ))
528
+ }
529
+ if version , ok := dMap ["version" ]; ok {
530
+ policy .PolicyVersion = helper .String (version .(string ))
531
+ }
532
+ request .SecurityGroupPolicySet = append (request .SecurityGroupPolicySet , policy )
533
+ }
534
+
535
+ _ , err := client .UseTCRClient ().DeleteMultipleSecurityPolicy (request )
536
+ if err != nil {
537
+ return err
538
+ }
539
+ return nil
540
+ }
0 commit comments