Skip to content

Commit 14df9c7

Browse files
committed
review changes 2
Signed-off-by: Mauritz Uphoff <[email protected]>
1 parent 23bb334 commit 14df9c7

File tree

7 files changed

+113
-41
lines changed

7 files changed

+113
-41
lines changed

docs/ephemeral-resources/access_token.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
page_title: "stackit_access_token Ephemeral Resource - stackit"
44
subcategory: ""
55
description: |-
6-
STACKIT Access Token ephemeral resource schema.
6+
Ephemeral resource that generates a short-lived STACKIT access token (JWT) using a service account key. A new token is generated each time the resource is evaluated, and it remains consistent for the duration of a Terraform operation. If a private key is not explicitly provided, the provider attempts to extract it from the service account key instead. Token generation logic prioritizes environment variables first, followed by provider configuration. Access tokens generated from service account keys expire after 60 minutes.
77
---
88

99
# stackit_access_token (Ephemeral Resource)
1010

11-
STACKIT Access Token ephemeral resource schema.
11+
Ephemeral resource that generates a short-lived STACKIT access token (JWT) using a service account key. A new token is generated each time the resource is evaluated, and it remains consistent for the duration of a Terraform operation. If a private key is not explicitly provided, the provider attempts to extract it from the service account key instead. Token generation logic prioritizes environment variables first, followed by provider configuration. Access tokens generated from service account keys expire after 60 minutes.
1212

1313
## Example Usage
1414

@@ -18,16 +18,16 @@ ephemeral "stackit_access_token" "example" {}
1818
// https://registry.terraform.io/providers/Mastercard/restapi/latest/docs
1919
provider "restapi" {
2020
alias = "stackit_iaas"
21-
uri = "https://iaas.api.eu01.stackit.cloud"
21+
uri = "https://iaas.api.eu01.stackit.cloud/v2"
2222
write_returns_object = true
2323
2424
headers = {
2525
"Authorization" = "Bearer ${ephemeral.stackit_access_token.example.access_token}"
2626
}
2727
28-
create_method = "GET"
29-
update_method = "GET"
30-
destroy_method = "GET"
28+
create_method = "POST"
29+
update_method = "PUT"
30+
destroy_method = "DELETE"
3131
}
3232
```
3333

examples/ephemeral-resources/stackit_access_token/ephemeral-resource.tf

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ ephemeral "stackit_access_token" "example" {}
33
// https://registry.terraform.io/providers/Mastercard/restapi/latest/docs
44
provider "restapi" {
55
alias = "stackit_iaas"
6-
uri = "https://iaas.api.eu01.stackit.cloud"
6+
uri = "https://iaas.api.eu01.stackit.cloud/v2"
77
write_returns_object = true
88

99
headers = {
1010
"Authorization" = "Bearer ${ephemeral.stackit_access_token.example.access_token}"
1111
}
1212

13-
create_method = "GET"
14-
update_method = "GET"
15-
destroy_method = "GET"
13+
create_method = "POST"
14+
update_method = "PUT"
15+
destroy_method = "DELETE"
1616
}

stackit/internal/conversion/conversion.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,6 @@ func ParseProviderData(ctx context.Context, providerData any, diags *diag.Diagno
184184
return stackitProviderData, true
185185
}
186186

187-
// TODO: write tests
188187
func ParseEphemeralProviderData(ctx context.Context, providerData any, diags *diag.Diagnostics) (core.EphemeralProviderData, bool) {
189188
// Prevent panic if the provider has not been configured.
190189
if providerData == nil {

stackit/internal/conversion/conversion_test.go

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,3 +304,91 @@ func TestParseProviderData(t *testing.T) {
304304
})
305305
}
306306
}
307+
308+
func TestParseEphemeralProviderData(t *testing.T) {
309+
type args struct {
310+
providerData any
311+
}
312+
type want struct {
313+
ok bool
314+
providerData core.EphemeralProviderData
315+
}
316+
tests := []struct {
317+
name string
318+
args args
319+
want want
320+
wantErr bool
321+
}{
322+
{
323+
name: "provider has not been configured",
324+
args: args{
325+
providerData: nil,
326+
},
327+
want: want{
328+
ok: false,
329+
},
330+
wantErr: false,
331+
},
332+
{
333+
name: "invalid provider data",
334+
args: args{
335+
providerData: struct{}{},
336+
},
337+
want: want{
338+
ok: false,
339+
},
340+
wantErr: true,
341+
},
342+
{
343+
name: "valid provider data 1",
344+
args: args{
345+
providerData: core.EphemeralProviderData{},
346+
},
347+
want: want{
348+
ok: true,
349+
providerData: core.EphemeralProviderData{},
350+
},
351+
wantErr: false,
352+
},
353+
{
354+
name: "valid provider data 2",
355+
args: args{
356+
providerData: core.EphemeralProviderData{
357+
PrivateKey: "",
358+
PrivateKeyPath: "/home/dev/foo/private-key.json",
359+
ServiceAccountKey: "",
360+
ServiceAccountKeyPath: "/home/dev/foo/key.json",
361+
TokenCustomEndpoint: "",
362+
},
363+
},
364+
want: want{
365+
ok: true,
366+
providerData: core.EphemeralProviderData{
367+
PrivateKey: "",
368+
PrivateKeyPath: "/home/dev/foo/private-key.json",
369+
ServiceAccountKey: "",
370+
ServiceAccountKeyPath: "/home/dev/foo/key.json",
371+
TokenCustomEndpoint: "",
372+
},
373+
},
374+
wantErr: false,
375+
},
376+
}
377+
for _, tt := range tests {
378+
t.Run(tt.name, func(t *testing.T) {
379+
ctx := context.Background()
380+
diags := diag.Diagnostics{}
381+
382+
actual, ok := ParseEphemeralProviderData(ctx, tt.args.providerData, &diags)
383+
if diags.HasError() != tt.wantErr {
384+
t.Errorf("ConfigureClient() error = %v, want %v", diags.HasError(), tt.wantErr)
385+
}
386+
if ok != tt.want.ok {
387+
t.Errorf("ParseProviderData() got = %v, want %v", ok, tt.want.ok)
388+
}
389+
if !reflect.DeepEqual(actual, tt.want.providerData) {
390+
t.Errorf("ParseProviderData() got = %v, want %v", actual, tt.want)
391+
}
392+
})
393+
}
394+
}

stackit/internal/core/core.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ const (
2626
)
2727

2828
type EphemeralProviderData struct {
29-
ProviderData
30-
3129
PrivateKey string
3230
PrivateKeyPath string
3331
ServiceAccountKey string
@@ -38,7 +36,6 @@ type EphemeralProviderData struct {
3836
type ProviderData struct {
3937
RoundTripper http.RoundTripper
4038
ServiceAccountEmail string // Deprecated: ServiceAccountEmail is not required and will be removed after 12th June 2025.
41-
4239
// Deprecated: Use DefaultRegion instead
4340
Region string
4441
DefaultRegion string

stackit/internal/services/access_token/ephemeral_resource.go

Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,7 @@ func NewAccessTokenEphemeralResource() ephemeral.EphemeralResource {
2424
}
2525

2626
type accessTokenEphemeralResource struct {
27-
serviceAccountKeyPath string
28-
serviceAccountKey string
29-
privateKeyPath string
30-
privateKey string
31-
tokenCustomEndpoint string
27+
keyAuthConfig config.Configuration
3228
}
3329

3430
func (e *accessTokenEphemeralResource) Configure(ctx context.Context, req ephemeral.ConfigureRequest, resp *ephemeral.ConfigureResponse) {
@@ -37,11 +33,13 @@ func (e *accessTokenEphemeralResource) Configure(ctx context.Context, req epheme
3733
return
3834
}
3935

40-
e.serviceAccountKey = providerData.ServiceAccountKey
41-
e.serviceAccountKeyPath = providerData.ServiceAccountKeyPath
42-
e.privateKey = providerData.PrivateKey
43-
e.privateKeyPath = providerData.PrivateKeyPath
44-
e.tokenCustomEndpoint = providerData.TokenCustomEndpoint
36+
e.keyAuthConfig = config.Configuration{
37+
ServiceAccountKey: providerData.ServiceAccountKey,
38+
ServiceAccountKeyPath: providerData.ServiceAccountKeyPath,
39+
PrivateKeyPath: providerData.PrivateKey,
40+
PrivateKey: providerData.PrivateKeyPath,
41+
TokenCustomUrl: providerData.TokenCustomEndpoint,
42+
}
4543
}
4644

4745
type ephemeralTokenModel struct {
@@ -54,7 +52,11 @@ func (e *accessTokenEphemeralResource) Metadata(_ context.Context, req ephemeral
5452

5553
func (e *accessTokenEphemeralResource) Schema(_ context.Context, _ ephemeral.SchemaRequest, resp *ephemeral.SchemaResponse) {
5654
resp.Schema = schema.Schema{
57-
Description: "STACKIT Access Token ephemeral resource schema.",
55+
Description: "Ephemeral resource that generates a short-lived STACKIT access token (JWT) using a service account key. " +
56+
"A new token is generated each time the resource is evaluated, and it remains consistent for the duration of a Terraform operation. " +
57+
"If a private key is not explicitly provided, the provider attempts to extract it from the service account key instead. " +
58+
"Token generation logic prioritizes environment variables first, followed by provider configuration. " +
59+
"Access tokens generated from service account keys expire after 60 minutes.",
5860
Attributes: map[string]schema.Attribute{
5961
"access_token": schema.StringAttribute{
6062
Description: "JWT access token for STACKIT API authentication.",
@@ -73,15 +75,7 @@ func (e *accessTokenEphemeralResource) Open(ctx context.Context, req ephemeral.O
7375
return
7476
}
7577

76-
cfg := config.Configuration{
77-
ServiceAccountKey: e.serviceAccountKey,
78-
ServiceAccountKeyPath: e.serviceAccountKeyPath,
79-
PrivateKeyPath: e.privateKeyPath,
80-
PrivateKey: e.privateKey,
81-
TokenCustomUrl: e.tokenCustomEndpoint,
82-
}
83-
84-
rt, err := auth.KeyAuth(&cfg)
78+
rt, err := auth.KeyAuth(&e.keyAuthConfig)
8579
if err != nil {
8680
core.LogAndAddError(ctx, &resp.Diagnostics, "Access token generation failed", fmt.Sprintf("Failed to initialize authentication: %v", err))
8781
return
@@ -97,12 +91,7 @@ func (e *accessTokenEphemeralResource) Open(ctx context.Context, req ephemeral.O
9791
// Retrieve the access token
9892
accessToken, err := client.GetAccessToken()
9993
if err != nil {
100-
core.LogAndAddError(
101-
ctx,
102-
&resp.Diagnostics,
103-
"Access token retrieval failed",
104-
fmt.Sprintf("Error obtaining access token: %v", err),
105-
)
94+
core.LogAndAddError(ctx, &resp.Diagnostics, "Access token retrieval failed", fmt.Sprintf("Error obtaining access token: %v", err))
10695
return
10796
}
10897

stackit/internal/services/access_token/ephemeral_resource_test.go

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)