Skip to content

Commit

Permalink
Merge pull request #111 from jfrog/GH-110-project-repository-error
Browse files Browse the repository at this point in the history
Add retry logic for project_repository create func
  • Loading branch information
alexhung authored Mar 27, 2024
2 parents 41ce2b5 + 8a24140 commit 3e578f6
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 17 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 1.5.2 (March 28, 2024)

IMPROVEMENTS:

* resource/project_repository: Add retry logic after resource creation to allow time for repository project assignment to be synced up. Issue: [#110](https://github.com/jfrog/terraform-provider-project/issues/110) PR: [#111](https://github.com/jfrog/terraform-provider-project/pull/111)

## 1.5.1 (March 14, 2024)

BUG FIXES:
Expand Down
74 changes: 58 additions & 16 deletions pkg/project/resource_project_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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)
Expand All @@ -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
Expand All @@ -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 {
Expand Down Expand Up @@ -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
}
Expand Down
2 changes: 1 addition & 1 deletion sample.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ terraform {
required_providers {
project = {
source = "jfrog/project"
version = "1.5.0"
version = "1.5.1"
}
}
}
Expand Down

0 comments on commit 3e578f6

Please sign in to comment.