From 2a572465bf7f7d8cbe981df341954020c8434a7c Mon Sep 17 00:00:00 2001 From: Alex Hung Date: Wed, 27 Mar 2024 10:35:20 -0700 Subject: [PATCH] Add retry logic for project_repository create func --- pkg/project/resource_project_repository.go | 74 +++++++++++++++++----- sample.tf | 2 +- 2 files changed, 59 insertions(+), 17 deletions(-) diff --git a/pkg/project/resource_project_repository.go b/pkg/project/resource_project_repository.go index 4ca6999c..b0312acf 100644 --- a/pkg/project/resource_project_repository.go +++ b/pkg/project/resource_project_repository.go @@ -8,18 +8,25 @@ import ( "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/jfrog/terraform-provider-shared/util" "github.com/jfrog/terraform-provider-shared/util/sdk" "github.com/jfrog/terraform-provider-shared/validator" ) +const repositoryEndpoint = "/artifactory/api/repositories/{key}" + type Repository struct { Key string `json:"key"` ProjectKey string `json:"projectKey"` } func projectRepositoryResource() *schema.Resource { + var projectRepositoryID = func(projectKey, repoKey string) string { + return fmt.Sprintf("%s-%s", projectKey, repoKey) + } + var projectRepositorySchema = map[string]*schema.Schema{ "project_key": { Type: schema.TypeString, @@ -37,17 +44,28 @@ func projectRepositoryResource() *schema.Resource { }, } + var packProjectRepository = func(repo Repository, data *schema.ResourceData) error { + setValue := sdk.MkLens(data) + + setValue("project_key", repo.ProjectKey) + errors := setValue("key", repo.Key) + if len(errors) > 0 { + return fmt.Errorf("failed to pack project repository %q", errors) + } + + data.SetId(projectRepositoryID(repo.ProjectKey, repo.Key)) + + return nil + } + var readProjectRepository = func(ctx context.Context, data *schema.ResourceData, m interface{}) diag.Diagnostics { repoKey := data.Get("key").(string) var repo Repository - - var projectError ProjectErrorsResponse resp, err := m.(util.ProvderMetadata).Client.R(). SetResult(&repo). SetPathParam("key", repoKey). - SetError(&projectError). - Get("/artifactory/api/repositories/{key}") + Get(repositoryEndpoint) if err != nil { return diag.FromErr(err) @@ -57,22 +75,18 @@ func projectRepositoryResource() *schema.Resource { return nil } if resp.IsError() { - return diag.Errorf("%s", projectError.String()) + return diag.Errorf("%s", resp.String()) } if repo.ProjectKey == "" { - tflog.Info(ctx, "no project_key for repo", map[string]any{"repoKey": repoKey}) + tflog.Warn(ctx, "no project_key for repo", map[string]any{"repoKey": repoKey}) data.SetId("") return nil } - setValue := sdk.MkLens(data) - - setValue("project_key", repo.ProjectKey) - errors := setValue("key", repo.Key) - - if len(errors) > 0 { - return diag.Errorf("failed to pack project repository %q", errors) + err = packProjectRepository(repo, data) + if err != nil { + return diag.FromErr(err) } return nil @@ -98,9 +112,37 @@ func projectRepositoryResource() *schema.Resource { return diag.Errorf("%s", projectError.String()) } - data.SetId(fmt.Sprintf("%s-%s", projectKey, repoKey)) + retryError := retry.RetryContext(ctx, data.Timeout(schema.TimeoutCreate), func() *retry.RetryError { + var repo Repository + resp, err := m.(util.ProvderMetadata).Client.R(). + SetResult(&repo). + SetPathParam("key", repoKey). + Get(repositoryEndpoint) + + if err != nil { + return retry.NonRetryableError(fmt.Errorf("error getting repository: %s", err)) + } + if resp.IsError() { + return retry.NonRetryableError(fmt.Errorf("error getting repository: %s", resp.String())) + } + + if repo.ProjectKey == "" { + return retry.RetryableError(fmt.Errorf("expected repository to be assigned to project but currently not")) + } + + err = packProjectRepository(repo, data) + if err != nil { + return retry.NonRetryableError(err) + } + + return nil + }) - return readProjectRepository(ctx, data, m) + if retryError != nil { + return diag.FromErr(retryError) + } + + return nil } var deleteProjectRepository = func(ctx context.Context, data *schema.ResourceData, m interface{}) diag.Diagnostics { @@ -132,7 +174,7 @@ func projectRepositoryResource() *schema.Resource { d.Set("project_key", parts[0]) d.Set("key", parts[1]) - d.SetId(fmt.Sprintf("%s-%s", parts[0], parts[1])) + d.SetId(projectRepositoryID(parts[0], parts[1])) return []*schema.ResourceData{d}, nil } diff --git a/sample.tf b/sample.tf index 4fc17040..e2d68ffc 100644 --- a/sample.tf +++ b/sample.tf @@ -2,7 +2,7 @@ terraform { required_providers { project = { source = "jfrog/project" - version = "1.5.0" + version = "1.5.1" } } }