Skip to content

Commit 3e578f6

Browse files
author
Alex Hung
authored
Merge pull request #111 from jfrog/GH-110-project-repository-error
Add retry logic for project_repository create func
2 parents 41ce2b5 + 8a24140 commit 3e578f6

File tree

3 files changed

+65
-17
lines changed

3 files changed

+65
-17
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## 1.5.2 (March 28, 2024)
2+
3+
IMPROVEMENTS:
4+
5+
* 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)
6+
17
## 1.5.1 (March 14, 2024)
28

39
BUG FIXES:

pkg/project/resource_project_repository.go

Lines changed: 58 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,25 @@ import (
88

99
"github.com/hashicorp/terraform-plugin-log/tflog"
1010
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
11+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
1112
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1213
"github.com/jfrog/terraform-provider-shared/util"
1314
"github.com/jfrog/terraform-provider-shared/util/sdk"
1415
"github.com/jfrog/terraform-provider-shared/validator"
1516
)
1617

18+
const repositoryEndpoint = "/artifactory/api/repositories/{key}"
19+
1720
type Repository struct {
1821
Key string `json:"key"`
1922
ProjectKey string `json:"projectKey"`
2023
}
2124

2225
func projectRepositoryResource() *schema.Resource {
26+
var projectRepositoryID = func(projectKey, repoKey string) string {
27+
return fmt.Sprintf("%s-%s", projectKey, repoKey)
28+
}
29+
2330
var projectRepositorySchema = map[string]*schema.Schema{
2431
"project_key": {
2532
Type: schema.TypeString,
@@ -37,17 +44,28 @@ func projectRepositoryResource() *schema.Resource {
3744
},
3845
}
3946

47+
var packProjectRepository = func(repo Repository, data *schema.ResourceData) error {
48+
setValue := sdk.MkLens(data)
49+
50+
setValue("project_key", repo.ProjectKey)
51+
errors := setValue("key", repo.Key)
52+
if len(errors) > 0 {
53+
return fmt.Errorf("failed to pack project repository %q", errors)
54+
}
55+
56+
data.SetId(projectRepositoryID(repo.ProjectKey, repo.Key))
57+
58+
return nil
59+
}
60+
4061
var readProjectRepository = func(ctx context.Context, data *schema.ResourceData, m interface{}) diag.Diagnostics {
4162
repoKey := data.Get("key").(string)
4263

4364
var repo Repository
44-
45-
var projectError ProjectErrorsResponse
4665
resp, err := m.(util.ProvderMetadata).Client.R().
4766
SetResult(&repo).
4867
SetPathParam("key", repoKey).
49-
SetError(&projectError).
50-
Get("/artifactory/api/repositories/{key}")
68+
Get(repositoryEndpoint)
5169

5270
if err != nil {
5371
return diag.FromErr(err)
@@ -57,22 +75,18 @@ func projectRepositoryResource() *schema.Resource {
5775
return nil
5876
}
5977
if resp.IsError() {
60-
return diag.Errorf("%s", projectError.String())
78+
return diag.Errorf("%s", resp.String())
6179
}
6280

6381
if repo.ProjectKey == "" {
64-
tflog.Info(ctx, "no project_key for repo", map[string]any{"repoKey": repoKey})
82+
tflog.Warn(ctx, "no project_key for repo", map[string]any{"repoKey": repoKey})
6583
data.SetId("")
6684
return nil
6785
}
6886

69-
setValue := sdk.MkLens(data)
70-
71-
setValue("project_key", repo.ProjectKey)
72-
errors := setValue("key", repo.Key)
73-
74-
if len(errors) > 0 {
75-
return diag.Errorf("failed to pack project repository %q", errors)
87+
err = packProjectRepository(repo, data)
88+
if err != nil {
89+
return diag.FromErr(err)
7690
}
7791

7892
return nil
@@ -98,9 +112,37 @@ func projectRepositoryResource() *schema.Resource {
98112
return diag.Errorf("%s", projectError.String())
99113
}
100114

101-
data.SetId(fmt.Sprintf("%s-%s", projectKey, repoKey))
115+
retryError := retry.RetryContext(ctx, data.Timeout(schema.TimeoutCreate), func() *retry.RetryError {
116+
var repo Repository
117+
resp, err := m.(util.ProvderMetadata).Client.R().
118+
SetResult(&repo).
119+
SetPathParam("key", repoKey).
120+
Get(repositoryEndpoint)
121+
122+
if err != nil {
123+
return retry.NonRetryableError(fmt.Errorf("error getting repository: %s", err))
124+
}
125+
if resp.IsError() {
126+
return retry.NonRetryableError(fmt.Errorf("error getting repository: %s", resp.String()))
127+
}
128+
129+
if repo.ProjectKey == "" {
130+
return retry.RetryableError(fmt.Errorf("expected repository to be assigned to project but currently not"))
131+
}
132+
133+
err = packProjectRepository(repo, data)
134+
if err != nil {
135+
return retry.NonRetryableError(err)
136+
}
137+
138+
return nil
139+
})
102140

103-
return readProjectRepository(ctx, data, m)
141+
if retryError != nil {
142+
return diag.FromErr(retryError)
143+
}
144+
145+
return nil
104146
}
105147

106148
var deleteProjectRepository = func(ctx context.Context, data *schema.ResourceData, m interface{}) diag.Diagnostics {
@@ -132,7 +174,7 @@ func projectRepositoryResource() *schema.Resource {
132174

133175
d.Set("project_key", parts[0])
134176
d.Set("key", parts[1])
135-
d.SetId(fmt.Sprintf("%s-%s", parts[0], parts[1]))
177+
d.SetId(projectRepositoryID(parts[0], parts[1]))
136178

137179
return []*schema.ResourceData{d}, nil
138180
}

sample.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ terraform {
22
required_providers {
33
project = {
44
source = "jfrog/project"
5-
version = "1.5.0"
5+
version = "1.5.1"
66
}
77
}
88
}

0 commit comments

Comments
 (0)