Skip to content

Commit 53ec994

Browse files
authored
feat(iaas): set custom user-agent header for STACKIT API calls (#821)
relates to STACKITTPR-184
1 parent 536d824 commit 53ec994

39 files changed

Lines changed: 575 additions & 740 deletions

File tree

stackit/internal/conversion/conversion.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import (
44
"context"
55
"fmt"
66

7+
"github.com/hashicorp/terraform-plugin-framework/diag"
8+
79
"github.com/hashicorp/terraform-plugin-framework/attr"
810
"github.com/hashicorp/terraform-plugin-framework/types"
911
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
@@ -167,3 +169,17 @@ func ToJSONMapPartialUpdatePayload(ctx context.Context, current, desired types.M
167169
}
168170
return mapPayload, nil
169171
}
172+
173+
func ParseProviderData(ctx context.Context, providerData any, diags *diag.Diagnostics) (core.ProviderData, bool) {
174+
// Prevent panic if the provider has not been configured.
175+
if providerData == nil {
176+
return core.ProviderData{}, false
177+
}
178+
179+
stackitProviderData, ok := providerData.(core.ProviderData)
180+
if !ok {
181+
core.LogAndAddError(ctx, diags, "Error configuring API client", fmt.Sprintf("Expected configure type stackit.ProviderData, got %T", providerData))
182+
return core.ProviderData{}, false
183+
}
184+
return stackitProviderData, true
185+
}

stackit/internal/conversion/conversion_test.go

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ import (
55
"reflect"
66
"testing"
77

8+
"github.com/hashicorp/terraform-plugin-framework/diag"
9+
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core"
10+
811
"github.com/google/go-cmp/cmp"
912
"github.com/hashicorp/terraform-plugin-framework/attr"
1013
"github.com/hashicorp/terraform-plugin-framework/types"
@@ -217,3 +220,87 @@ func TestToJSONMapUpdatePayload(t *testing.T) {
217220
})
218221
}
219222
}
223+
224+
func TestParseProviderData(t *testing.T) {
225+
type args struct {
226+
providerData any
227+
}
228+
type want struct {
229+
ok bool
230+
providerData core.ProviderData
231+
}
232+
tests := []struct {
233+
name string
234+
args args
235+
want want
236+
wantErr bool
237+
}{
238+
{
239+
name: "provider has not been configured",
240+
args: args{
241+
providerData: nil,
242+
},
243+
want: want{
244+
ok: false,
245+
},
246+
wantErr: false,
247+
},
248+
{
249+
name: "invalid provider data",
250+
args: args{
251+
providerData: struct{}{},
252+
},
253+
want: want{
254+
ok: false,
255+
},
256+
wantErr: true,
257+
},
258+
{
259+
name: "valid provider data 1",
260+
args: args{
261+
providerData: core.ProviderData{},
262+
},
263+
want: want{
264+
ok: true,
265+
providerData: core.ProviderData{},
266+
},
267+
wantErr: false,
268+
},
269+
{
270+
name: "valid provider data 2",
271+
args: args{
272+
providerData: core.ProviderData{
273+
DefaultRegion: "eu02",
274+
RabbitMQCustomEndpoint: "https://rabbitmq-custom-endpoint.api.stackit.cloud",
275+
Version: "1.2.3",
276+
},
277+
},
278+
want: want{
279+
ok: true,
280+
providerData: core.ProviderData{
281+
DefaultRegion: "eu02",
282+
RabbitMQCustomEndpoint: "https://rabbitmq-custom-endpoint.api.stackit.cloud",
283+
Version: "1.2.3",
284+
},
285+
},
286+
wantErr: false,
287+
},
288+
}
289+
for _, tt := range tests {
290+
t.Run(tt.name, func(t *testing.T) {
291+
ctx := context.Background()
292+
diags := diag.Diagnostics{}
293+
294+
actual, ok := ParseProviderData(ctx, tt.args.providerData, &diags)
295+
if diags.HasError() != tt.wantErr {
296+
t.Errorf("ConfigureClient() error = %v, want %v", diags.HasError(), tt.wantErr)
297+
}
298+
if ok != tt.want.ok {
299+
t.Errorf("ParseProviderData() got = %v, want %v", ok, tt.want.ok)
300+
}
301+
if !reflect.DeepEqual(actual, tt.want.providerData) {
302+
t.Errorf("ParseProviderData() got = %v, want %v", actual, tt.want)
303+
}
304+
})
305+
}
306+
}

stackit/internal/core/core.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ type ProviderData struct {
4646
ServiceAccountCustomEndpoint string
4747
EnableBetaResources bool
4848
Experiments []string
49+
50+
Version string // version of the STACKIT Terraform provider
4951
}
5052

5153
// GetRegion returns the effective region for the provider, falling back to the deprecated _region_ attribute

stackit/internal/services/iaas/affinitygroup/datasource.go

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import (
66
"net/http"
77
"regexp"
88

9+
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/conversion"
10+
iaasUtils "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/iaas/utils"
11+
912
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core"
1013
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/utils"
1114
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/validate"
@@ -17,7 +20,6 @@ import (
1720
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
1821
"github.com/hashicorp/terraform-plugin-framework/types"
1922
"github.com/hashicorp/terraform-plugin-log/tflog"
20-
"github.com/stackitcloud/stackit-sdk-go/core/config"
2123
"github.com/stackitcloud/stackit-sdk-go/services/iaas"
2224
)
2325

@@ -35,37 +37,15 @@ type affinityGroupDatasource struct {
3537
}
3638

3739
func (d *affinityGroupDatasource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
38-
// Prevent panic if the provider has not been configured.
39-
if req.ProviderData == nil {
40-
return
41-
}
42-
43-
providerData, ok := req.ProviderData.(core.ProviderData)
40+
providerData, ok := conversion.ParseProviderData(ctx, req.ProviderData, &resp.Diagnostics)
4441
if !ok {
45-
core.LogAndAddError(ctx, &resp.Diagnostics, "Error configuring API client", fmt.Sprintf("Expected configure type stackit.ProviderData, got %T", req.ProviderData))
4642
return
4743
}
4844

49-
var apiClient *iaas.APIClient
50-
var err error
51-
if providerData.IaaSCustomEndpoint != "" {
52-
ctx = tflog.SetField(ctx, "iaas_custom_endpoint", providerData.IaaSCustomEndpoint)
53-
apiClient, err = iaas.NewAPIClient(
54-
config.WithCustomAuth(providerData.RoundTripper),
55-
config.WithEndpoint(providerData.IaaSCustomEndpoint),
56-
)
57-
} else {
58-
apiClient, err = iaas.NewAPIClient(
59-
config.WithCustomAuth(providerData.RoundTripper),
60-
config.WithRegion(providerData.GetRegion()),
61-
)
62-
}
63-
64-
if err != nil {
65-
core.LogAndAddError(ctx, &resp.Diagnostics, "Error configuring API client", fmt.Sprintf("Configuring client: %v. This is an error related to the provider configuration, not to the resource configuratio", err))
45+
apiClient := iaasUtils.ConfigureClient(ctx, &providerData, &resp.Diagnostics)
46+
if resp.Diagnostics.HasError() {
6647
return
6748
}
68-
6949
d.client = apiClient
7050
tflog.Info(ctx, "iaas client configured")
7151
}

stackit/internal/services/iaas/affinitygroup/resource.go

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import (
77
"regexp"
88
"strings"
99

10+
iaasUtils "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/iaas/utils"
11+
1012
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/conversion"
1113
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core"
1214
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/validate"
@@ -21,7 +23,6 @@ import (
2123
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
2224
"github.com/hashicorp/terraform-plugin-framework/types"
2325
"github.com/hashicorp/terraform-plugin-log/tflog"
24-
"github.com/stackitcloud/stackit-sdk-go/core/config"
2526
"github.com/stackitcloud/stackit-sdk-go/core/oapierror"
2627
"github.com/stackitcloud/stackit-sdk-go/services/iaas"
2728
)
@@ -58,37 +59,15 @@ func (r *affinityGroupResource) Metadata(_ context.Context, req resource.Metadat
5859

5960
// Configure adds the provider configured client to the resource.
6061
func (r *affinityGroupResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
61-
// Prevent panic if the provider has not been configured.
62-
if req.ProviderData == nil {
63-
return
64-
}
65-
66-
providerData, ok := req.ProviderData.(core.ProviderData)
62+
providerData, ok := conversion.ParseProviderData(ctx, req.ProviderData, &resp.Diagnostics)
6763
if !ok {
68-
core.LogAndAddError(ctx, &resp.Diagnostics, "Error configuring API client", fmt.Sprintf("Expected configure type stackit.ProviderDate, got %T", req.ProviderData))
6964
return
7065
}
7166

72-
var apiClient *iaas.APIClient
73-
var err error
74-
if providerData.IaaSCustomEndpoint != "" {
75-
ctx = tflog.SetField(ctx, "iaas_custom_endpoint", providerData.IaaSCustomEndpoint)
76-
apiClient, err = iaas.NewAPIClient(
77-
config.WithCustomAuth(providerData.RoundTripper),
78-
config.WithEndpoint(providerData.IaaSCustomEndpoint),
79-
)
80-
} else {
81-
apiClient, err = iaas.NewAPIClient(
82-
config.WithCustomAuth(providerData.RoundTripper),
83-
config.WithRegion(providerData.GetRegion()),
84-
)
85-
}
86-
87-
if err != nil {
88-
core.LogAndAddError(ctx, &resp.Diagnostics, "Error configuring API client", fmt.Sprintf("Configuring client: %v. This is an error related to the provider configuration, not to the resource configuratio", err))
67+
apiClient := iaasUtils.ConfigureClient(ctx, &providerData, &resp.Diagnostics)
68+
if resp.Diagnostics.HasError() {
8969
return
9070
}
91-
9271
r.client = apiClient
9372
tflog.Info(ctx, "iaas client configured")
9473
}

stackit/internal/services/iaas/image/datasource.go

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import (
66
"net/http"
77
"strings"
88

9+
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/conversion"
10+
iaasUtils "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/iaas/utils"
11+
912
"github.com/hashicorp/terraform-plugin-framework/attr"
1013
"github.com/hashicorp/terraform-plugin-framework/datasource"
1114
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
@@ -14,7 +17,6 @@ import (
1417
"github.com/hashicorp/terraform-plugin-framework/types"
1518
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
1619
"github.com/hashicorp/terraform-plugin-log/tflog"
17-
"github.com/stackitcloud/stackit-sdk-go/core/config"
1820
"github.com/stackitcloud/stackit-sdk-go/services/iaas"
1921
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core"
2022
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/utils"
@@ -57,36 +59,15 @@ func (d *imageDataSource) Metadata(_ context.Context, req datasource.MetadataReq
5759
}
5860

5961
func (d *imageDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
60-
// Prevent panic if the provider has not been configured.
61-
if req.ProviderData == nil {
62-
return
63-
}
64-
65-
var apiClient *iaas.APIClient
66-
var err error
67-
68-
providerData, ok := req.ProviderData.(core.ProviderData)
62+
providerData, ok := conversion.ParseProviderData(ctx, req.ProviderData, &resp.Diagnostics)
6963
if !ok {
70-
core.LogAndAddError(ctx, &resp.Diagnostics, "Error configuring API client", fmt.Sprintf("Expected configure type stackit.ProviderData, got %T", req.ProviderData))
7164
return
7265
}
7366

74-
if providerData.IaaSCustomEndpoint != "" {
75-
apiClient, err = iaas.NewAPIClient(
76-
config.WithCustomAuth(providerData.RoundTripper),
77-
config.WithEndpoint(providerData.IaaSCustomEndpoint),
78-
)
79-
} else {
80-
apiClient, err = iaas.NewAPIClient(
81-
config.WithCustomAuth(providerData.RoundTripper),
82-
config.WithRegion(providerData.GetRegion()),
83-
)
84-
}
85-
if err != nil {
86-
core.LogAndAddError(ctx, &resp.Diagnostics, "Error configuring API client", fmt.Sprintf("Configuring client: %v. This is an error related to the provider configuration, not to the data source configuration", err))
67+
apiClient := iaasUtils.ConfigureClient(ctx, &providerData, &resp.Diagnostics)
68+
if resp.Diagnostics.HasError() {
8769
return
8870
}
89-
9071
d.client = apiClient
9172
tflog.Info(ctx, "iaas client configured")
9273
}

stackit/internal/services/iaas/image/resource.go

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import (
99
"strings"
1010
"time"
1111

12+
iaasUtils "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/iaas/utils"
13+
1214
"github.com/hashicorp/terraform-plugin-framework/attr"
1315
"github.com/hashicorp/terraform-plugin-framework/diag"
1416
"github.com/hashicorp/terraform-plugin-framework/path"
@@ -23,7 +25,6 @@ import (
2325
"github.com/hashicorp/terraform-plugin-framework/types"
2426
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
2527
"github.com/hashicorp/terraform-plugin-log/tflog"
26-
"github.com/stackitcloud/stackit-sdk-go/core/config"
2728
"github.com/stackitcloud/stackit-sdk-go/core/oapierror"
2829
"github.com/stackitcloud/stackit-sdk-go/services/iaas"
2930
"github.com/stackitcloud/stackit-sdk-go/services/iaas/wait"
@@ -118,37 +119,15 @@ func (r *imageResource) Metadata(_ context.Context, req resource.MetadataRequest
118119

119120
// Configure adds the provider configured client to the resource.
120121
func (r *imageResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
121-
// Prevent panic if the provider has not been configured.
122-
if req.ProviderData == nil {
123-
return
124-
}
125-
126-
providerData, ok := req.ProviderData.(core.ProviderData)
122+
providerData, ok := conversion.ParseProviderData(ctx, req.ProviderData, &resp.Diagnostics)
127123
if !ok {
128-
core.LogAndAddError(ctx, &resp.Diagnostics, "Error configuring API client", fmt.Sprintf("Expected configure type stackit.ProviderData, got %T", req.ProviderData))
129124
return
130125
}
131126

132-
var apiClient *iaas.APIClient
133-
var err error
134-
if providerData.IaaSCustomEndpoint != "" {
135-
ctx = tflog.SetField(ctx, "iaas_custom_endpoint", providerData.IaaSCustomEndpoint)
136-
apiClient, err = iaas.NewAPIClient(
137-
config.WithCustomAuth(providerData.RoundTripper),
138-
config.WithEndpoint(providerData.IaaSCustomEndpoint),
139-
)
140-
} else {
141-
apiClient, err = iaas.NewAPIClient(
142-
config.WithCustomAuth(providerData.RoundTripper),
143-
config.WithRegion(providerData.GetRegion()),
144-
)
145-
}
146-
147-
if err != nil {
148-
core.LogAndAddError(ctx, &resp.Diagnostics, "Error configuring API client", fmt.Sprintf("Configuring client: %v. This is an error related to the provider configuration, not to the resource configuration", err))
127+
apiClient := iaasUtils.ConfigureClient(ctx, &providerData, &resp.Diagnostics)
128+
if resp.Diagnostics.HasError() {
149129
return
150130
}
151-
152131
r.client = apiClient
153132
tflog.Info(ctx, "iaas client configured")
154133
}

0 commit comments

Comments
 (0)