@@ -14,6 +14,21 @@ resource "tencentcloud_tcr_instance" "foo" {
14
14
}
15
15
```
16
16
17
+ Using public network access whitelist
18
+ ```
19
+ resource "tencentcloud_tcr_instance" "foo" {
20
+ name = "example"
21
+ instance_type = "basic"
22
+ open_public_operation = true
23
+ security_poicy {
24
+ cidr_block = "10.0.0.1/24"
25
+ }
26
+ security_policy {
27
+ cidr_block = "192.168.1.1"
28
+ }
29
+ }
30
+ ```
31
+
17
32
Import
18
33
19
34
tcr instance can be imported using the id, e.g.
@@ -27,18 +42,19 @@ package tencentcloud
27
42
import (
28
43
"context"
29
44
"fmt"
30
-
31
45
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
32
46
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
47
+ tcr "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tcr/v20190924"
33
48
"github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper"
49
+ "log"
34
50
)
35
51
36
52
func resourceTencentCloudTcrInstance () * schema.Resource {
37
53
return & schema.Resource {
38
54
Create : resourceTencentCloudTcrInstanceCreate ,
39
55
Read : resourceTencentCloudTcrInstanceRead ,
40
56
Update : resourceTencentCloudTcrInstanceUpdate ,
41
- Delete : resourceTencentCLoudTcrInstanceDelete ,
57
+ Delete : resourceTencentCloudTcrInstanceDelete ,
42
58
Importer : & schema.ResourceImporter {
43
59
State : schema .ImportStatePassthrough ,
44
60
},
@@ -67,6 +83,35 @@ func resourceTencentCloudTcrInstance() *schema.Resource {
67
83
Default : false ,
68
84
Description : "Control public network access." ,
69
85
},
86
+ "security_policy" : {
87
+ Type : schema .TypeSet ,
88
+ Optional : true ,
89
+ Description : "Public network access allowlist policies of the TCR instance. Only available when `open_public_operation` is `true`." ,
90
+ Elem : & schema.Resource {
91
+ Schema : map [string ]* schema.Schema {
92
+ "cidr_block" : {
93
+ Type : schema .TypeString ,
94
+ Optional : true ,
95
+ Description : "The public network IP address of the access source." ,
96
+ },
97
+ "description" : {
98
+ Type : schema .TypeString ,
99
+ Optional : true ,
100
+ Description : "Remarks of policy." ,
101
+ },
102
+ "index" : {
103
+ Type : schema .TypeInt ,
104
+ Computed : true ,
105
+ Description : "Index of policy." ,
106
+ },
107
+ "version" : {
108
+ Type : schema .TypeString ,
109
+ Computed : true ,
110
+ Description : "Version of policy." ,
111
+ },
112
+ },
113
+ },
114
+ },
70
115
//Computed values
71
116
"status" : {
72
117
Type : schema .TypeString ,
@@ -104,17 +149,23 @@ func resourceTencentCloudTcrInstanceCreate(d *schema.ResourceData, meta interfac
104
149
logId := getLogId (contextNil )
105
150
ctx := context .WithValue (context .TODO (), logIdKey , logId )
106
151
107
- tcrService := TCRService {client : meta .(* TencentCloudClient ).apiV3Conn }
152
+ client := meta .(* TencentCloudClient ).apiV3Conn
153
+ tcrService := TCRService {client : client }
108
154
109
155
var (
110
156
name = d .Get ("name" ).(string )
111
157
insType = d .Get ("instance_type" ).(string )
112
158
outErr , inErr error
113
159
instanceId string
114
160
instanceStatus string
115
- operation bool
161
+ operation = d . Get ( "open_public_operation" ).( bool )
116
162
)
117
163
164
+ // Check if security_policy but open_public_operation is false
165
+ if _ , ok := d .GetOk ("security_policy" ); ok && ! operation {
166
+ return fmt .Errorf ("`open_public_operation` must be `true` if `security_policy` set" )
167
+ }
168
+
118
169
outErr = resource .Retry (writeRetryTimeout , func () * resource.RetryError {
119
170
instanceId , inErr = tcrService .CreateTCRInstance (ctx , name , insType , map [string ]string {})
120
171
if inErr != nil {
@@ -147,9 +198,11 @@ func resourceTencentCloudTcrInstanceCreate(d *schema.ResourceData, meta interfac
147
198
return err
148
199
}
149
200
if instanceStatus == "Running" {
201
+ openPublicOperation , ok := d .GetOk ("open_public_operation" )
202
+ operation = openPublicOperation .(bool )
203
+
150
204
outErr = resource .Retry (writeRetryTimeout , func () * resource.RetryError {
151
- if v , ok := d .GetOk ("open_public_operation" ); ok {
152
- operation = v .(bool )
205
+ if ok {
153
206
if operation {
154
207
inErr = tcrService .ManageTCRExternalEndpoint (ctx , instanceId , "Create" )
155
208
} else {
@@ -164,6 +217,38 @@ func resourceTencentCloudTcrInstanceCreate(d *schema.ResourceData, meta interfac
164
217
if outErr != nil {
165
218
return outErr
166
219
}
220
+
221
+ if raw , ok := d .GetOk ("security_policy" ); ok && operation {
222
+ // Waiting for External EndPoint opened
223
+ err = resource .Retry (5 * readRetryTimeout , func () * resource.RetryError {
224
+ var (
225
+ status string
226
+ )
227
+ status , _ , err = tcrService .DescribeExternalEndpointStatus (ctx , instanceId )
228
+ if err != nil {
229
+ return resource .NonRetryableError (fmt .Errorf ("an error occured during DescribeExternalEndpointStatus: %s" , err .Error ()))
230
+ }
231
+
232
+ if status == "Opened" {
233
+ return nil
234
+ }
235
+
236
+ if status == "Opening" {
237
+ return resource .RetryableError (fmt .Errorf ("external endpoint status is `%s`, retrying" , status ))
238
+ }
239
+
240
+ return resource .NonRetryableError (fmt .Errorf ("unexpected external endpoint status: `%s`" , status ))
241
+ })
242
+
243
+ if err != nil {
244
+ return err
245
+ }
246
+ if err := resourceTencentCloudTcrSecurityPolicyAdd (d , meta , raw .(* schema.Set ).List ()); err != nil {
247
+ return err
248
+ }
249
+ } else if ! operation {
250
+ log .Printf ("[WARN] `open_public_operation` was not opened, skip `security_policy` set." )
251
+ }
167
252
}
168
253
169
254
if tags := helper .GetTags (d , "tags" ); len (tags ) > 0 {
@@ -185,7 +270,8 @@ func resourceTencentCloudTcrInstanceRead(d *schema.ResourceData, meta interface{
185
270
ctx := context .WithValue (context .TODO (), logIdKey , logId )
186
271
187
272
var outErr , inErr error
188
- tcrService := TCRService {client : meta .(* TencentCloudClient ).apiV3Conn }
273
+ client := meta .(* TencentCloudClient ).apiV3Conn
274
+ tcrService := TCRService {client : client }
189
275
instance , has , outErr := tcrService .DescribeTCRInstanceById (ctx , d .Id ())
190
276
if outErr != nil {
191
277
outErr = resource .Retry (readRetryTimeout , func () * resource.RetryError {
@@ -234,6 +320,31 @@ func resourceTencentCloudTcrInstanceRead(d *schema.ResourceData, meta interface{
234
320
_ = d .Set ("internal_end_point" , instance .InternalEndpoint )
235
321
_ = d .Set ("public_status" , publicStatus )
236
322
323
+ request := tcr .NewDescribeSecurityPoliciesRequest ()
324
+ request .RegistryId = helper .String (d .Id ())
325
+ response , err := client .UseTCRClient ().DescribeSecurityPolicies (request )
326
+ if err == nil {
327
+ if response .Response .SecurityPolicySet != nil {
328
+ securityPolicySet := response .Response .SecurityPolicySet
329
+ policies := make ([]interface {}, 0 , len (securityPolicySet ))
330
+ for i := range securityPolicySet {
331
+ item := securityPolicySet [i ]
332
+ policy := make (map [string ]interface {})
333
+ policy ["cidr_block" ] = * item .CidrBlock
334
+ policy ["description" ] = * item .Description
335
+ policy ["index" ] = * item .PolicyIndex
336
+ policy ["version" ] = * item .PolicyVersion
337
+ policies = append (policies , policy )
338
+ }
339
+ if err := d .Set ("security_policy" , policies ); err != nil {
340
+ return err
341
+ }
342
+ }
343
+ } else {
344
+ _ = d .Set ("security_policy" , make ([]interface {}, 0 ))
345
+ log .Printf ("[WARN] %s error: %s" , request .GetAction (), err .Error ())
346
+ }
347
+
237
348
tags := make (map [string ]string , len (instance .TagSpecification .Tags ))
238
349
for _ , tag := range instance .TagSpecification .Tags {
239
350
tags [* tag .Key ] = * tag .Value
@@ -259,16 +370,13 @@ func resourceTencentCloudTcrInstanceUpdate(d *schema.ResourceData, meta interfac
259
370
if d .HasChange ("open_public_operation" ) {
260
371
operation = d .Get ("open_public_operation" ).(bool )
261
372
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
- }
373
+ if operation {
374
+ inErr = tcrService .ManageTCRExternalEndpoint (ctx , instanceId , "Create" )
375
+ } else {
376
+ inErr = tcrService .ManageTCRExternalEndpoint (ctx , instanceId , "Delete" )
377
+ }
378
+ if inErr != nil {
379
+ return retryError (inErr )
272
380
}
273
381
return nil
274
382
})
@@ -277,6 +385,53 @@ func resourceTencentCloudTcrInstanceUpdate(d *schema.ResourceData, meta interfac
277
385
}
278
386
}
279
387
388
+ if d .HasChange ("security_policy" ) {
389
+ var err error
390
+ // Waiting for External EndPoint opened
391
+ err = resource .Retry (5 * readRetryTimeout , func () * resource.RetryError {
392
+ var (
393
+ status string
394
+ )
395
+ status , _ , err = tcrService .DescribeExternalEndpointStatus (ctx , instanceId )
396
+ if err != nil {
397
+ return resource .NonRetryableError (fmt .Errorf ("an error occured during DescribeExternalEndpointStatus: %s" , err .Error ()))
398
+ }
399
+
400
+ if status == "Opened" {
401
+ return nil
402
+ }
403
+
404
+ if status == "Opening" {
405
+ return resource .RetryableError (fmt .Errorf ("external endpoint status is `%s`, retrying" , status ))
406
+ }
407
+
408
+ return resource .NonRetryableError (fmt .Errorf ("unexpected external endpoint status: `%s`" , status ))
409
+ })
410
+
411
+ if err != nil {
412
+ return err
413
+ }
414
+
415
+ o , n := d .GetChange ("security_policy" )
416
+ os := o .(* schema.Set )
417
+ ns := n .(* schema.Set )
418
+ add := ns .Difference (os ).List ()
419
+ remove := os .Difference (ns ).List ()
420
+ if len (remove ) > 0 {
421
+ err := resourceTencentCloudTcrSecurityPolicyRemove (d , meta , remove )
422
+ if err != nil {
423
+ return err
424
+ }
425
+ }
426
+ if len (add ) > 0 {
427
+ err := resourceTencentCloudTcrSecurityPolicyAdd (d , meta , add )
428
+ if err != nil {
429
+ return err
430
+ }
431
+ }
432
+ d .SetPartial ("security_policy" )
433
+ }
434
+
280
435
if d .HasChange ("tags" ) {
281
436
oldTags , newTags := d .GetChange ("tags" )
282
437
replaceTags , deleteTags := diffTags (oldTags .(map [string ]interface {}), newTags .(map [string ]interface {}))
@@ -292,7 +447,7 @@ func resourceTencentCloudTcrInstanceUpdate(d *schema.ResourceData, meta interfac
292
447
return resourceTencentCloudTcrInstanceRead (d , meta )
293
448
}
294
449
295
- func resourceTencentCLoudTcrInstanceDelete (d * schema.ResourceData , meta interface {}) error {
450
+ func resourceTencentCloudTcrInstanceDelete (d * schema.ResourceData , meta interface {}) error {
296
451
defer logElapsed ("resource.tencentcloud_tcr_instance.delete" )()
297
452
298
453
logId := getLogId (contextNil )
@@ -338,3 +493,63 @@ func resourceTencentCLoudTcrInstanceDelete(d *schema.ResourceData, meta interfac
338
493
339
494
return nil
340
495
}
496
+
497
+ func resourceTencentCloudTcrSecurityPolicyAdd (d * schema.ResourceData , meta interface {}, add []interface {}) error {
498
+ client := meta .(* TencentCloudClient ).apiV3Conn
499
+ request := tcr .NewCreateMultipleSecurityPolicyRequest ()
500
+ request .RegistryId = helper .String (d .Id ())
501
+
502
+ for _ , i := range add {
503
+ dMap := i .(map [string ]interface {})
504
+ policy := & tcr.SecurityPolicy {}
505
+ if cidr , ok := dMap ["cidr_block" ]; ok {
506
+ policy .CidrBlock = helper .String (cidr .(string ))
507
+ }
508
+ if desc , ok := dMap ["description" ]; ok {
509
+ policy .Description = helper .String (desc .(string ))
510
+ }
511
+ if index , ok := dMap ["index" ]; ok {
512
+ policy .PolicyIndex = helper .IntInt64 (index .(int ))
513
+ }
514
+ if version , ok := dMap ["version" ]; ok {
515
+ policy .PolicyVersion = helper .String (version .(string ))
516
+ }
517
+ request .SecurityGroupPolicySet = append (request .SecurityGroupPolicySet , policy )
518
+ }
519
+
520
+ _ , err := client .UseTCRClient ().CreateMultipleSecurityPolicy (request )
521
+ if err != nil {
522
+ return err
523
+ }
524
+ return nil
525
+ }
526
+
527
+ func resourceTencentCloudTcrSecurityPolicyRemove (d * schema.ResourceData , meta interface {}, remove []interface {}) error {
528
+ client := meta .(* TencentCloudClient ).apiV3Conn
529
+ request := tcr .NewDeleteMultipleSecurityPolicyRequest ()
530
+ request .RegistryId = helper .String (d .Id ())
531
+
532
+ for _ , i := range remove {
533
+ dMap := i .(map [string ]interface {})
534
+ policy := & tcr.SecurityPolicy {}
535
+ if cidr , ok := dMap ["cidr_block" ]; ok {
536
+ policy .CidrBlock = helper .String (cidr .(string ))
537
+ }
538
+ if desc , ok := dMap ["description" ]; ok {
539
+ policy .Description = helper .String (desc .(string ))
540
+ }
541
+ if index , ok := dMap ["index" ]; ok {
542
+ policy .PolicyIndex = helper .IntInt64 (index .(int ))
543
+ }
544
+ if version , ok := dMap ["version" ]; ok {
545
+ policy .PolicyVersion = helper .String (version .(string ))
546
+ }
547
+ request .SecurityGroupPolicySet = append (request .SecurityGroupPolicySet , policy )
548
+ }
549
+
550
+ _ , err := client .UseTCRClient ().DeleteMultipleSecurityPolicy (request )
551
+ if err != nil {
552
+ return err
553
+ }
554
+ return nil
555
+ }
0 commit comments