@@ -27,18 +27,19 @@ package tencentcloud
2727import (
2828 "context"
2929 "fmt"
30-
3130 "github.com/hashicorp/terraform-plugin-sdk/helper/resource"
3231 "github.com/hashicorp/terraform-plugin-sdk/helper/schema"
32+ tcr "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tcr/v20190924"
3333 "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper"
34+ "log"
3435)
3536
3637func resourceTencentCloudTcrInstance () * schema.Resource {
3738 return & schema.Resource {
3839 Create : resourceTencentCloudTcrInstanceCreate ,
3940 Read : resourceTencentCloudTcrInstanceRead ,
4041 Update : resourceTencentCloudTcrInstanceUpdate ,
41- Delete : resourceTencentCLoudTcrInstanceDelete ,
42+ Delete : resourceTencentCloudTcrInstanceDelete ,
4243 Importer : & schema.ResourceImporter {
4344 State : schema .ImportStatePassthrough ,
4445 },
@@ -67,6 +68,35 @@ func resourceTencentCloudTcrInstance() *schema.Resource {
6768 Default : false ,
6869 Description : "Control public network access." ,
6970 },
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+ },
70100 //Computed values
71101 "status" : {
72102 Type : schema .TypeString ,
@@ -104,17 +134,23 @@ func resourceTencentCloudTcrInstanceCreate(d *schema.ResourceData, meta interfac
104134 logId := getLogId (contextNil )
105135 ctx := context .WithValue (context .TODO (), logIdKey , logId )
106136
107- tcrService := TCRService {client : meta .(* TencentCloudClient ).apiV3Conn }
137+ client := meta .(* TencentCloudClient ).apiV3Conn
138+ tcrService := TCRService {client : client }
108139
109140 var (
110141 name = d .Get ("name" ).(string )
111142 insType = d .Get ("instance_type" ).(string )
112143 outErr , inErr error
113144 instanceId string
114145 instanceStatus string
115- operation bool
146+ operation = d . Get ( "open_public_operation" ).( bool )
116147 )
117148
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+
118154 outErr = resource .Retry (writeRetryTimeout , func () * resource.RetryError {
119155 instanceId , inErr = tcrService .CreateTCRInstance (ctx , name , insType , map [string ]string {})
120156 if inErr != nil {
@@ -147,9 +183,11 @@ func resourceTencentCloudTcrInstanceCreate(d *schema.ResourceData, meta interfac
147183 return err
148184 }
149185 if instanceStatus == "Running" {
186+ openPublicOperation , ok := d .GetOk ("open_public_operation" )
187+ operation = openPublicOperation .(bool )
188+
150189 outErr = resource .Retry (writeRetryTimeout , func () * resource.RetryError {
151- if v , ok := d .GetOk ("open_public_operation" ); ok {
152- operation = v .(bool )
190+ if ok {
153191 if operation {
154192 inErr = tcrService .ManageTCRExternalEndpoint (ctx , instanceId , "Create" )
155193 } else {
@@ -164,6 +202,38 @@ func resourceTencentCloudTcrInstanceCreate(d *schema.ResourceData, meta interfac
164202 if outErr != nil {
165203 return outErr
166204 }
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+ }
167237 }
168238
169239 if tags := helper .GetTags (d , "tags" ); len (tags ) > 0 {
@@ -185,7 +255,8 @@ func resourceTencentCloudTcrInstanceRead(d *schema.ResourceData, meta interface{
185255 ctx := context .WithValue (context .TODO (), logIdKey , logId )
186256
187257 var outErr , inErr error
188- tcrService := TCRService {client : meta .(* TencentCloudClient ).apiV3Conn }
258+ client := meta .(* TencentCloudClient ).apiV3Conn
259+ tcrService := TCRService {client : client }
189260 instance , has , outErr := tcrService .DescribeTCRInstanceById (ctx , d .Id ())
190261 if outErr != nil {
191262 outErr = resource .Retry (readRetryTimeout , func () * resource.RetryError {
@@ -234,6 +305,31 @@ func resourceTencentCloudTcrInstanceRead(d *schema.ResourceData, meta interface{
234305 _ = d .Set ("internal_end_point" , instance .InternalEndpoint )
235306 _ = d .Set ("public_status" , publicStatus )
236307
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+
237333 tags := make (map [string ]string , len (instance .TagSpecification .Tags ))
238334 for _ , tag := range instance .TagSpecification .Tags {
239335 tags [* tag .Key ] = * tag .Value
@@ -259,16 +355,13 @@ func resourceTencentCloudTcrInstanceUpdate(d *schema.ResourceData, meta interfac
259355 if d .HasChange ("open_public_operation" ) {
260356 operation = d .Get ("open_public_operation" ).(bool )
261357 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 )
272365 }
273366 return nil
274367 })
@@ -277,6 +370,53 @@ func resourceTencentCloudTcrInstanceUpdate(d *schema.ResourceData, meta interfac
277370 }
278371 }
279372
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+
280420 if d .HasChange ("tags" ) {
281421 oldTags , newTags := d .GetChange ("tags" )
282422 replaceTags , deleteTags := diffTags (oldTags .(map [string ]interface {}), newTags .(map [string ]interface {}))
@@ -292,7 +432,7 @@ func resourceTencentCloudTcrInstanceUpdate(d *schema.ResourceData, meta interfac
292432 return resourceTencentCloudTcrInstanceRead (d , meta )
293433}
294434
295- func resourceTencentCLoudTcrInstanceDelete (d * schema.ResourceData , meta interface {}) error {
435+ func resourceTencentCloudTcrInstanceDelete (d * schema.ResourceData , meta interface {}) error {
296436 defer logElapsed ("resource.tencentcloud_tcr_instance.delete" )()
297437
298438 logId := getLogId (contextNil )
@@ -338,3 +478,63 @@ func resourceTencentCLoudTcrInstanceDelete(d *schema.ResourceData, meta interfac
338478
339479 return nil
340480}
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