Skip to content

Commit a47d754

Browse files
authored
access-token: handle ExpiresAt state transition (#123)
fixes #122 Signed-off-by: Nick Santos <nick.santos@docker.com>
1 parent 1dcec0e commit a47d754

File tree

2 files changed

+51
-9
lines changed

2 files changed

+51
-9
lines changed

internal/provider/resource_access_token.go

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ func (r *AccessTokenResource) Create(ctx context.Context, req resource.CreateReq
163163
return
164164
}
165165

166-
data = r.toModel(ctx, at)
166+
data = r.toModel(ctx, at, nil)
167167
if resp.Diagnostics.HasError() {
168168
return
169169
}
@@ -191,7 +191,7 @@ func (r *AccessTokenResource) Read(ctx context.Context, req resource.ReadRequest
191191
return
192192
}
193193

194-
fromAPI := r.toModel(ctx, at)
194+
fromAPI := r.toModel(ctx, at, &fromState)
195195
if resp.Diagnostics.HasError() {
196196
return
197197
}
@@ -230,15 +230,11 @@ func (r *AccessTokenResource) Update(ctx context.Context, req resource.UpdateReq
230230
return
231231
}
232232

233-
fromAPI := r.toModel(ctx, at)
233+
fromAPI := r.toModel(ctx, at, &fromState)
234234
if resp.Diagnostics.HasError() {
235235
return
236236
}
237237

238-
// The token is not returned by the API after initial creation,
239-
// so we need to copy it from the state
240-
fromAPI.Token = fromState.Token
241-
242238
resp.Diagnostics.Append(resp.State.Set(ctx, &fromAPI)...)
243239
}
244240

@@ -261,14 +257,27 @@ func (r *AccessTokenResource) ImportState(ctx context.Context, req resource.Impo
261257
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("uuid"), req.ID)...)
262258
}
263259

264-
func (r *AccessTokenResource) toModel(ctx context.Context, at hubclient.AccessToken) AccessTokenResourceModel {
260+
func (r *AccessTokenResource) toModel(ctx context.Context, at hubclient.AccessToken, currentState *AccessTokenResourceModel) AccessTokenResourceModel {
265261
scopes, _ := types.ListValueFrom(ctx, types.StringType, at.Scopes)
266-
return AccessTokenResourceModel{
262+
result := AccessTokenResourceModel{
267263
UUID: types.StringValue(at.UUID),
268264
IsActive: types.BoolValue(at.IsActive),
269265
TokenLabel: types.StringValue(at.TokenLabel),
270266
Scopes: scopes,
271267
Token: types.StringValue(at.Token),
272268
ExpiresAt: types.StringValue(at.ExpiresAt),
273269
}
270+
271+
// If the current state is null, keep it as null instead of changing to empty string.
272+
if at.ExpiresAt == "" && currentState != nil && currentState.ExpiresAt.IsNull() {
273+
result.ExpiresAt = types.StringNull()
274+
}
275+
276+
// The token is not returned by the API after initial creation,
277+
// so we need to copy it from the state
278+
if currentState != nil {
279+
result.Token = currentState.Token
280+
}
281+
282+
return result
274283
}

internal/provider/resource_access_token_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,36 @@ resource "docker_access_token" "test" {
6262
expires_at = "2029-12-31T23:59:59Z"
6363
}
6464
`
65+
66+
func TestAccessTokenResource_Upgrade(t *testing.T) {
67+
config := `
68+
resource "docker_access_token" "test" {
69+
token_label = "test-label"
70+
scopes = ["repo:read"]
71+
}
72+
`
73+
resource.Test(t, resource.TestCase{
74+
PreCheck: func() { testAccPreCheck(t) },
75+
Steps: []resource.TestStep{
76+
{
77+
ExternalProviders: map[string]resource.ExternalProvider{
78+
"docker": {
79+
VersionConstraint: "0.4.1",
80+
Source: "docker/docker",
81+
},
82+
},
83+
Config: config,
84+
Check: resource.ComposeAggregateTestCheckFunc(
85+
resource.TestCheckResourceAttrSet("docker_access_token.test", "uuid"),
86+
),
87+
},
88+
{
89+
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
90+
Config: config,
91+
Check: resource.ComposeAggregateTestCheckFunc(
92+
resource.TestCheckResourceAttrSet("docker_access_token.test", "uuid"),
93+
),
94+
},
95+
},
96+
})
97+
}

0 commit comments

Comments
 (0)