diff --git a/alicloud/provider.go b/alicloud/provider.go index c7fa85610ae8..8cd63f60760b 100644 --- a/alicloud/provider.go +++ b/alicloud/provider.go @@ -1193,7 +1193,7 @@ func Provider() terraform.ResourceProvider { "alicloud_cr_ee_instance": resourceAliCloudCrInstance(), "alicloud_cr_ee_namespace": resourceAliCloudCrEENamespace(), "alicloud_cr_ee_repo": resourceAliCloudCrEERepo(), - "alicloud_cr_ee_sync_rule": resourceAliCloudCrEESyncRule(), + "alicloud_cr_ee_sync_rule": resourceAliCloudCrRepoSyncRule(), "alicloud_cdn_domain": resourceAlicloudCdnDomain(), "alicloud_cdn_domain_new": resourceAliCloudCdnDomain(), "alicloud_cdn_domain_config": resourceAliCloudCdnDomainConfig(), diff --git a/alicloud/resource_alicloud_cr_ee_sync_rule.go b/alicloud/resource_alicloud_cr_ee_sync_rule.go index a26da0157b21..78cc5ce2efce 100644 --- a/alicloud/resource_alicloud_cr_ee_sync_rule.go +++ b/alicloud/resource_alicloud_cr_ee_sync_rule.go @@ -1,24 +1,35 @@ +// Package alicloud. This file is generated automatically. Please do not modify it manually, thank you! package alicloud import ( "fmt" - "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "log" "time" - "github.com/aliyun/alibaba-cloud-sdk-go/services/cr_ee" + util "github.com/alibabacloud-go/tea-utils/service" "github.com/aliyun/terraform-provider-alicloud/alicloud/connectivity" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" ) -func resourceAliCloudCrEESyncRule() *schema.Resource { +func resourceAliCloudCrRepoSyncRule() *schema.Resource { return &schema.Resource{ - Create: resourceAliCloudCrEESyncRuleCreate, - Read: resourceAliCloudCrEESyncRuleRead, - Delete: resourceAliCloudCrEESyncRuleDelete, + Create: resourceAliCloudCrRepoSyncRuleCreate, + Read: resourceAliCloudCrRepoSyncRuleRead, + Update: resourceAliCloudCrRepoSyncRuleUpdate, + Delete: resourceAliCloudCrRepoSyncRuleDelete, Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(5 * time.Minute), + Delete: schema.DefaultTimeout(5 * time.Minute), + }, Schema: map[string]*schema.Schema{ + "create_time": { + Type: schema.TypeString, + Computed: true, + }, "instance_id": { Type: schema.TypeString, Required: true, @@ -29,34 +40,58 @@ func resourceAliCloudCrEESyncRule() *schema.Resource { Required: true, ForceNew: true, }, - "name": { + "region_id": { Type: schema.TypeString, - Required: true, - ForceNew: true, + Computed: true, }, - "target_instance_id": { + "repo_name": { Type: schema.TypeString, - Required: true, + Optional: true, ForceNew: true, }, - "target_namespace_name": { + "repo_sync_rule_id": { + Type: schema.TypeString, + Computed: true, + }, + "sync_rule_name": { + Type: schema.TypeString, + Optional: true, + ExactlyOneOf: []string{"sync_rule_name", "name"}, + Computed: true, + ForceNew: true, + }, + "sync_scope": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + ValidateFunc: StringInSlice([]string{"REPO", "NAMESPACE"}, false), + }, + "sync_trigger": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + ValidateFunc: StringInSlice([]string{"INITIATIVE", "PASSIVE"}, false), + }, + "tag_filter": { Type: schema.TypeString, Required: true, ForceNew: true, }, - "target_region_id": { + "target_instance_id": { Type: schema.TypeString, Required: true, ForceNew: true, }, - "tag_filter": { + "target_namespace_name": { Type: schema.TypeString, Required: true, ForceNew: true, }, - "repo_name": { + "target_region_id": { Type: schema.TypeString, - Optional: true, + Required: true, ForceNew: true, }, "target_repo_name": { @@ -64,66 +99,101 @@ func resourceAliCloudCrEESyncRule() *schema.Resource { Optional: true, ForceNew: true, }, - "rule_id": { + "target_user_id": { Type: schema.TypeString, - Computed: true, + Optional: true, }, "sync_direction": { Type: schema.TypeString, Computed: true, }, - "sync_scope": { - Type: schema.TypeString, - Computed: true, + "name": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Deprecated: "Field `name` has been deprecated from provider version 1.240.0. New field `sync_rule_name` instead.", + ForceNew: true, + }, + "rule_id": { + Type: schema.TypeString, + Computed: true, + Deprecated: "Field `rule_id` has been deprecated from provider version 1.240.0. New field `repo_sync_rule_id` instead.", }, }, } } -func resourceAliCloudCrEESyncRuleCreate(d *schema.ResourceData, meta interface{}) error { +func resourceAliCloudCrRepoSyncRuleCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*connectivity.AliyunClient) - crService := &CrService{client} - response := &cr_ee.CreateRepoSyncRuleResponse{} - request := cr_ee.CreateCreateRepoSyncRuleRequest() - request.RegionId = crService.client.RegionId - request.SyncTrigger = "PASSIVE" - request.InstanceId = d.Get("instance_id").(string) - request.NamespaceName = d.Get("namespace_name").(string) - request.SyncRuleName = d.Get("name").(string) - request.TargetInstanceId = d.Get("target_instance_id").(string) - request.TargetNamespaceName = d.Get("target_namespace_name").(string) - request.TargetRegionId = d.Get("target_region_id").(string) - request.TagFilter = d.Get("tag_filter").(string) + + action := "CreateRepoSyncRule" + var request map[string]interface{} + var response map[string]interface{} + query := make(map[string]interface{}) + conn, err := client.NewAcrClient() + if err != nil { + return WrapError(err) + } + request = make(map[string]interface{}) + request["InstanceId"] = d.Get("instance_id") + request["RegionId"] = client.RegionId + + request["NamespaceName"] = d.Get("namespace_name") + request["TargetRegionId"] = d.Get("target_region_id") + request["TargetInstanceId"] = d.Get("target_instance_id") + request["TargetNamespaceName"] = d.Get("target_namespace_name") + request["TagFilter"] = d.Get("tag_filter") + + if v, ok := d.GetOk("sync_rule_name"); ok { + request["SyncRuleName"] = v + } else if v, ok := d.GetOk("name"); ok { + request["SyncRuleName"] = v + } else { + return WrapError(Error(`[ERROR] Field "sync_rule_name" or "name" must be set one!`)) + } var repoName, targetRepoName string if v, ok := d.GetOk("repo_name"); ok { repoName = v.(string) + request["RepoName"] = repoName } if v, ok := d.GetOk("target_repo_name"); ok { targetRepoName = v.(string) + request["TargetRepoName"] = targetRepoName } if (repoName != "" && targetRepoName == "") || (repoName == "" && targetRepoName != "") { - return WrapError(Error("repo_name and target_repo_name must be set at the same time")) + return WrapError(Error(`[ERROR] Field "repo_name" and "target_repo_name" must be set at the same time!`)) } - if repoName != "" && targetRepoName != "" { - request.SyncScope = "REPO" - request.RepoName = repoName - request.TargetRepoName = targetRepoName + if v, ok := d.GetOk("sync_scope"); ok { + request["SyncScope"] = v } else { - request.SyncScope = "NAMESPACE" + if repoName != "" && targetRepoName != "" { + request["SyncScope"] = "REPO" + } else { + request["SyncScope"] = "NAMESPACE" + } } - var raw interface{} - var err error - wait := incrementalWait(3*time.Second, 3*time.Second) - err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutCreate)), func() *resource.RetryError { - raw, err = crService.client.WithCrEEClient(func(creeClient *cr_ee.Client) (interface{}, error) { - return creeClient.CreateRepoSyncRule(request) - }) + if v, ok := d.GetOk("sync_trigger"); ok { + request["SyncTrigger"] = v + } else { + request["SyncTrigger"] = "PASSIVE" + + } + + if v, ok := d.GetOk("target_user_id"); ok { + request["TargetUserId"] = v + } + runtime := util.RuntimeOptions{} + runtime.SetAutoretry(true) + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(d.Timeout(schema.TimeoutCreate), func() *resource.RetryError { + response, err = conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2018-12-01"), StringPointer("AK"), query, request, &runtime) if err != nil { if NeedRetry(err) { wait() @@ -133,55 +203,99 @@ func resourceAliCloudCrEESyncRuleCreate(d *schema.ResourceData, meta interface{} } return nil }) - addDebug(request.GetActionName(), raw, request.RpcRequest, request) + addDebug(action, response, request) if err != nil { - return WrapErrorf(err, DefaultErrorMsg, "alicloud_cr_ee_sync_rule", request.GetActionName(), AlibabaCloudSdkGoERROR) + return WrapErrorf(err, DefaultErrorMsg, "alicloud_cr_ee_sync_rule", action, AlibabaCloudSdkGoERROR) } - response, _ = raw.(*cr_ee.CreateRepoSyncRuleResponse) - if !response.CreateRepoSyncRuleIsSuccess { - return WrapErrorf(fmt.Errorf("%v", response), DefaultErrorMsg, "alicloud_cr_ee_sync_rule", request.GetActionName(), AlibabaCloudSdkGoERROR) - } + d.SetId(fmt.Sprintf("%s:%s:%s", request["InstanceId"], request["NamespaceName"], response["SyncRuleId"])) - d.SetId(fmt.Sprintf("%s:%s:%s", request.InstanceId, request.NamespaceName, response.SyncRuleId)) - - return resourceAliCloudCrEESyncRuleRead(d, meta) + return resourceAliCloudCrRepoSyncRuleRead(d, meta) } -func resourceAliCloudCrEESyncRuleRead(d *schema.ResourceData, meta interface{}) error { +func resourceAliCloudCrRepoSyncRuleRead(d *schema.ResourceData, meta interface{}) error { client := meta.(*connectivity.AliyunClient) - crService := &CrService{client} + crServiceV2 := CrServiceV2{client} - object, err := crService.DescribeCrEESyncRule(d.Id()) + objectRaw, err := crServiceV2.DescribeCrRepoSyncRule(d.Id()) if err != nil { if !d.IsNewResource() && NotFoundError(err) { + log.Printf("[DEBUG] Resource alicloud_cr_ee_sync_rule DescribeCrRepoSyncRule Failed!!! %s", err) d.SetId("") return nil } return WrapError(err) } - d.Set("instance_id", object.LocalInstanceId) - d.Set("namespace_name", object.LocalNamespaceName) - d.Set("name", object.SyncRuleName) - d.Set("target_instance_id", object.TargetInstanceId) - d.Set("target_namespace_name", object.TargetNamespaceName) - d.Set("target_region_id", object.TargetRegionId) - d.Set("tag_filter", object.TagFilter) - d.Set("repo_name", object.LocalRepoName) - d.Set("target_repo_name", object.TargetRepoName) - d.Set("rule_id", object.SyncRuleId) - d.Set("sync_direction", object.SyncDirection) - d.Set("sync_scope", object.SyncScope) + if objectRaw["CreateTime"] != nil { + d.Set("create_time", objectRaw["CreateTime"]) + } + if objectRaw["LocalNamespaceName"] != nil { + d.Set("namespace_name", objectRaw["LocalNamespaceName"]) + } + if objectRaw["LocalRegionId"] != nil { + d.Set("region_id", objectRaw["LocalRegionId"]) + } + if objectRaw["LocalRepoName"] != nil { + d.Set("repo_name", objectRaw["LocalRepoName"]) + } + if objectRaw["SyncRuleName"] != nil { + d.Set("sync_rule_name", objectRaw["SyncRuleName"]) + d.Set("name", objectRaw["SyncRuleName"]) + } + if objectRaw["SyncScope"] != nil { + d.Set("sync_scope", objectRaw["SyncScope"]) + } + if objectRaw["SyncTrigger"] != nil { + d.Set("sync_trigger", objectRaw["SyncTrigger"]) + } + if objectRaw["TagFilter"] != nil { + d.Set("tag_filter", objectRaw["TagFilter"]) + } + if objectRaw["TargetInstanceId"] != nil { + d.Set("target_instance_id", objectRaw["TargetInstanceId"]) + } + if objectRaw["TargetNamespaceName"] != nil { + d.Set("target_namespace_name", objectRaw["TargetNamespaceName"]) + } + if objectRaw["TargetRegionId"] != nil { + d.Set("target_region_id", objectRaw["TargetRegionId"]) + } + if objectRaw["TargetRepoName"] != nil { + d.Set("target_repo_name", objectRaw["TargetRepoName"]) + } + if objectRaw["LocalInstanceId"] != nil { + d.Set("instance_id", objectRaw["LocalInstanceId"]) + } + if objectRaw["SyncRuleId"] != nil { + d.Set("repo_sync_rule_id", objectRaw["SyncRuleId"]) + d.Set("rule_id", objectRaw["SyncRuleId"]) + } + if objectRaw["SyncDirection"] != nil { + d.Set("sync_direction", objectRaw["SyncDirection"]) + } + + return nil +} +func resourceAliCloudCrRepoSyncRuleUpdate(d *schema.ResourceData, meta interface{}) error { + log.Printf("[INFO] Cannot update resource alicloud_cr_ee_sync_rule.") return nil } -func resourceAliCloudCrEESyncRuleDelete(d *schema.ResourceData, meta interface{}) error { +func resourceAliCloudCrRepoSyncRuleDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*connectivity.AliyunClient) - crService := &CrService{client} - response := &cr_ee.DeleteRepoSyncRuleResponse{} + action := "DeleteRepoSyncRule" + var request map[string]interface{} + var response map[string]interface{} + query := make(map[string]interface{}) + conn, err := client.NewAcrClient() + if err != nil { + return WrapError(err) + } + request = make(map[string]interface{}) parts, err := ParseResourceId(d.Id(), 3) if err != nil { @@ -193,17 +307,16 @@ func resourceAliCloudCrEESyncRuleDelete(d *schema.ResourceData, meta interface{} return WrapError(Error(DefaultErrorMsg, d.Id(), "delete", "[Please delete sync rule in the source instance]")) } - request := cr_ee.CreateDeleteRepoSyncRuleRequest() - request.RegionId = crService.client.RegionId - request.InstanceId = parts[0] - request.SyncRuleId = parts[2] + request["RegionId"] = client.RegionId + request["InstanceId"] = parts[0] + request["SyncRuleId"] = parts[2] + + runtime := util.RuntimeOptions{} + runtime.SetAutoretry(true) + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(d.Timeout(schema.TimeoutDelete), func() *resource.RetryError { + response, err = conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2018-12-01"), StringPointer("AK"), query, request, &runtime) - var raw interface{} - wait := incrementalWait(3*time.Second, 3*time.Second) - err = resource.Retry(client.GetRetryTimeout(d.Timeout(schema.TimeoutDelete)), func() *resource.RetryError { - raw, err = crService.client.WithCrEEClient(func(creeClient *cr_ee.Client) (interface{}, error) { - return creeClient.DeleteRepoSyncRule(request) - }) if err != nil { if NeedRetry(err) { wait() @@ -213,15 +326,13 @@ func resourceAliCloudCrEESyncRuleDelete(d *schema.ResourceData, meta interface{} } return nil }) - addDebug(request.GetActionName(), raw, request.RpcRequest, request) + addDebug(action, response, request) if err != nil { - return WrapErrorf(err, DefaultErrorMsg, d.Id(), request.GetActionName(), AlibabaCloudSdkGoERROR) - } - - response, _ = raw.(*cr_ee.DeleteRepoSyncRuleResponse) - if !response.DeleteRepoSyncRuleIsSuccess { - return WrapErrorf(fmt.Errorf("%v", response), DefaultErrorMsg, d.Id(), request.GetActionName(), AlibabaCloudSdkGoERROR) + if NotFoundError(err) { + return nil + } + return WrapErrorf(err, DefaultErrorMsg, d.Id(), action, AlibabaCloudSdkGoERROR) } return nil diff --git a/alicloud/resource_alicloud_cr_ee_sync_rule_test.go b/alicloud/resource_alicloud_cr_ee_sync_rule_test.go index e74dd45a3e65..8f68113f0842 100644 --- a/alicloud/resource_alicloud_cr_ee_sync_rule_test.go +++ b/alicloud/resource_alicloud_cr_ee_sync_rule_test.go @@ -9,18 +9,130 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/helper/resource" ) -func TestAccAliCloudCREESyncRule_basic0(t *testing.T) { +func TestAccAliCloudCrRepoSyncRule_basic0(t *testing.T) { var v map[string]interface{} resourceId := "alicloud_cr_ee_sync_rule.default" - ra := resourceAttrInit(resourceId, AliCloudCREESyncRuleMap0) + ra := resourceAttrInit(resourceId, AliCloudCrRepoSyncRuleMap0) rc := resourceCheckInitWithDescribeMethod(resourceId, &v, func() interface{} { - return &CrService{testAccProvider.Meta().(*connectivity.AliyunClient)} - }, "DescribeCrEESyncRule") + return &CrServiceV2{testAccProvider.Meta().(*connectivity.AliyunClient)} + }, "DescribeCrRepoSyncRule") rac := resourceAttrCheckInit(rc, ra) testAccCheck := rac.resourceAttrMapUpdateSet() rand := acctest.RandIntRange(1000000, 9999999) name := fmt.Sprintf("tf-testacc-cr-sync-rule-%d", rand) - testAccConfig := resourceTestAccConfigFunc(resourceId, name, AliCloudCREESyncRuleBasicDependence0) + testAccConfig := resourceTestAccConfigFunc(resourceId, name, AliCloudCrRepoSyncRuleBasicDependence0) + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + }, + IDRefreshName: resourceId, + Providers: testAccProviders, + CheckDestroy: rac.checkResourceDestroy(), + Steps: []resource.TestStep{ + { + Config: testAccConfig(map[string]interface{}{ + "instance_id": "${alicloud_cr_ee_namespace.source.instance_id}", + "namespace_name": "${alicloud_cr_ee_namespace.source.name}", + "sync_rule_name": name, + "target_instance_id": "${alicloud_cr_ee_namespace.target.instance_id}", + "target_namespace_name": "${alicloud_cr_ee_namespace.target.name}", + "target_region_id": defaultRegionToTest, + "tag_filter": ".*", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "instance_id": CHECKSET, + "namespace_name": CHECKSET, + "sync_rule_name": name, + "target_instance_id": CHECKSET, + "target_namespace_name": CHECKSET, + "target_region_id": CHECKSET, + "tag_filter": ".*", + }), + ), + }, + { + ResourceName: resourceId, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"target_user_id"}, + }, + }, + }) +} + +func TestAccAliCloudCrRepoSyncRule_basic0_twin(t *testing.T) { + var v map[string]interface{} + resourceId := "alicloud_cr_ee_sync_rule.default" + ra := resourceAttrInit(resourceId, AliCloudCrRepoSyncRuleMap0) + rc := resourceCheckInitWithDescribeMethod(resourceId, &v, func() interface{} { + return &CrServiceV2{testAccProvider.Meta().(*connectivity.AliyunClient)} + }, "DescribeCrRepoSyncRule") + rac := resourceAttrCheckInit(rc, ra) + testAccCheck := rac.resourceAttrMapUpdateSet() + rand := acctest.RandIntRange(1000000, 9999999) + name := fmt.Sprintf("tf-testacc-cr-sync-rule-%d", rand) + testAccConfig := resourceTestAccConfigFunc(resourceId, name, AliCloudCrRepoSyncRuleBasicDependence1) + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + }, + IDRefreshName: resourceId, + Providers: testAccProviders, + CheckDestroy: rac.checkResourceDestroy(), + Steps: []resource.TestStep{ + { + Config: testAccConfig(map[string]interface{}{ + "instance_id": "${alicloud_cr_ee_namespace.source.instance_id}", + "namespace_name": "${alicloud_cr_ee_namespace.source.name}", + "sync_rule_name": name, + "target_instance_id": "${alicloud_cr_ee_namespace.target.instance_id}", + "target_namespace_name": "${alicloud_cr_ee_namespace.target.name}", + "target_region_id": defaultRegionToTest, + "tag_filter": ".*", + "repo_name": "${alicloud_cr_ee_repo.source.name}", + "target_repo_name": "${alicloud_cr_ee_repo.target.name}", + "sync_scope": "REPO", + "sync_trigger": "PASSIVE", + }), + Check: resource.ComposeTestCheckFunc( + testAccCheck(map[string]string{ + "instance_id": CHECKSET, + "namespace_name": CHECKSET, + "sync_rule_name": name, + "target_instance_id": CHECKSET, + "target_namespace_name": CHECKSET, + "target_region_id": CHECKSET, + "tag_filter": ".*", + "repo_name": CHECKSET, + "target_repo_name": CHECKSET, + "sync_scope": "REPO", + "sync_trigger": "PASSIVE", + }), + ), + }, + { + ResourceName: resourceId, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"target_user_id"}, + }, + }, + }) +} + +func TestAccAliCloudCrRepoSyncRule_basic1(t *testing.T) { + var v map[string]interface{} + resourceId := "alicloud_cr_ee_sync_rule.default" + ra := resourceAttrInit(resourceId, AliCloudCrRepoSyncRuleMap0) + rc := resourceCheckInitWithDescribeMethod(resourceId, &v, func() interface{} { + return &CrServiceV2{testAccProvider.Meta().(*connectivity.AliyunClient)} + }, "DescribeCrRepoSyncRule") + rac := resourceAttrCheckInit(rc, ra) + testAccCheck := rac.resourceAttrMapUpdateSet() + rand := acctest.RandIntRange(1000000, 9999999) + name := fmt.Sprintf("tf-testacc-cr-sync-rule-%d", rand) + testAccConfig := resourceTestAccConfigFunc(resourceId, name, AliCloudCrRepoSyncRuleBasicDependence0) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) @@ -52,26 +164,27 @@ func TestAccAliCloudCREESyncRule_basic0(t *testing.T) { ), }, { - ResourceName: resourceId, - ImportState: true, - ImportStateVerify: true, + ResourceName: resourceId, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"target_user_id"}, }, }, }) } -func TestAccAliCloudCREESyncRule_basic0_twin(t *testing.T) { +func TestAccAliCloudCrRepoSyncRule_basic1_twin(t *testing.T) { var v map[string]interface{} resourceId := "alicloud_cr_ee_sync_rule.default" - ra := resourceAttrInit(resourceId, AliCloudCREESyncRuleMap0) + ra := resourceAttrInit(resourceId, AliCloudCrRepoSyncRuleMap0) rc := resourceCheckInitWithDescribeMethod(resourceId, &v, func() interface{} { - return &CrService{testAccProvider.Meta().(*connectivity.AliyunClient)} - }, "DescribeCrEESyncRule") + return &CrServiceV2{testAccProvider.Meta().(*connectivity.AliyunClient)} + }, "DescribeCrRepoSyncRule") rac := resourceAttrCheckInit(rc, ra) testAccCheck := rac.resourceAttrMapUpdateSet() rand := acctest.RandIntRange(1000000, 9999999) name := fmt.Sprintf("tf-testacc-cr-sync-rule-%d", rand) - testAccConfig := resourceTestAccConfigFunc(resourceId, name, AliCloudCREESyncRuleBasicDependence1) + testAccConfig := resourceTestAccConfigFunc(resourceId, name, AliCloudCrRepoSyncRuleBasicDependence1) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) @@ -91,6 +204,8 @@ func TestAccAliCloudCREESyncRule_basic0_twin(t *testing.T) { "tag_filter": ".*", "repo_name": "${alicloud_cr_ee_repo.source.name}", "target_repo_name": "${alicloud_cr_ee_repo.target.name}", + "sync_scope": "REPO", + "sync_trigger": "PASSIVE", }), Check: resource.ComposeTestCheckFunc( testAccCheck(map[string]string{ @@ -103,25 +218,32 @@ func TestAccAliCloudCREESyncRule_basic0_twin(t *testing.T) { "tag_filter": ".*", "repo_name": CHECKSET, "target_repo_name": CHECKSET, + "sync_scope": "REPO", + "sync_trigger": "PASSIVE", }), ), }, { - ResourceName: resourceId, - ImportState: true, - ImportStateVerify: true, + ResourceName: resourceId, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"target_user_id"}, }, }, }) } -var AliCloudCREESyncRuleMap0 = map[string]string{ - "rule_id": CHECKSET, - "sync_direction": CHECKSET, - "sync_scope": CHECKSET, +var AliCloudCrRepoSyncRuleMap0 = map[string]string{ + "create_time": CHECKSET, + "region_id": CHECKSET, + "repo_sync_rule_id": CHECKSET, + "sync_scope": CHECKSET, + "sync_trigger": CHECKSET, + "sync_direction": CHECKSET, + "rule_id": CHECKSET, } -func AliCloudCREESyncRuleBasicDependence0(name string) string { +func AliCloudCrRepoSyncRuleBasicDependence0(name string) string { return fmt.Sprintf(` variable "name" { default = "%s" @@ -146,7 +268,7 @@ func AliCloudCREESyncRuleBasicDependence0(name string) string { `, name) } -func AliCloudCREESyncRuleBasicDependence1(name string) string { +func AliCloudCrRepoSyncRuleBasicDependence1(name string) string { return fmt.Sprintf(` variable "name" { default = "%s" diff --git a/alicloud/service_alicloud_cr_v2.go b/alicloud/service_alicloud_cr_v2.go index b45bdfdfb7d4..e2690b0c1973 100644 --- a/alicloud/service_alicloud_cr_v2.go +++ b/alicloud/service_alicloud_cr_v2.go @@ -248,3 +248,87 @@ func (s *CrServiceV2) DescribeAsyncCrInstanceStateRefreshFunc(d *schema.Resource } // DescribeCrInstance >>> Encapsulated. +// DescribeCrRepoSyncRule <<< Encapsulated get interface for Cr RepoSyncRule. + +func (s *CrServiceV2) DescribeCrRepoSyncRule(id string) (object map[string]interface{}, err error) { + client := s.client + var request map[string]interface{} + var response map[string]interface{} + var query map[string]interface{} + + parts, err := ParseResourceId(id, 3) + if err != nil { + return object, WrapError(err) + } + + action := "ListRepoSyncRule" + conn, err := client.NewAcrClient() + if err != nil { + return object, WrapError(err) + } + request = make(map[string]interface{}) + query = make(map[string]interface{}) + request["InstanceId"] = parts[0] + request["NamespaceName"] = parts[1] + request["RegionId"] = client.RegionId + request["PageSize"] = PageSizeLarge + request["PageNo"] = 1 + + idExist := false + for { + runtime := util.RuntimeOptions{} + runtime.SetAutoretry(true) + wait := incrementalWait(3*time.Second, 5*time.Second) + err = resource.Retry(1*time.Minute, func() *resource.RetryError { + response, err = conn.DoRequest(StringPointer(action), nil, StringPointer("POST"), StringPointer("2018-12-01"), StringPointer("AK"), query, request, &runtime) + + if err != nil { + if NeedRetry(err) { + wait() + return resource.RetryableError(err) + } + return resource.NonRetryableError(err) + } + return nil + }) + addDebug(action, response, request) + + if err != nil { + return object, WrapErrorf(err, DefaultErrorMsg, id, action, AlibabaCloudSdkGoERROR) + } + + if fmt.Sprint(response["IsSuccess"]) == "false" { + return object, WrapError(fmt.Errorf("%s failed, response: %v", action, response)) + } + + resp, err := jsonpath.Get("$.SyncRules", response) + if err != nil { + return object, WrapErrorf(err, FailedGetAttributeMsg, id, "$.SyncRules", response) + } + + if v, ok := resp.([]interface{}); !ok || len(v) < 1 { + return object, WrapErrorf(Error(GetNotFoundMessage("Cr:RepoSyncRule", id)), NotFoundWithResponse, response) + } + + for _, v := range resp.([]interface{}) { + if fmt.Sprint(v.(map[string]interface{})["LocalInstanceId"]) == parts[0] && fmt.Sprint(v.(map[string]interface{})["LocalNamespaceName"]) == parts[1] && fmt.Sprint(v.(map[string]interface{})["SyncRuleId"]) == parts[2] { + idExist = true + return v.(map[string]interface{}), nil + } + } + + if len(resp.([]interface{})) < request["PageSize"].(int) { + break + } + + request["PageNo"] = request["PageNo"].(int) + 1 + } + + if !idExist { + return object, WrapErrorf(Error(GetNotFoundMessage("Cr:RepoSyncRule", id)), NotFoundWithResponse, response) + } + + return object, nil +} + +// DescribeCrInstance >>> Encapsulated. diff --git a/website/docs/r/cr_ee_sync_rule.html.markdown b/website/docs/r/cr_ee_sync_rule.html.markdown index 8e8eb10a0481..bf4c57c76a1c 100644 --- a/website/docs/r/cr_ee_sync_rule.html.markdown +++ b/website/docs/r/cr_ee_sync_rule.html.markdown @@ -2,20 +2,19 @@ subcategory: "Container Registry (CR)" layout: "alicloud" page_title: "Alicloud: alicloud_cr_ee_sync_rule" -sidebar_current: "docs-alicloud-resource-cr-ee-sync-rule" description: |- - Provides a Alicloud Container Registry Enterprise Edition Sync Rule resource. + Provides a Alicloud Container Registry Sync Rule resource. --- # alicloud_cr_ee_sync_rule -Provides a Container Registry Enterprise Edition Sync Rule resource. +Provides a Container Registry Sync Rule resource. -For information about Container Registry Enterprise Edition Sync Rule and how to use it, see [What is Sync Rule](https://www.alibabacloud.com/help/en/acr/developer-reference/api-cr-2018-12-01-createreposyncrule) +For information about Container Registry Sync Rule and how to use it, see [What is Sync Rule](https://www.alibabacloud.com/help/en/acr/developer-reference/api-cr-2018-12-01-createreposyncrule) -> **NOTE:** Available since v1.90.0. --> **NOTE:** You need to set your registry password in Container Registry Enterprise Edition console before use this resource. +-> **NOTE:** You need to set your registry password in Container Registry console before use this resource. ## Example Usage @@ -92,7 +91,7 @@ resource "alicloud_cr_ee_repo" "target" { resource "alicloud_cr_ee_sync_rule" "default" { instance_id = alicloud_cr_ee_instance.source.id namespace_name = alicloud_cr_ee_namespace.source.name - name = "${var.name}-${random_integer.default.result}" + sync_rule_name = "${var.name}-${random_integer.default.result}" target_instance_id = alicloud_cr_ee_instance.target.id target_namespace_name = alicloud_cr_ee_namespace.target.name target_region_id = data.alicloud_regions.default.regions.0.id @@ -105,30 +104,48 @@ resource "alicloud_cr_ee_sync_rule" "default" { ## Argument Reference The following arguments are supported: - -* `instance_id` - (Required, ForceNew) The ID of the Container Registry Enterprise Edition source instance. +* `instance_id` - (Required, ForceNew) The ID of the Container Registry source instance. * `namespace_name` - (Required, ForceNew) The namespace name of the source instance. -* `name` - (Required, ForceNew) The name of the sync rule. +* `repo_name` - (Optional, ForceNew) The image repository name of the source instance. +* `sync_rule_name` - (Optional, ForceNew, Available since v1.240.0) The name of the sync rule. +* `sync_scope` - (Optional, ForceNew) The synchronization scope. Valid values: + - `REPO`: Encrypts or decrypts data. + - `NAMESPACE`: Generates or verifies a digital signature. +-> **NOTE:** From version 1.240.0, `sync_scope` can be set. +* `sync_trigger` - (Optional, ForceNew, Available since v1.240.0) The policy configured to trigger the synchronization rule. Default value: `PASSIVE`. Valid values: + - `INITIATIVE`: Manually triggers the synchronization rule. + - `PASSIVE`: Automatically triggers the synchronization rule. +* `tag_filter` - (Required, ForceNew) The regular expression used to filter image tags. * `target_instance_id` - (Required, ForceNew) The ID of the destination instance. * `target_namespace_name` - (Required, ForceNew) The namespace name of the destination instance. * `target_region_id` - (Required, ForceNew) The region ID of the destination instance. -* `tag_filter` - (Required, ForceNew) The regular expression used to filter image tags. -* `repo_name` - (Optional, ForceNew) The image repository name of the source instance. * `target_repo_name` - (Optional, ForceNew) The image repository name of the destination instance. +* `target_user_id` - (Optional, Available since v1.240.0) The UID of the account to which the target instance belongs. +* `name` - (Optional, ForceNew, Deprecated since v1.240.0) Field `name` has been deprecated from provider version 1.240.0. New field `sync_rule_name` instead. ## Attributes Reference The following attributes are exported: -* `id` - The resource ID in terraform of Sync Rule. It formats as `::`. -* `rule_id` - The ID of the sync rule. +* `id` - The resource ID in terraform of Sync Rule. It formats as `::`. +* `repo_sync_rule_id` - (Available since v1.240.0) The ID of the synchronization rule. * `sync_direction` - The synchronization direction. -* `sync_scope` - The synchronization scope. +* `create_time` - (Available since v1.240.0) The time when the synchronization rule was created. +* `region_id` - (Available since v1.240.0) The region ID of the source instance. +* `rule_id` - (Deprecated since v1.240.0) Field `rule_id` has been deprecated from provider version 1.240.0. New field `repo_sync_rule_id` instead. + +## Timeouts + +-> **NOTE:** Available since v1.240.0. + +The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/docs/configuration-0-11/resources.html#timeouts) for certain actions: +* `create` - (Defaults to 5 mins) Used when create the Repo Sync Rule. +* `delete` - (Defaults to 5 mins) Used when delete the Repo Sync Rule. ## Import -Container Registry Enterprise Edition Sync Rule can be imported using the id, e.g. +Container Registry Sync Rule can be imported using the id, e.g. ```shell -$ terraform import alicloud_cr_ee_sync_rule.example :: +$ terraform import alicloud_cr_ee_sync_rule.example :: ```