Skip to content

Commit c196264

Browse files
committed
gitlab_project_access_token: Test bugfix and destroy improvement
- Fixed a test bug where a hardcoded expiration date that passed caused failures - Improved the destroy function to wait for the token to finish deleting
1 parent 2d31a32 commit c196264

File tree

2 files changed

+125
-370
lines changed

2 files changed

+125
-370
lines changed

internal/provider/resource_gitlab_project_access_token.go

Lines changed: 72 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@ package provider
22

33
import (
44
"context"
5+
"errors"
56
"fmt"
67
"log"
78
"strconv"
89
"time"
910

1011
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
12+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
1113
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1214
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
1315
gitlab "github.com/xanzy/go-gitlab"
@@ -140,7 +142,6 @@ func resourceGitlabProjectAccessTokenCreate(ctx context.Context, d *schema.Resou
140142
}
141143

142144
func resourceGitlabProjectAccessTokenRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
143-
144145
project, PATstring, err := parseTwoPartID(d.Id())
145146
if err != nil {
146147
return diag.Errorf("Error parsing ID: %s", d.Id())
@@ -155,6 +156,73 @@ func resourceGitlabProjectAccessTokenRead(ctx context.Context, d *schema.Resourc
155156

156157
log.Printf("[DEBUG] read gitlab ProjectAccessToken %d, project ID %s", projectAccessTokenID, project)
157158

159+
projectAccessToken, err := resourceGitlabProjectAccessTokenFind(ctx, client, project, projectAccessTokenID)
160+
if errors.Is(err, errResourceGitlabProjectAccessTokenNotFound) {
161+
log.Printf("[DEBUG] failed to read gitlab ProjectAccessToken %d, project ID %s", projectAccessTokenID, project)
162+
d.SetId("")
163+
}
164+
if err != nil {
165+
return diag.FromErr(err)
166+
}
167+
168+
d.Set("project", project)
169+
d.Set("name", projectAccessToken.Name)
170+
if projectAccessToken.ExpiresAt != nil {
171+
d.Set("expires_at", projectAccessToken.ExpiresAt.String())
172+
}
173+
d.Set("active", projectAccessToken.Active)
174+
d.Set("created_at", projectAccessToken.CreatedAt.String())
175+
d.Set("revoked", projectAccessToken.Revoked)
176+
d.Set("user_id", projectAccessToken.UserID)
177+
d.Set("access_level", accessLevelValueToName[projectAccessToken.AccessLevel])
178+
err = d.Set("scopes", projectAccessToken.Scopes)
179+
if err != nil {
180+
return diag.FromErr(err)
181+
}
182+
183+
return nil
184+
}
185+
186+
func resourceGitlabProjectAccessTokenDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
187+
project, patString, err := parseTwoPartID(d.Id())
188+
if err != nil {
189+
return diag.Errorf("Error parsing ID: %s", d.Id())
190+
}
191+
192+
client := meta.(*gitlab.Client)
193+
194+
projectAccessTokenID, err := strconv.Atoi(patString)
195+
if err != nil {
196+
return diag.Errorf("%s cannot be converted to int", patString)
197+
}
198+
199+
log.Printf("[DEBUG] Delete gitlab ProjectAccessToken %s", d.Id())
200+
_, err = client.ProjectAccessTokens.DeleteProjectAccessToken(project, projectAccessTokenID, gitlab.WithContext(ctx))
201+
if err != nil {
202+
return diag.FromErr(err)
203+
}
204+
205+
log.Printf("[DEBUG] Waiting for ProjectAccessToken %s to finish deleting", d.Id())
206+
207+
err = resource.RetryContext(ctx, 5*time.Minute, func() *resource.RetryError {
208+
_, err := resourceGitlabProjectAccessTokenFind(ctx, client, project, projectAccessTokenID)
209+
if errors.Is(err, errResourceGitlabProjectAccessTokenNotFound) {
210+
return nil
211+
}
212+
if err != nil {
213+
return resource.NonRetryableError(err)
214+
}
215+
return resource.RetryableError(errors.New("project access token was not deleted"))
216+
})
217+
218+
return diag.FromErr(err)
219+
}
220+
221+
var errResourceGitlabProjectAccessTokenNotFound = errors.New("project access token not found")
222+
223+
// resourceGitlabProjectAccessTokenFind finds the project access token with the specified tokenID.
224+
// It returns a errResourceGitlabProjectAccessTokenNotFound error if the token is not found.
225+
func resourceGitlabProjectAccessTokenFind(ctx context.Context, client *gitlab.Client, project interface{}, projectAccessTokenID int) (*gitlab.ProjectAccessToken, error) {
158226
//there is a slight possibility to not find an existing item, for example
159227
// 1. item is #101 (ie, in the 2nd page)
160228
// 2. I load first page (ie. I don't find my target item)
@@ -167,55 +235,17 @@ func resourceGitlabProjectAccessTokenRead(ctx context.Context, d *schema.Resourc
167235
for page != 0 {
168236
projectAccessTokens, response, err := client.ProjectAccessTokens.ListProjectAccessTokens(project, &gitlab.ListProjectAccessTokensOptions{Page: page, PerPage: 100}, gitlab.WithContext(ctx))
169237
if err != nil {
170-
return diag.FromErr(err)
238+
return nil, err
171239
}
172240

173241
for _, projectAccessToken := range projectAccessTokens {
174242
if projectAccessToken.ID == projectAccessTokenID {
175-
176-
d.Set("project", project)
177-
d.Set("name", projectAccessToken.Name)
178-
if projectAccessToken.ExpiresAt != nil {
179-
d.Set("expires_at", projectAccessToken.ExpiresAt.String())
180-
}
181-
d.Set("active", projectAccessToken.Active)
182-
d.Set("created_at", projectAccessToken.CreatedAt.String())
183-
d.Set("revoked", projectAccessToken.Revoked)
184-
d.Set("user_id", projectAccessToken.UserID)
185-
d.Set("access_level", accessLevelValueToName[projectAccessToken.AccessLevel])
186-
187-
err = d.Set("scopes", projectAccessToken.Scopes)
188-
if err != nil {
189-
return diag.FromErr(err)
190-
}
191-
192-
return nil
243+
return projectAccessToken, nil
193244
}
194245
}
195246

196247
page = response.NextPage
197248
}
198249

199-
log.Printf("[DEBUG] failed to read gitlab ProjectAccessToken %d, project ID %s", projectAccessTokenID, project)
200-
d.SetId("")
201-
return nil
202-
}
203-
204-
func resourceGitlabProjectAccessTokenDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
205-
206-
project, PATstring, err := parseTwoPartID(d.Id())
207-
if err != nil {
208-
return diag.Errorf("Error parsing ID: %s", d.Id())
209-
}
210-
211-
client := meta.(*gitlab.Client)
212-
213-
projectAccessTokenID, err := strconv.Atoi(PATstring)
214-
if err != nil {
215-
return diag.Errorf("%s cannot be converted to int", PATstring)
216-
}
217-
218-
log.Printf("[DEBUG] Delete gitlab ProjectAccessToken %s", d.Id())
219-
_, err = client.ProjectAccessTokens.DeleteProjectAccessToken(project, projectAccessTokenID, gitlab.WithContext(ctx))
220-
return diag.FromErr(err)
250+
return nil, errResourceGitlabProjectAccessTokenNotFound
221251
}

0 commit comments

Comments
 (0)